3 #include <vtestbed/config/real_type.hh> 4 #include <vtestbed/linalg/linear_algebra.hh> 13 return all(*
this == this->transpose());
21 return all(abs(*
this - this->transpose()) < eps);
31 #if defined(VTB_DEBUG_LINEAR_ALGEBRA) 32 if (!this->is_square()) {
36 const auto& rhs = *
this;
39 const int n = rhs.rows();
40 for (
int i=0; i<n; ++i) {
41 for (
int j=0; j<i; ++j) {
43 L(i,j) = (rhs(i,j) - sum(L(i,r)*L(j,r))) / L(j,j);
45 T s = sum(pow2(L(i, Range(0,i))));
46 if (rhs(i,i) < s) {
return false; }
47 L(i,i) = sqrt(rhs(i,i) - s);
55 const auto& rhs = *
this;
56 const int nrows = rhs.rows();
57 const int ncols = rhs.cols();
58 for (
int i=1; i<nrows; ++i) {
59 for (
int j=1; j<ncols; ++j) {
60 if (rhs(i,j) != rhs(i-1, j-1)) {
return false; }
70 const auto& rhs = *
this;
71 const int nrows = rhs.rows();
72 const int ncols = rhs.cols();
73 for (
int i=1; i<nrows; ++i) {
74 for (
int j=1; j<ncols; ++j) {
75 if (abs(rhs(i,j) - rhs(i-1,j-1)) < eps) {
86 #if defined(VTB_DEBUG_LINEAR_ALGEBRA) 87 if (!this->is_square()) {
93 const int n = L.rows();
96 for (
int i=1; i<n; ++i) {
97 blitz::Range r{0,i-1};
98 y(i) = (b(i) - sum(L(i,r)*y(r))) / L(i,i);
106 #if defined(VTB_DEBUG_LINEAR_ALGEBRA) 107 if (!this->is_square()) {
112 const int n = L.rows();
114 x(n-1) = y(n-1) / L(n-1,n-1);
115 for (
int i=n-2; i>=0; --i) {
116 blitz::Range r{i+1,n-1};
118 for (
int j=i+1; j<n; ++j) {
119 sum += conj(L(j,i)) * x(j);
121 x(i) = (y(i) - sum) / L(i,i);
129 #if defined(VTB_DEBUG_LINEAR_ALGEBRA) 130 if (!this->is_square() ||
131 !this->is_symmetric()) {
135 using namespace blitz;
136 Lower_triangular_matrix_ldlt<T> L(this->shape());
139 const int n = A.rows();
143 for (
int i=0; i<n; ++i) {
144 L(i,j) = A(i,j) / d(j);
146 for (j=1; j<n; ++j) {
148 d(j) = A(j,j) - sum(pow2(L(j,r))*d(r));
149 for (
int i=0; i<n; ++i) {
150 L(i,j) = (A(i,j) - sum(L(i,r)*d(r)*L(j,r))) / d(j);
153 L._diagonal.reference(d);
163 const int n = a.rows();
167 int nelements = n*(n - 1) / 2;
168 int niterations = nelements*nsweeps;
169 for (
int it=0; it<niterations; ++it) {
174 T pivot = abs(a(0,1));
175 for (
int i=0; i<n; ++i) {
176 for (
int j=0; j<n; ++j) {
180 T new_pivot = abs(a(i,j));
181 if (new_pivot > pivot) {
188 if (abs(pivot) < eps) {
195 T w = (a(j,j) - a(i,i)) / (2*a(i,j));
196 T sqrt_w = sqrt(1 + w*w);
197 T t1 = -w + sqrt_w, t2 = -w - sqrt_w;
199 if (t1 == 0 || (t2 != 0 && abs(t2) < abs(t1))) {
203 T cos = 1 / r, sin = t / r;
204 T tau = sin / (1 + cos);
207 a(i,j) = (cos*cos - sin*sin)*a(i,j) + cos*sin*(a(i,i) - a(j,j));
211 for (
int k=0; k<n; ++k) {
212 if (k == i || k == j) {
215 T sa_ik = sin*a(i,k);
216 T sa_jk = sin*a(j,k);
217 a(i,k) -= sa_jk + tau*sa_ik;
218 a(j,k) += sa_ik - tau*sa_jk;
222 #if defined(VTB_DEBUG_EIGEN_VALUES) 224 << std::setw(20) << __func__
225 << std::setw(20) << pivot
226 << std::setw(20) << w
227 << std::setw(20) << t
228 << std::setw(20) << cos
229 << std::setw(20) << sin
233 for (
int i=0; i<n; ++i) {
242 #if defined(VTB_DEBUG_LINEAR_ALGEBRA) 243 if (!this->is_square() || !this->is_symmetric()) {
254 const int n = rhs.rows();
255 for (
int i=0; i<n; ++i) {
256 for (
int j=0; j<i; ++j) {
258 L(i,j) = (rhs(i,j) - sum(L(i,r)*L(j,r))) / L(j,j);
260 T s = rhs(i,i) - sum(pow2(L(i, Range(0,i))));
274 #if defined(VTB_DEBUG_LINEAR_ALGEBRA) 275 if (!this->is_square()) {
279 Square_matrix<T> result(this->shape());
281 const int n = rhs.rows();
282 for (
int j=0; j<n; ++j) {
283 for (
int i=0; i<n; ++i) {
284 result(i,j) = (_permutations(i) == j) ? 1 : 0;
285 for (
int k=0; k<i; ++k) {
286 result(i,j) -= rhs(i,k) * result(k,j);
289 for (
int i=n-1; i>=0; --i) {
290 for (
int k=i+1; k<n; ++k) {
291 result(i,j) -= rhs(i,k) * result(k,j);
293 result(i,j) /= rhs(i,i);
294 if (!std::isfinite(result(i,j))) {
305 const auto& A = *
this;
306 const auto& p = this->_permutations;
307 const int n = this->rows();
308 Vector<T> x(b.shape());
309 for (
int i=0; i<n; ++i) {
312 for (
int i=0; i<n; ++i) {
313 for (
int k=0; k<i; ++k) {
317 for (
int i=n-1; i>=0; --i) {
318 for (
int k=i+1; k<n; ++k) {
322 if (!std::isfinite(x(i))) {
332 #if defined(VTB_DEBUG_LINEAR_ALGEBRA) 333 if (!this->is_square()) {
343 const auto& _ = Range::all();
345 const int n = rhs.rows();
346 auto& p = this->_permutations;
348 for (
int i=0; i<n; ++i) {
351 int npermutations = 0;
353 for (
int i=0; i<n; ++i) {
357 for (
int j=i; j<n; ++j) {
358 const T new_elem = abs(rhs(j,i));
359 if (elem < new_elem) {
366 swap(p(i), p(pivot));
368 rhs(pivot,_) = rhs(i,_);
372 for (
int j=i+1; j<n; ++j) {
373 const T x = rhs(i,i);
377 "lower_upper_triangular_self: bad matrix" 380 for (
int k=i+1; k<n; ++k) {
381 rhs(j,k) -= rhs(j,i)*rhs(i,k);
385 this->_npermutations = npermutations;
392 #if defined(VTB_DEBUG_LINEAR_ALGEBRA) 393 if (!this->is_square()) {
397 using namespace blitz;
400 T result = product(rhs(i,i));
401 if (this->_npermutations%2 == 1) {
409 vtb::linalg::product(
const Matrix<T>& lhs,
const Vector<T>& rhs) -> Vector<T>
411 #if defined(VTB_DEBUG_LINEAR_ALGEBRA) 412 if (lhs.extent(1) != rhs.extent(0)) {
418 const blitz::Range& _ = blitz::Range::all();
419 const int nrows = lhs.rows();
420 Vector<T> result(nrows);
421 for (
int i=0; i<nrows; ++i) {
422 result(i) = blitz::dot(lhs(i,_), rhs);
429 vtb::linalg::product(
const Matrix<T>& lhs,
const Matrix<T>& rhs) -> Matrix<T>
431 const int nrows = lhs.rows();
432 const int ncols = rhs.cols();
433 #if defined(VTB_DEBUG_LINEAR_ALGEBRA) 434 if (lhs.cols() != rhs.rows()) {
438 const blitz::Range& _ = blitz::Range::all();
439 Matrix<T> result(nrows, ncols);
440 for (
int i=0; i<nrows; ++i) {
441 for (
int j=0; j<ncols; ++j) {
442 result(i,j) = blitz::dot(lhs(i,_), rhs(_,j));
455 vtb::linalg::product(
456 const Matrix<VTB_REAL_TYPE>& lhs,
457 const Matrix<VTB_REAL_TYPE>& rhs
458 ) -> Matrix<VTB_REAL_TYPE>;
461 vtb::linalg::product(
462 const Matrix<VTB_REAL_TYPE>& lhs,
463 const Vector<VTB_REAL_TYPE>& rhs
464 ) -> Vector<VTB_REAL_TYPE>;
466 #if defined(VTB_REAL_TYPE_FLOAT) 472 vtb::linalg::product(
473 const Matrix<double>& lhs,
474 const Matrix<double>& rhs
477 vtb::linalg::product(
478 const Matrix<double>& lhs,
479 const Vector<double>& rhs
Vector< T > backward_substitution(const Vector< T > &y) const
Backward substitution.
bool is_positive_definite() const
New and missing Blitz++ functions.
Vector< T > eigen_values(T eps, int nsweeps) const
Compute eigen values.
Lower_triangular_matrix< T > cholesky() const
Cholesky decomposition.
Vector< T > forward_substitution(const Vector< T > &b) const
Forward substitution.