72 #ifndef GMM_PRECOND_ILU_H 
   73 #define GMM_PRECOND_ILU_H 
   85   template <
typename Matrix>
 
   89     typedef typename linalg_traits<Matrix>::value_type value_type;
 
   90     typedef csr_matrix_ref<value_type *, size_type *, size_type *, 0> tm_type;
 
   95     std::vector<value_type> L_val, U_val;
 
   96     std::vector<size_type> L_ind, U_ind, L_ptr, U_ptr;
 
   98     template<
typename M> 
void do_ilu(
const M& A, row_major);
 
   99     void do_ilu(
const Matrix& A, col_major);
 
  103     size_type nrows(
void)
 const { 
return mat_nrows(L); }
 
  104     size_type ncols(
void)
 const { 
return mat_ncols(U); }
 
  106     void build_with(
const Matrix& A) {
 
  108        L_ptr.resize(mat_nrows(A)+1);
 
  109        U_ptr.resize(mat_nrows(A)+1);
 
  110        do_ilu(A, 
typename principal_orientation_type<
typename 
  111               linalg_traits<Matrix>::sub_orientation>::potype());
 
  115     size_type memsize()
 const { 
 
  116       return sizeof(*this) + 
 
  117         (L_val.size()+U_val.size()) * 
sizeof(value_type) + 
 
  118         (L_ind.size()+L_ptr.size()) * 
sizeof(size_type) +
 
  119         (U_ind.size()+U_ptr.size()) * 
sizeof(size_type); 
 
  123   template <
typename Matrix> 
template <
typename M>
 
  125     typedef typename linalg_traits<Matrix>::storage_type store_type;
 
  126     typedef value_type T;
 
  127     typedef typename number_traits<T>::magnitude_type R;
 
  129     size_type L_loc = 0, U_loc = 0, n = mat_nrows(A), i, j, k;
 
  131     L_ptr[0] = 0; U_ptr[0] = 0;
 
  132     R prec = default_tol(R());
 
  133     R max_pivot = gmm::abs(A(0,0)) * prec;
 
  136     for (
int count = 0; count < 2; ++count) {
 
  138         L_val.resize(L_loc); L_ind.resize(L_loc);
 
  139         U_val.resize(U_loc); U_ind.resize(U_loc);
 
  142       for (i = 0; i < n; ++i) {
 
  143         typedef typename linalg_traits<M>::const_sub_row_type row_type;
 
  144         row_type row = mat_const_row(A, i);
 
  145         typename linalg_traits<typename org_type<row_type>::t>::const_iterator
 
  146           it = vect_const_begin(row), ite = vect_const_end(row);
 
  148         if (count) { U_val[U_loc] = T(0); U_ind[U_loc] = i; }
 
  151         for (k = 0; it != ite && k < 1000; ++it, ++k) {
 
  154           j = index_of_it(it, k, store_type());
 
  156             if (count) { L_val[L_loc] = *it; L_ind[L_loc] = j; }
 
  160             if (count) U_val[U_loc-1] = *it;
 
  163             if (count) { U_val[U_loc] = *it; U_ind[U_loc] = j; }
 
  167         L_ptr[i+1] = L_loc; U_ptr[i+1] = U_loc;
 
  171     if (A(0,0) == T(0)) {
 
  172       U_val[U_ptr[0]] = T(1);
 
  173       GMM_WARNING2(
"pivot 0 is too small");
 
  177     for (i = 1; i < n; i++) {
 
  180       if (gmm::abs(U_val[pn]) <= max_pivot) {
 
  182         GMM_WARNING2(
"pivot " << i << 
" is too small");
 
  184       max_pivot = std::max(max_pivot,
 
  185                            std::min(gmm::abs(U_val[pn]) * prec, R(1)));
 
  187       for (j = L_ptr[i]; j < L_ptr[i+1]; j++) {
 
  188         pn = U_ptr[L_ind[j]];
 
  190         T multiplier = (L_val[j] /= U_val[pn]);
 
  195         for (pn++; pn < U_ptr[L_ind[j]+1] && U_ind[pn] < i; pn++) {
 
  196           while (qn < L_ptr[i+1] && L_ind[qn] < U_ind[pn])
 
  198           if (qn < L_ptr[i+1] && U_ind[pn] == L_ind[qn])
 
  199             L_val[qn] -= multiplier * U_val[pn];
 
  201         for (; pn < U_ptr[L_ind[j]+1]; pn++) {
 
  202           while (rn < U_ptr[i+1] && U_ind[rn] < U_ind[pn])
 
  204           if (rn < U_ptr[i+1] && U_ind[pn] == U_ind[rn])
 
  205             U_val[rn] -= multiplier * U_val[pn];
 
  210     L = tm_type(&(L_val[0]), &(L_ind[0]), &(L_ptr[0]), n, mat_ncols(A));
 
  211     U = tm_type(&(U_val[0]), &(U_ind[0]), &(U_ptr[0]), n, mat_ncols(A));
 
  214   template <
typename Matrix>
 
  215   void ilu_precond<Matrix>::do_ilu(
const Matrix& A, col_major) {
 
  216     do_ilu(gmm::transposed(A), row_major());
 
  220   template <
typename Matrix, 
typename V1, 
typename V2> 
inline 
  221   void mult(
const ilu_precond<Matrix>& P, 
const V1 &v1, V2 &v2) {
 
  224       gmm::lower_tri_solve(gmm::transposed(P.U), v2, 
false);
 
  225       gmm::upper_tri_solve(gmm::transposed(P.L), v2, 
true);
 
  228       gmm::lower_tri_solve(P.L, v2, 
true);
 
  229       gmm::upper_tri_solve(P.U, v2, 
false);
 
  233   template <
typename Matrix, 
typename V1, 
typename V2> 
inline 
  234   void transposed_mult(
const ilu_precond<Matrix>& P,
const V1 &v1,V2 &v2) {
 
  237       gmm::lower_tri_solve(P.L, v2, 
true);
 
  238       gmm::upper_tri_solve(P.U, v2, 
false);
 
  241       gmm::lower_tri_solve(gmm::transposed(P.U), v2, 
false);
 
  242       gmm::upper_tri_solve(gmm::transposed(P.L), v2, 
true);
 
  246   template <
typename Matrix, 
typename V1, 
typename V2> 
inline 
  247   void left_mult(
const ilu_precond<Matrix>& P, 
const V1 &v1, V2 &v2) {
 
  249     if (P.invert) gmm::lower_tri_solve(gmm::transposed(P.U), v2, 
false);
 
  250     else gmm::lower_tri_solve(P.L, v2, 
true);
 
  253   template <
typename Matrix, 
typename V1, 
typename V2> 
inline 
  254   void right_mult(
const ilu_precond<Matrix>& P, 
const V1 &v1, V2 &v2) {
 
  256     if (P.invert) gmm::upper_tri_solve(gmm::transposed(P.L), v2, 
true);
 
  257     else gmm::upper_tri_solve(P.U, v2, 
false);
 
  260   template <
typename Matrix, 
typename V1, 
typename V2> 
inline 
  261   void transposed_left_mult(
const ilu_precond<Matrix>& P, 
const V1 &v1,
 
  264     if (P.invert) gmm::upper_tri_solve(P.U, v2, 
false);
 
  265     else gmm::upper_tri_solve(gmm::transposed(P.L), v2, 
true);
 
  268   template <
typename Matrix, 
typename V1, 
typename V2> 
inline 
  269   void transposed_right_mult(
const ilu_precond<Matrix>& P, 
const V1 &v1,
 
  272     if (P.invert) gmm::lower_tri_solve(P.L, v2, 
true);
 
  273     else gmm::lower_tri_solve(gmm::transposed(P.U), v2, 
false);
 
Incomplete LU without fill-in Preconditioner.
 
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