37 #ifndef GMM_PRECOND_DIAGONAL_H
38 #define GMM_PRECOND_DIAGONAL_H
46 typedef typename linalg_traits<Matrix>::value_type value_type;
47 typedef typename number_traits<value_type>::magnitude_type magnitude_type;
49 std::vector<magnitude_type> diag;
51 void build_with(
const Matrix &M) {
52 diag.resize(mat_nrows(M));
53 for (size_type i = 0; i < mat_nrows(M); ++i) {
54 magnitude_type x = gmm::abs(M(i, i));
55 if (x == magnitude_type(0)) {
56 x = magnitude_type(1);
57 GMM_WARNING2(
"The matrix has a zero on its diagonal");
59 diag[i] = magnitude_type(1) / x;
62 size_type memsize()
const {
return sizeof(*this) + diag.size() *
sizeof(value_type); }
67 template <
typename Matrix,
typename V2>
inline
69 typename linalg_traits<V2>::iterator it = vect_begin(v2),
71 for (; it != ite; ++it) *it *= P.diag[it.index()];
74 template <
typename Matrix,
typename V2>
inline
75 void mult_diag_p(
const diagonal_precond<Matrix>& P,V2 &v2, abstract_skyline)
76 { mult_diag_p(P, v2, abstract_sparse()); }
78 template <
typename Matrix,
typename V2>
inline
79 void mult_diag_p(
const diagonal_precond<Matrix>& P, V2 &v2, abstract_dense){
80 for (
size_type i = 0; i < P.diag.size(); ++i) v2[i] *= P.diag[i];
83 template <
typename Matrix,
typename V1,
typename V2>
inline
84 void mult(
const diagonal_precond<Matrix>& P,
const V1 &v1, V2 &v2) {
85 GMM_ASSERT2(P.diag.size() == vect_size(v2),
"dimensions mismatch");
87 mult_diag_p(P, v2,
typename linalg_traits<V2>::storage_type());
90 template <
typename Matrix,
typename V1,
typename V2>
inline
91 void transposed_mult(
const diagonal_precond<Matrix>& P,
const V1 &v1,V2 &v2) {
97 template <
typename Matrix,
typename V1,
typename V2>
inline
98 void left_mult(
const diagonal_precond<Matrix>& P,
const V1 &v1, V2 &v2) {
99 GMM_ASSERT2(P.diag.size() == vect_size(v2),
"dimensions mismatch");
101 # ifdef DIAG_LEFT_MULT_SQRT
102 for (
size_type i= 0; i < P.diag.size(); ++i) v2[i] *= gmm::sqrt(P.diag[i]);
104 for (
size_type i= 0; i < P.diag.size(); ++i) v2[i] *= P.diag[i];
108 template <
typename Matrix,
typename V1,
typename V2>
inline
109 void transposed_left_mult(
const diagonal_precond<Matrix>& P,
110 const V1 &v1, V2 &v2)
111 { left_mult(P, v1, v2); }
113 template <
typename Matrix,
typename V1,
typename V2>
inline
114 void right_mult(
const diagonal_precond<Matrix>& P,
const V1 &v1, V2 &v2) {
116 GMM_ASSERT2(P.diag.size() == vect_size(v2),
"dimensions mismatch");
118 # ifdef DIAG_LEFT_MULT_SQRT
119 for (
size_type i= 0; i < P.diag.size(); ++i) v2[i] *= gmm::sqrt(P.diag[i]);
123 template <
typename Matrix,
typename V1,
typename V2>
inline
124 void transposed_right_mult(
const diagonal_precond<Matrix>& P,
125 const V1 &v1, V2 &v2)
126 { right_mult(P, v1, v2); }
void copy(const L1 &l1, L2 &l2)
*/
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
size_t size_type
used as the common size type in the library