64 #ifndef GMM_PRECOND_ILUT_H 
   65 #define GMM_PRECOND_ILUT_H 
   87   template<
typename T> 
struct elt_rsvector_value_less_ {
 
   88     inline bool operator()(
const elt_rsvector_<T>& a, 
 
   89                            const elt_rsvector_<T>& b)
 const 
   90     { 
return (gmm::abs(a.e) > gmm::abs(b.e)); }
 
  101   template <
typename Matrix>
 
  104     typedef typename linalg_traits<Matrix>::value_type value_type;
 
  107     typedef row_matrix<_rsvector> LU_Matrix;
 
  116     template<
typename M> 
void do_ilut(
const M&, row_major);
 
  117     void do_ilut(
const Matrix&, col_major);
 
  120     void build_with(
const Matrix& A, 
int k_ = -1, 
double eps_ = 
double(-1)) {
 
  122       if (eps_ >= 
double(0)) eps = eps_;
 
  126       do_ilut(A, 
typename principal_orientation_type<
typename 
  127               linalg_traits<Matrix>::sub_orientation>::potype());
 
  130       : L(mat_nrows(A), mat_ncols(A)), U(mat_nrows(A), mat_ncols(A)),
 
  131         K(k_), eps(eps_) { build_with(A); }
 
  132     ilut_precond(size_type k_, 
double eps_) :  K(k_), eps(eps_) {}
 
  134     size_type memsize()
 const { 
 
  135       return sizeof(*this) + (
nnz(U)+
nnz(L))*
sizeof(value_type);
 
  139   template<
typename Matrix> 
template<
typename M> 
 
  141     typedef value_type T;
 
  142     typedef typename number_traits<T>::magnitude_type R;
 
  144     size_type n = mat_nrows(A);
 
  146     std::vector<T> indiag(n);
 
  147     _wsvector w(mat_ncols(A));
 
  148     _rsvector ww(mat_ncols(A)), wL(mat_ncols(A)), wU(mat_ncols(A));
 
  151     R prec = default_tol(R()); 
 
  152     R max_pivot = gmm::abs(A(0,0)) * prec;
 
  154     for (size_type i = 0; i < n; ++i) {
 
  158       typename _wsvector::iterator wkold = w.end();
 
  159       for (
typename _wsvector::iterator wk = w.begin();
 
  160            wk != w.end() && wk->first < i; ) {
 
  161         size_type k = wk->first;
 
  162         tmp = (wk->second) * indiag[k];
 
  163         if (gmm::abs(tmp) < eps * norm_row) w.erase(k);
 
  164         else { wk->second += tmp; 
gmm::add(scaled(mat_row(U, k), -tmp), w); }
 
  165         if (wkold == w.end()) wk = w.begin(); 
else { wk = wkold; ++wk; }
 
  166         if (wk != w.end() && wk->first == k)
 
  167           { 
if (wkold == w.end()) wkold = w.begin(); 
else ++wkold; ++wk; }
 
  171       if (gmm::abs(tmp) <= max_pivot) {
 
  172         GMM_WARNING2(
"pivot " << i << 
" too small. try with ilutp ?");
 
  176       max_pivot = std::max(max_pivot, std::min(gmm::abs(tmp) * prec, R(1)));
 
  177       indiag[i] = T(1) / tmp;
 
  180       std::sort(ww.begin(), ww.end(), elt_rsvector_value_less_<T>());
 
  181       typename _rsvector::const_iterator wit = ww.begin(), wite = ww.end();
 
  184       wL.base_resize(K); wU.base_resize(K+1);
 
  185       typename _rsvector::iterator witL = wL.begin(), witU = wU.begin();
 
  186       for (; wit != wite; ++wit) 
 
  187         if (wit->c < i) { 
if (nnl < K) { *witL++ = *wit; ++nnl; } }
 
  188         else { 
if (nnu < K  || wit->c == i) { *witU++ = *wit; ++nnu; } }
 
  189       wL.base_resize(nnl); wU.base_resize(nnu);
 
  190       std::sort(wL.begin(), wL.end());
 
  191       std::sort(wU.begin(), wU.end());
 
  198   template<
typename Matrix> 
 
  199   void ilut_precond<Matrix>::do_ilut(
const Matrix& A, col_major) {
 
  200     do_ilut(gmm::transposed(A), row_major());
 
  204   template <
typename Matrix, 
typename V1, 
typename V2> 
inline 
  205   void mult(
const ilut_precond<Matrix>& P, 
const V1 &v1, V2 &v2) {
 
  208       gmm::lower_tri_solve(gmm::transposed(P.U), v2, 
false);
 
  209       gmm::upper_tri_solve(gmm::transposed(P.L), v2, 
true);
 
  212       gmm::lower_tri_solve(P.L, v2, 
true);
 
  213       gmm::upper_tri_solve(P.U, v2, 
false);
 
  217   template <
typename Matrix, 
typename V1, 
typename V2> 
inline 
  218   void transposed_mult(
const ilut_precond<Matrix>& P,
const V1 &v1,V2 &v2) {
 
  221       gmm::lower_tri_solve(P.L, v2, 
true);
 
  222       gmm::upper_tri_solve(P.U, v2, 
false);
 
  225       gmm::lower_tri_solve(gmm::transposed(P.U), v2, 
false);
 
  226       gmm::upper_tri_solve(gmm::transposed(P.L), v2, 
true);
 
  230   template <
typename Matrix, 
typename V1, 
typename V2> 
inline 
  231   void left_mult(
const ilut_precond<Matrix>& P, 
const V1 &v1, V2 &v2) {
 
  233     if (P.invert) gmm::lower_tri_solve(gmm::transposed(P.U), v2, 
false);
 
  234     else gmm::lower_tri_solve(P.L, v2, 
true);
 
  237   template <
typename Matrix, 
typename V1, 
typename V2> 
inline 
  238   void right_mult(
const ilut_precond<Matrix>& P, 
const V1 &v1, V2 &v2) {
 
  240     if (P.invert) gmm::upper_tri_solve(gmm::transposed(P.L), v2, 
true);
 
  241     else gmm::upper_tri_solve(P.U, v2, 
false);
 
  244   template <
typename Matrix, 
typename V1, 
typename V2> 
inline 
  245   void transposed_left_mult(
const ilut_precond<Matrix>& P, 
const V1 &v1,
 
  248     if (P.invert) gmm::upper_tri_solve(P.U, v2, 
false);
 
  249     else gmm::upper_tri_solve(gmm::transposed(P.L), v2, 
true);
 
  252   template <
typename Matrix, 
typename V1, 
typename V2> 
inline 
  253   void transposed_right_mult(
const ilut_precond<Matrix>& P, 
const V1 &v1,
 
  256     if (P.invert) gmm::lower_tri_solve(P.L, v2, 
true);
 
  257     else gmm::lower_tri_solve(gmm::transposed(P.U), v2, 
false);
 
Incomplete LU with threshold and K fill-in Preconditioner.
 
sparse vector built upon std::vector.
 
sparse vector built upon std::map.
 
size_type nnz(const L &l)
count the number of non-zero entries of a vector or matrix.
 
void copy(const L1 &l1, L2 &l2)
*/
 
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2(const V &v)
Euclidean norm of a vector.
 
void clear(L &l)
clear (fill with zeros) a vector or matrix.
 
void resize(V &v, size_type n)
*/
 
void clean(L &l, double threshold)
Clean a vector or matrix (replace near-zero entries with zeroes).
 
void mult(const L1 &l1, const L2 &l2, L3 &l3)
*/
 
void add(const L1 &l1, L2 &l2)
*/
 
size_t size_type
used as the common size type in the library