38 #ifndef GMM_PRECOND_DIAGONAL_H
39 #define GMM_PRECOND_DIAGONAL_H
47 typedef typename linalg_traits<Matrix>::value_type value_type;
48 typedef typename number_traits<value_type>::magnitude_type magnitude_type;
50 std::vector<magnitude_type> diag;
52 void build_with(
const Matrix &M) {
53 diag.resize(mat_nrows(M));
54 for (size_type i = 0; i < mat_nrows(M); ++i) {
55 magnitude_type x = gmm::abs(M(i, i));
56 if (x == magnitude_type(0)) {
57 x = magnitude_type(1);
58 GMM_WARNING2(
"The matrix has a zero on its diagonal");
60 diag[i] = magnitude_type(1) / x;
63 size_type memsize()
const {
return sizeof(*this) + diag.size() *
sizeof(value_type); }
68 template <
typename Matrix,
typename V2>
inline
70 typename linalg_traits<V2>::iterator it = vect_begin(v2),
72 for (; it != ite; ++it) *it *= P.diag[it.index()];
75 template <
typename Matrix,
typename V2>
inline
76 void mult_diag_p(
const diagonal_precond<Matrix>& P,V2 &v2, abstract_skyline)
77 { mult_diag_p(P, v2, abstract_sparse()); }
79 template <
typename Matrix,
typename V2>
inline
80 void mult_diag_p(
const diagonal_precond<Matrix>& P, V2 &v2, abstract_dense){
81 for (
size_type i = 0; i < P.diag.size(); ++i) v2[i] *= P.diag[i];
84 template <
typename Matrix,
typename V1,
typename V2>
inline
85 void mult(
const diagonal_precond<Matrix>& P,
const V1 &v1, V2 &v2) {
86 GMM_ASSERT2(P.diag.size() == vect_size(v2),
"dimensions mismatch");
88 mult_diag_p(P, v2,
typename linalg_traits<V2>::storage_type());
91 template <
typename Matrix,
typename V1,
typename V2>
inline
92 void transposed_mult(
const diagonal_precond<Matrix>& P,
const V1 &v1,V2 &v2) {
98 template <
typename Matrix,
typename V1,
typename V2>
inline
99 void left_mult(
const diagonal_precond<Matrix>& P,
const V1 &v1, V2 &v2) {
100 GMM_ASSERT2(P.diag.size() == vect_size(v2),
"dimensions mismatch");
102 # ifdef DIAG_LEFT_MULT_SQRT
103 for (
size_type i= 0; i < P.diag.size(); ++i) v2[i] *= gmm::sqrt(P.diag[i]);
105 for (
size_type i= 0; i < P.diag.size(); ++i) v2[i] *= P.diag[i];
109 template <
typename Matrix,
typename V1,
typename V2>
inline
110 void transposed_left_mult(
const diagonal_precond<Matrix>& P,
111 const V1 &v1, V2 &v2)
112 { left_mult(P, v1, v2); }
114 template <
typename Matrix,
typename V1,
typename V2>
inline
115 void right_mult(
const diagonal_precond<Matrix>& P,
const V1 &v1, V2 &v2) {
117 GMM_ASSERT2(P.diag.size() == vect_size(v2),
"dimensions mismatch");
119 # ifdef DIAG_LEFT_MULT_SQRT
120 for (
size_type i= 0; i < P.diag.size(); ++i) v2[i] *= gmm::sqrt(P.diag[i]);
124 template <
typename Matrix,
typename V1,
typename V2>
inline
125 void transposed_right_mult(
const diagonal_precond<Matrix>& P,
126 const V1 &v1, V2 &v2)
127 { right_mult(P, v1, v2); }