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")); }
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(); }