73 #ifndef GMM_PRECOND_MR_APPROX_INVERSE_H
74 #define GMM_PRECOND_MR_APPROX_INVERSE_H
83 template <
typename Matrix>
86 typedef typename linalg_traits<Matrix>::value_type value_type;
87 typedef typename number_traits<value_type>::magnitude_type magnitude_type;
88 typedef typename principal_orientation_type<
typename
89 linalg_traits<Matrix>::sub_orientation>::potype sub_orientation;
91 typedef col_matrix<VVector> MMatrix;
95 magnitude_type threshold;
97 void build_with(
const Matrix& A);
99 magnitude_type threshold_)
100 : M(mat_nrows(A), mat_ncols(A))
101 { threshold = threshold_; nb_it = nb_it_; build_with(A); }
103 { threshold = magnitude_type(1E-7); nb_it = 5; }
105 { threshold = threshold_; nb_it = nb_it_; }
106 const MMatrix &approx_inverse(
void)
const {
return M; }
109 template <
typename Matrix,
typename V1,
typename V2>
inline
111 { mult(P.M, v1, v2); }
113 template <
typename Matrix,
typename V1,
typename V2>
inline
114 void transposed_mult(
const mr_approx_inverse_precond<Matrix>& P,
116 { mult(gmm::conjugated(P.M), v1, v2); }
118 template <
typename Matrix>
119 void mr_approx_inverse_precond<Matrix>::build_with(
const Matrix& A) {
121 typedef value_type T;
122 typedef magnitude_type R;
123 VVector m(mat_ncols(A)),r(mat_ncols(A)),ei(mat_ncols(A)),Ar(mat_ncols(A));
125 if (alpha == T(0))
alpha = T(1);
127 for (
size_type i = 0; i < mat_nrows(A); ++i) {
133 gmm::mult(A, gmm::scaled(m, T(-1)), r);
137 if (gmm::abs(nAr) > R(0)) {
138 gmm::add(gmm::scaled(r, gmm::safe_divide(
vect_sp(r, Ar),
vect_sp(Ar, Ar))), m);
139 gmm::clean(m, threshold * gmm::vect_norm2(m));
142 if (gmm::vect_norm2(m) == R(0)) m[i] =
alpha;
143 gmm::copy(m, M.col(i));