void test(Matrix& A, const char* name) { using mtl::irange; A= 0.0; A[0][0]= 1.0; hessian_setup(A, 1.0); A[irange(0, 8)][irange(0, 8)]; mtl::matrix::recursator<Matrix> rec(A); std::cout << "\n" << name << "\n"; std::cout << "A:\n" << A << '\n'; std::cout << "A[irange(0, 8)][irange(0, 8)]:\n" << A[irange(0, 8)][irange(0, 8)] << '\n'; std::cout << "*rec:\n" << *rec << '\n'; mtl::matrix::recursator<Matrix> nw= north_west(rec); std::cout << "north_west:\n" << *nw << '\n'; std::cout << "north_west of north_west:\n" << *north_west(nw) << '\n'; MTL_THROW_IF((*north_west(nw))[0][0] != 0.0, mtl::runtime_error("(*north_west(nw))[0][0] != 0.0")); (*north_west(nw))[0][0]= 2.0; std::cout << "south_east of north_west:\n" << *south_east(nw) << '\n'; MTL_THROW_IF((*south_east(nw))[0][0] != 4.0, mtl::runtime_error("(*south_east(nw))[0][0] != 4.0")); std::cout << "north_west of north_west:\n" << *north_west(nw) << '\n'; MTL_THROW_IF((*north_west(nw))[0][0] != 2.0, mtl::runtime_error("(*north_west(nw))[0][0] != 2.0")); std::cout << "south_east of north_west:\n" << *south_east(nw) << '\n'; MTL_THROW_IF((*south_east(nw))[0][0] != 4.0, mtl::runtime_error("(*south_east(nw))[0][0] != 4.0")); std::cout << "nw.first_address() == " << nw.first_address() << ", &(*nw)[0][0] == " << &(*nw)[0][0] << '\n'; MTL_THROW_IF(nw.first_address() != &(*nw)[0][0], mtl::runtime_error("Inconsistency in address calculation")); }
dense2D<typename mtl::Collection <typename mtl::Collection<VVector>::value_type >::value_type, parameters<> > inline orthogonalize_factors(VVector& v, tag::vector) { using ::mtl::two_norm; using math::zero; using mtl::size1D; typedef typename mtl::Collection<VVector>::size_type Size; typedef typename mtl::Collection<VVector>::value_type Vector; typedef typename mtl::Collection<Vector>::value_type Scalar; dense2D<Scalar, parameters<> > tau(size1D(v), size1D(v)); tau= zero(Scalar()); for (Size j= 0; j < size1D(v); ++j) { for (Size i= 0; i < j; ++i) { Scalar t= dot(entry1D(v, i), entry1D(v, j)) / tau[i][i]; tau[i][j]= t; entry1D(v, j)-= t * entry1D(v, i); } tau[j][j]= dot(entry1D(v, j), entry1D(v, j)); } return tau; }
void test2(Matrix& A, const char* name) { using mtl::irange; using mtl::imax; using mtl::iall; A= 0.0; A[1][1]= 1.0; hessian_setup(A, 1.0); std::cout << "\n" << name << "\nA == \n" << A; cout << "A[irange(2, 4)][irange(2, imax)] == \n" << A[irange(2, 4)][irange(2, imax)] << "\n"; Matrix B(A[irange(2, 4)][irange(2, imax)]); MTL_THROW_IF(B[0][0] != 4.0, mtl::runtime_error("Wrong value in B")); MTL_THROW_IF(A[irange(2, 4)][irange(2, imax)][0][0] != 4.0, mtl::runtime_error("Wrong value in A[][]")); Matrix C(A[irange(4, imax)][irange(0, imax)]); std::cout << "\n" << name << "\nA[irange(4, imax)][irange(0, imax)] == \n" << C; MTL_THROW_IF(C[0][1] != 5.0, mtl::runtime_error("Wrong value in C")); Matrix D(A[irange(4, imax)][iall]); std::cout << "\n" << name << "\nA[irange(4, imax)][iall] == \n" << C; MTL_THROW_IF(D[0][1] != 5.0, mtl::runtime_error("Wrong value in D")); }
inline void orth(VVector& v, typename mtl::Collection<VVector>::size_type j, tag::vector) { using mtl::two_norm; using mtl::size1D; MTL_DEBUG_THROW_IF(j < 0 || j >= size1D(v), index_out_of_range()); typedef typename mtl::Collection<VVector>::size_type Size; for (Size i= 0; i < j; ++i) entry1D(v, j)-= dot(entry1D(v, i), entry1D(v, j)) * entry1D(v, i); entry1D(v, j)/= two_norm(entry1D(v, j)); }
void test(Matrix& matrix, const char* name) { using mtl::conj; set_to_zero(matrix); typename Matrix::value_type ref(0); { mtl::matrix::inserter<Matrix> ins(matrix); ins(2, 3) << value(ref); ins(4, 3) << value(ref) + 1.0; ins(2, 5) << value(ref) + 2.0; } cout << "\n\n" << name << "\n"; cout << "Original matrix:\n" << matrix << "\n"; mtl::matrix::scaled_view<double, Matrix> scaled_matrix(2.0, matrix); cout << "matrix scaled with 2.0\n" << scaled_matrix << "\n"; MTL_THROW_IF(scaled_matrix(2, 3) != svalue(ref), mtl::runtime_error("scaling wrong")); cout << "matrix scaled with 2.0 (as operator)\n" << 2.0 * matrix << "\n"; MTL_THROW_IF((2.0 * matrix)(2, 3) != svalue(ref), mtl::runtime_error("scaling wrong")); mtl::matrix::conj_view<Matrix> conj_matrix(matrix); cout << "conjugated matrix\n" << conj_matrix << "\n"; MTL_THROW_IF(conj_matrix(2, 3) != cvalue(ref), mtl::runtime_error(" wrong")); mtl::matrix::scaled_view<ct, Matrix> cscaled_matrix(ct(0.0, 1.0), matrix); cout << "matrix scaled with i (complex(0, 1))\n" << cscaled_matrix << "\n"; MTL_THROW_IF(cscaled_matrix(2, 3) != csvalue(ref), mtl::runtime_error("complex scaling wrong")); mtl::matrix::hermitian_view<Matrix> hermitian_matrix(matrix); cout << "Hermitian matrix (conjugate transposed)\n" << hermitian_matrix << "\n"; MTL_THROW_IF(hermitian_matrix(3, 2) != cvalue(ref), mtl::runtime_error("conjugate transposing wrong")); cout << "matrix scaled with 2.0 (free function)\n" << scale(2.0, matrix) << "\n"; MTL_THROW_IF(scale(2.0, matrix)(2, 3) != svalue(ref), mtl::runtime_error("scaling wrong")); cout << "matrix scaled with 2.0 (free function as mtl::scale)\n" << mtl::scale(2.0, matrix) << "\n"; cout << "conjugated matrix (free function) \n" << conj(matrix) << "\n"; MTL_THROW_IF(conj(matrix)(2, 3) != cvalue(ref), mtl::runtime_error("conjugating wrong")); cout << "matrix scaled with i (complex(0, 1)) (free function)\n" << scale(ct(0.0, 1.0), matrix) << "\n"; MTL_THROW_IF(scale(ct(0.0, 1.0), matrix)(2, 3) != csvalue(ref), mtl::runtime_error("complex scaling wrong")); cout << "Hermitian matrix (conjugate transposed) (free function)\n" << hermitian(matrix) << "\n"; MTL_THROW_IF(hermitian(matrix)(3, 2) != cvalue(ref), mtl::runtime_error("conjugate transposing wrong")); }
int main(int, char**) { using namespace std; using mtl::lazy; using mtl::io::tout; typedef mtl::dense_vector<double> vt; vt v(60); iota(v); tout << "v is " << v << endl; mtl::mat::identity2D I(60); vt w1(I * v); tout << "I * v is " << w1 << endl; if (one_norm(vt(w1 - v)) > 0.001) throw "Wrong result with square identity"; w1-= I * v; tout << "w1-= I * v is " << w1 << endl; if (one_norm(w1) > 0.001) throw "Wrong result"; w1+= I * v; tout << "w1+= I * v is " << w1 << endl; if (one_norm(vt(w1 - v)) > 0.001) throw "Wrong result with square identity"; vt w2( w1 - I * v ); double alpha; (lazy(w2)= I * v) || (lazy(alpha)= lazy_dot(w2, v)); vt w3(30), w4(90); mtl::mat::identity2D I3(30, 60), I4(90, 60); w3= I3 * v; tout << "I3 * v is " << w3 << endl; if (one_norm(vt(w3 - v[mtl::irange(30)])) > 0.001) throw "Wrong result with broad identity"; w4= I4 * v; tout << "I4 * v is " << w4 << endl; if (one_norm(vt(w4[mtl::irange(60)] - v)) > 0.001) throw "Wrong result with long identity"; if (one_norm(w4[mtl::irange(60, 90)]) > 0.001) throw "Wrong result with long identity"; #if 0 mtl::dense2D<double> A(60,60); A=2; A+= A*I; std::cout<< "A=\n" << A << "\n"; #endif return 0; }
inline void orth(VVector& v, tag::vector) { typedef typename mtl::Collection<VVector>::size_type Size; using mtl::size1D; for (Size j= 0; j < size1D(v); ++j) orth(v, j, tag::vector()); }
void adjoint_solve(const VectorIn& x, VectorOut& y) const { using mtl::conj; y.checked_change_resource(x); MTL_THROW_IF(size(x) != size(inv_diag), mtl::incompatible_size()); for (size_type i= 0; i < size(inv_diag); ++i) y[i]= conj(inv_diag[i]) * x[i]; }
int bicg(const LinearOperator &A, Vector &x, const Vector &b, const Preconditioner &M, Iteration& iter) { using mtl::conj; typedef typename mtl::Collection<Vector>::value_type Scalar; Scalar rho_1(0), rho_2(0), alpha(0), beta(0); Vector r(b - A * x), z(size(x)), p(size(x)), q(size(x)), r_tilde(r), z_tilde(size(x)), p_tilde(size(x)), q_tilde(size(x)); while (! iter.finished(r)) { z= solve(M, r); z_tilde= adjoint_solve(M, r_tilde); rho_1= dot(z_tilde, z); if (rho_1 == 0.) { iter.fail(2, "bicg breakdown"); break; } if (iter.first()) { p= z; p_tilde= z_tilde; } else { beta= rho_1 / rho_2; p= z + beta * p; p_tilde= z_tilde + conj(beta) * p_tilde; } q= A * p; q_tilde= adjoint(A) * p_tilde; alpha= rho_1 / dot(p_tilde, q); x+= alpha * p; r-= alpha * q; r_tilde-= conj(alpha) * q_tilde; rho_2= rho_1; ++iter; } return iter.error_code(); }
void test(Matrix& matrix, const char* name) { cout << "\n" << name << "\n"; using mtl::matrix::inserter; using mtl::element_array; typedef typename mtl::Collection<Matrix>::value_type value_type; mtl::dense2D<double> m1(2, 2); m1[0][0]= 1.0; m1[0][1]= 2.0; m1[1][0]= 3.0; m1[1][1]= 4.0; std::vector<int> row1, col1; row1.push_back(1); row1.push_back(2); col1.push_back(0); col1.push_back(2); double a2[2][2]= {{11., 12.},{13., 14.}}; std::vector<int> ind2; ind2.push_back(2); ind2.push_back(4); std::vector<int> ind3; ind3.push_back(3); ind3.push_back(1); set_to_zero(matrix); // dense matrices are not automatically set to zero { inserter<Matrix, mtl::operations::update_plus<value_type> > ins(matrix); ins << element_matrix(m1, row1, col1) << element_array(a2, ind2); ins << element_array(a2, ind3); } cout << "Filled matrix:\n" << matrix << "\n"; MTL_THROW_IF(matrix[0][0] != 0.0, mtl::runtime_error("wrong zero-element")); MTL_THROW_IF(matrix[1][0] != 1.0, mtl::runtime_error("wrong insertion (single value)")); MTL_THROW_IF(matrix[2][2] != 15.0, mtl::runtime_error("wrong summation")); MTL_THROW_IF(matrix[1][1] != 14.0, mtl::runtime_error("wrong insertion (single value)")); }
int main(int, char**) { using namespace std; using mtl::lazy; using mtl::io::tout; typedef mtl::vector::dense_vector<double> vt; mtl::compressed2D<double> A0; laplacian_setup(A0, 4, 15); tout << "A0 is\n" << A0 << endl; vt v(60); iota(v); tout << "v is " << v << endl; vt w1(A0 * v); tout << "A0 * v is " << w1 << endl; mtl::matrix::poisson2D_dirichlet A(4, 15); vt w2(60); w2= A * v; tout << "A * v is " << w2 << endl; if (one_norm(vt(w1 - w2)) > 0.001) throw "Wrong result"; w2+= A * v; tout << "w2+= A * v is " << w2 << endl; if (one_norm(vt(w1 + w1 - w2)) > 0.001) throw "Wrong result"; w2-= A * v; tout << "w2-= A * v is " << w2 << endl; if (one_norm(vt(w1 - w2)) > 0.001) throw "Wrong result"; vt w3( w2 - A * v ); double alpha; (lazy(w3)= A * v) || (lazy(alpha)= lazy_dot(w3, v)); return 0; }
int main(int, char**) { using mtl::max; using std::pow; // to avoid possible ambiguity with ARPREC mtl::dense_vector<double> v(100); for (unsigned i= 0; i < size(v); i++) v[i]= double(i+1) * pow(-1.0, int(i)); // Amb. in MSVC std::cout << "max(v) is " << max(v)<< "\n"; std::cout << "min(v) is " << min(v)<< "\n"; std::cout << "max<6>(v) is " << max<6>(v)<< "\n"; return 0; }
void test(VectorU& u, VectorV& v, VectorW& w, const char* name) { using mtl::dot; // test right scale u= 3.0; v= 4.0; w= 5.0; std::cout << name << " --- v= u*3 + w*4;:\n"; std::cout.flush(); v= u*3 + w*4; cout << "v: " << v << "\n"; std::cout.flush(); MTL_THROW_IF(v[0] != 29.0, mtl::runtime_error("v wrong")); std::cout << name << " --- u= 3; v= 4; u+= v+= (w= 5) * 3.0;:\n"; std::cout.flush(); u= 3; v= 4; u+= v+= (w= 5.0) * 3.0; cout << "u: " << u << "v: " << v << "\n"; std::cout.flush(); MTL_THROW_IF(v[0] != 19.0, mtl::runtime_error("v wrong")); MTL_THROW_IF(u[0] != 22.0, mtl::runtime_error("u wrong")); std::cout << name << " --- u= 3; v= 4; w=5; u+= w * dot(v, w);:\n"; std::cout.flush(); u= 3; v= 4; w=5; u+= w * dot(v, w); cout << "u: " << u << "v: " << v << "w: " << w << "\n"; std::cout.flush(); MTL_THROW_IF(u[0] != 503.0, mtl::runtime_error("u wrong")); std::cout << name << " --- u+= w * dot<12>(v, w);:\n"; std::cout.flush(); u+= w * dot<12>(v, w); cout << "u: " << u << "v: " << v << "w: " << w << "\n"; std::cout.flush(); MTL_THROW_IF(u[0] != 1003.0, mtl::runtime_error("u wrong")); // test divide by scalar u= 3.0; v= 4.0; w= 5.0; std::cout << name << " --- v= u/3 + w/5;:\n"; std::cout.flush(); v= u/3 + w/5; cout << "v: " << v << "\n"; std::cout.flush(); MTL_THROW_IF(v[0] != 2.0, mtl::runtime_error("v wrong")); std::cout << name << " --- u= 3; v= 4; u+= v+= (w= 6.0) / 3.0;:\n"; std::cout.flush(); u= 3; v= 4; u+= v+= (w= 6.0) / 3.0; cout << "u: " << u << "v: " << v << "\n"; std::cout.flush(); MTL_THROW_IF(v[0] != 6.0, mtl::runtime_error("v wrong")); MTL_THROW_IF(u[0] != 9.0, mtl::runtime_error("u wrong")); }
void test(Vector& v, const char* name) { using mtl::size; using mtl::num_rows; using mtl::num_cols; cout << "\n" << name << "\n"; cout << "size(v) = " << size(v) << "\n"; // Value is less critical main purpose of the test is to check compilibilit MTL_THROW_IF(size(v) != 3, mtl::runtime_error("Vector size should be 3")); cout << "num_rows(v) = " << num_rows(v) << "\n"; // Value is less critical main purpose of the test is to check compilibilit MTL_THROW_IF(num_rows(v) != 3, mtl::runtime_error("Vector number of rows should be 3")); cout << "num_cols(v) = " << num_cols(v) << "\n"; // Value is less critical main purpose of the test is to check compilibilit MTL_THROW_IF(num_cols(v) != 1, mtl::runtime_error("Vector number of columns should be 1")); }
type lower_bound(Matrix const& c, size_type position) const { using mtl::num_cols; return type(std::min(num_cols(c), position), c); }
typename traits::permutation<Value>::type inline permutation(const PermutationVector& v) { using mtl::size; return reorder(v, size(v)); }
static inline void update(Value& value, const Element& x) { using mtl::squared_abs; value+= squared_abs(x); }
int bicgstab_ell(const LinearOperator &A, Vector &x, const Vector &b, const LeftPreconditioner &L, const RightPreconditioner &R, Iteration& iter, size_t l) { mtl::vampir_trace<7006> tracer; using mtl::size; using mtl::irange; using mtl::imax; using mtl::matrix::strict_upper; typedef typename mtl::Collection<Vector>::value_type Scalar; typedef typename mtl::Collection<Vector>::size_type Size; if (size(b) == 0) throw mtl::logic_error("empty rhs vector"); const Scalar zero= math::zero(Scalar()), one= math::one(Scalar()); Vector x0(resource(x)), y(resource(x)); mtl::vector::dense_vector<Vector> r_hat(l+1,Vector(resource(x))), u_hat(l+1,Vector(resource(x))); // shift problem x0= zero; r_hat[0]= b; if (two_norm(x) != zero) { r_hat[0]-= A * x; x0= x; x= zero; } Vector r0_tilde(r_hat[0]/two_norm(r_hat[0])); y= solve(L, r_hat[0]); r_hat[0]= y; u_hat[0]= zero; Scalar rho_0(one), rho_1(zero), alpha(zero), Gamma(zero), beta(zero), omega(one); mtl::matrix::dense2D<Scalar> tau(l+1, l+1); mtl::vector::dense_vector<Scalar> sigma(l+1), gamma(l+1), gamma_a(l+1), gamma_aa(l+1); while (! iter.finished(r_hat[0])) { ++iter; rho_0= -omega * rho_0; for (Size j= 0; j < l; ++j) { rho_1= dot(r0_tilde, r_hat[j]); beta= alpha * rho_1/rho_0; rho_0= rho_1; for (Size i= 0; i <= j; ++i) u_hat[i]= r_hat[i] - beta * u_hat[i]; y= A * Vector(solve(R, u_hat[j])); u_hat[j+1]= solve(L, y); Gamma= dot(r0_tilde, u_hat[j+1]); alpha= rho_0 / Gamma; for (Size i= 0; i <= j; ++i) r_hat[i]-= alpha * u_hat[i+1]; if (iter.finished(r_hat[j])) { x= solve(R, x); x+= x0; return iter; } r_hat[j+1]= solve(R, r_hat[j]); y= A * r_hat[j+1]; r_hat[j+1]= solve(L, y); x+= alpha * u_hat[0]; } // mod GS (MR part) irange i1m(1, imax); mtl::vector::dense_vector<Vector> r_hat_tail(r_hat[i1m]); tau[i1m][i1m]= orthogonalize_factors(r_hat_tail); for (Size j= 1; j <= l; ++j) gamma_a[j]= dot(r_hat[j], r_hat[0]) / tau[j][j]; gamma[l]= gamma_a[l]; omega= gamma[l]; if (omega == zero) return iter.fail(3, "bicg breakdown #2"); // is this something like a tri-solve? for (Size j= l-1; j > 0; --j) { Scalar sum= zero; for (Size i=j+1;i<=l;++i) sum += tau[j][i] * gamma[i]; gamma[j] = gamma_a[j] - sum; } gamma_aa[irange(1, l)]= strict_upper(tau[irange(1, l)][irange(1, l)]) * gamma[irange(2, l+1)] + gamma[irange(2, l+1)]; x+= gamma[1] * r_hat[0]; r_hat[0]-= gamma_a[l] * r_hat[l]; u_hat[0]-= gamma[l] * u_hat[l]; for (Size j=1; j < l; ++j) { u_hat[0] -= gamma[j] * u_hat[j]; x+= gamma_aa[j] * r_hat[j]; r_hat[0] -= gamma_a[j] * r_hat[j]; } } x= solve(R, x); x+= x0; // convert to real solution and undo shift return iter; }
type end(Matrix const& c) const { using mtl::num_rows; using mtl::matrix::num_rows; return type(num_rows(c), c); //return type(c.end_row(), c); }
type end(Cursor const& c) const { using mtl::num_cols; return type(c.ref, *c, num_cols(c.ref)); }
type end(Matrix const& c) const { using mtl::num_cols; return type(num_cols(c), c); // return type(c.end_col(), c); }
type end(Cursor const& c) const { using mtl::num_rows; return type(c.ref, num_rows(c.ref), *c); }
type end(Ref& c) { using mtl::size; return type(c.address_data() + size(c) + c.stride(), c.stride()); }
type lower_bound(Cursor const& c, size_type position) const { using mtl::num_rows; return type(c.ref, std::min(num_rows(c.ref), position), *c); }