20 #ifndef SELDON_FILE_ILUT_PRECONDITIONING_CXX
22 #include "SymmetricIlutPreconditioning.cxx"
27 template<
class cplx,
class Allocator>
28 IlutPreconditioning<cplx, Allocator>::IlutPreconditioning()
31 symmetric_algorithm =
false;
34 additional_fill = 1000000;
42 template<
class cplx,
class Allocator>
43 void IlutPreconditioning<cplx, Allocator>::Clear()
45 permutation_row.Clear();
51 template<
class cplx,
class Allocator>
52 bool IlutPreconditioning<cplx, Allocator>::UseInteger8()
const
58 template<
class cplx,
class Allocator>
59 void IlutPreconditioning<cplx, Allocator>::HideMessages()
65 template<
class cplx,
class Allocator>
66 void IlutPreconditioning<cplx, Allocator>::ShowMessages()
72 template<
class cplx,
class Allocator>
73 int IlutPreconditioning<cplx, Allocator>::GetFactorisationType()
const
79 template<
class cplx,
class Allocator>
80 int IlutPreconditioning<cplx, Allocator>::GetFillLevel()
const
86 template<
class cplx,
class Allocator>
87 int IlutPreconditioning<cplx, Allocator>::GetAdditionalFillNumber()
90 return additional_fill;
94 template<
class cplx,
class Allocator>
95 int IlutPreconditioning<cplx, Allocator>::GetPrintLevel()
const
101 template<
class cplx,
class Allocator>
102 int IlutPreconditioning<cplx, Allocator>::GetPivotBlockInteger()
const
108 template<
class cplx,
class Allocator>
109 size_t IlutPreconditioning<cplx, Allocator>::GetMemorySize()
const
111 size_t taille =
sizeof(int)*(permutation_row.GetM() + permutation_col.GetM());
112 taille += mat_sym.GetMemorySize() + mat_unsym.GetMemorySize();
117 template<
class T,
class Allocator>
118 inline int IlutPreconditioning<T, Allocator>::GetInfoFactorization()
const
124 template<
class cplx,
class Allocator>
125 void IlutPreconditioning<cplx, Allocator>
126 ::SetFactorisationType(
int type)
132 template<
class cplx,
class Allocator>
133 void IlutPreconditioning<cplx, Allocator>::SetFillLevel(
int level)
139 template<
class cplx,
class Allocator>
140 void IlutPreconditioning<cplx, Allocator>
141 ::SetAdditionalFillNumber(
int level)
143 additional_fill = level;
147 template<
class cplx,
class Allocator>
148 void IlutPreconditioning<cplx, Allocator>::SetPrintLevel(
int level)
154 template<
class cplx,
class Allocator>
155 void IlutPreconditioning<cplx, Allocator>::SetPivotBlockInteger(
int i)
161 template<
class cplx,
class Allocator>
162 typename ClassComplexType<cplx>::Treal IlutPreconditioning<cplx, Allocator>
163 ::GetDroppingThreshold()
const
169 template<
class cplx,
class Allocator>
170 typename ClassComplexType<cplx>::Treal IlutPreconditioning<cplx, Allocator>
171 ::GetDiagonalCoefficient()
const
177 template<
class cplx,
class Allocator>
178 typename ClassComplexType<cplx>::Treal IlutPreconditioning<cplx, Allocator>
179 ::GetPivotThreshold()
const
185 template<
class cplx,
class Allocator>
186 void IlutPreconditioning<cplx, Allocator>
187 ::SetDroppingThreshold(
typename ClassComplexType<cplx>::Treal tol)
193 template<
class cplx,
class Allocator>
194 void IlutPreconditioning<cplx, Allocator>
195 ::SetDiagonalCoefficient(
typename ClassComplexType<cplx>::Treal beta)
201 template<
class cplx,
class Allocator>
209 template<
class cplx,
class Allocator>
212 symmetric_algorithm =
true;
216 template<
class cplx,
class Allocator>
217 void IlutPreconditioning<cplx, Allocator>::SetUnsymmetricAlgorithm()
219 symmetric_algorithm =
false;
223 template<
class cplx,
class Allocator>
224 template<
class T0,
class Storage0,
class Allocator0>
225 void IlutPreconditioning<cplx, Allocator>::
226 FactorizeMatrix(
const IVect& perm,
227 Matrix<T0, General, Storage0, Allocator0>& mat,
230 if (symmetric_algorithm)
232 cout <<
"Conversion to symmetric matrices not implemented." << endl;
236 FactorizeUnsymMatrix(perm, mat, keep_matrix);
240 template<
class cplx,
class Allocator>
241 template<
class T0,
class Storage0,
class Allocator0>
242 void IlutPreconditioning<cplx, Allocator>::
243 FactorizeMatrix(
const IVect& perm,
244 Matrix<T0, Symmetric, Storage0, Allocator0>& mat,
247 if (symmetric_algorithm)
248 FactorizeSymMatrix(perm, mat, keep_matrix);
250 FactorizeUnsymMatrix(perm, mat, keep_matrix);
254 template<
class cplx,
class Allocator>
255 template<
class MatrixSparse>
256 void IlutPreconditioning<cplx, Allocator>::
257 FactorizeSymMatrix(
const IVect& perm, MatrixSparse& mat,
bool keep_matrix)
259 IVect inv_permutation;
269 int n = mat_sym.GetM();
270 if (perm.GetM() != n)
272 cout <<
"Numbering array should have the same size as matrix.";
277 permutation_row.Reallocate(n);
278 inv_permutation.Reallocate(n);
279 inv_permutation.Fill(-1);
280 for (
int i = 0; i < n; i++)
282 permutation_row(i) = perm(i);
283 inv_permutation(perm(i)) = i;
286 for (
int i = 0; i < n; i++)
287 if (inv_permutation(i) == -1)
289 cout <<
"Error in the numbering array." << endl;
294 ApplyInversePermutation(mat_sym, perm, perm);
301 template<
class cplx,
class Allocator>
302 template<
class MatrixSparse>
303 void IlutPreconditioning<cplx, Allocator>::
304 FactorizeUnsymMatrix(
const IVect& perm, MatrixSparse& mat,
bool keep_matrix)
306 IVect inv_permutation;
309 Copy(mat, mat_unsym);
316 int n = mat_unsym.GetM();
317 if (perm.GetM() != n)
319 cout <<
"Numbering array should have the same size as matrix.";
324 permutation_row.Reallocate(n);
325 permutation_col.Reallocate(n);
326 inv_permutation.Reallocate(n);
327 inv_permutation.Fill(-1);
328 for (
int i = 0; i < n; i++)
330 permutation_row(i) = i;
331 permutation_col(i) = i;
332 inv_permutation(perm(i)) = i;
335 for (
int i = 0; i < n; i++)
336 if (inv_permutation(i) == -1)
338 cout <<
"Error in the numbering array." << endl;
342 IVect iperm = inv_permutation;
345 ApplyInversePermutation(mat_unsym, perm, perm);
349 inv_permutation.Fill();
350 GetIlut(*
this, mat_unsym, permutation_col, inv_permutation);
353 IVect itmp = permutation_col;
354 for (
int i = 0; i < n; i++)
355 permutation_col(i) = iperm(itmp(i));
357 permutation_row = perm;
361 #ifdef SELDON_WITH_VIRTUAL
362 template<
class T,
class Allocator>
365 ::Solve(
const VirtualMatrix<T>&,
const Vector<T>& r, Vector<T>& z)
367 if (symmetric_algorithm)
370 for (
int i = 0; i < r.GetM(); i++)
371 xtmp(permutation_row(i)) = r(i);
373 SolveLU(mat_sym, xtmp);
375 for (
int i = 0; i < r.GetM(); i++)
376 z(i) = xtmp(permutation_row(i));
381 for (
int i = 0; i < r.GetM(); i++)
382 xtmp(permutation_row(i)) = r(i);
384 SolveLU(mat_unsym, xtmp);
386 for (
int i = 0; i < r.GetM(); i++)
387 z(permutation_col(i)) = xtmp(i);
393 template<
class T,
class Allocator>
395 ::TransSolve(
const VirtualMatrix<T>& A,
const Vector<T>& r, Vector<T>& z)
397 if (symmetric_algorithm)
402 for (
int i = 0; i < r.GetM(); i++)
403 xtmp(i) = r(permutation_col(i));
405 SolveLU(SeldonTrans, mat_unsym, xtmp);
407 for (
int i = 0; i < r.GetM(); i++)
408 z(i) = xtmp(permutation_row(i));
415 template<
class cplx,
class Allocator>
416 template<
class Matrix1,
class Vector1>
418 ::Solve(
const Matrix1& A,
const Vector1& r, Vector1& z)
420 if (symmetric_algorithm)
423 for (
int i = 0; i < r.GetM(); i++)
424 xtmp(permutation_row(i)) = r(i);
426 SolveLU(mat_sym, xtmp);
428 for (
int i = 0; i < r.GetM(); i++)
429 z(i) = xtmp(permutation_row(i));
434 for (
int i = 0; i < r.GetM(); i++)
435 xtmp(permutation_row(i)) = r(i);
437 SolveLU(mat_unsym, xtmp);
439 for (
int i = 0; i < r.GetM(); i++)
440 z(permutation_col(i)) = xtmp(i);
446 template<
class cplx,
class Allocator>
447 template<
class Matrix1,
class Vector1>
451 if (symmetric_algorithm)
456 for (
int i = 0; i < r.GetM(); i++)
457 xtmp(i) = r(permutation_col(i));
459 SolveLU(SeldonTrans, mat_unsym, xtmp);
461 for (
int i = 0; i < r.GetM(); i++)
462 z(i) = xtmp(permutation_row(i));
468 template<
class cplx,
class Allocator>
469 template<
class Vector1>
472 if (symmetric_algorithm)
475 for (
int i = 0; i < z.GetM(); i++)
476 xtmp(permutation_row(i)) = z(i);
478 SolveLU(mat_sym, xtmp);
480 for (
int i = 0; i < z.GetM(); i++)
481 z(i) = xtmp(permutation_row(i));
486 for (
int i = 0; i < z.GetM(); i++)
487 xtmp(permutation_row(i)) = z(i);
489 SolveLU(mat_unsym, xtmp);
491 for (
int i = 0; i < z.GetM(); i++)
492 z(permutation_col(i)) = xtmp(i);
497 template<
class cplx,
class Allocator>
498 template<
class Vector1>
501 if (symmetric_algorithm)
506 for (
int i = 0; i < z.GetM(); i++)
507 xtmp(i) = z(permutation_col(i));
509 SolveLU(SeldonTrans, mat_unsym, xtmp);
511 for (
int i = 0; i < z.GetM(); i++)
512 z(i) = xtmp(permutation_row(i));
517 template<
class cplx,
class Allocator>
template<
class Vector1>
519 ::Solve(
const SeldonTranspose& transA, Vector1& z)
528 template<
class cplx,
class Allocator>
530 ::Solve(
const SeldonTranspose& TransA, cplx* x_ptr,
int nrhs)
533 int n = permutation_row.GetM();
534 for (
int k = 0; k < nrhs; k++)
536 x.SetData(n, &x_ptr[k*n]);
543 template<
class real,
class cplx,
class Storage,
class Allocator>
544 void qsplit_ilut(Vector<cplx, Storage, Allocator>& a, IVect& ind,
int first,
545 int n,
int ncut,
const real& abs_ncut)
561 if ((ncut_ < first_) || (ncut_ > last))
564 cplx tmp; real abskey;
566 bool test_loop =
true;
572 abskey = abs(a(mid));
573 for (
int j = (first_+1); j <= last; j++)
575 if (abs(a(j)) > abskey)
594 ind(mid) = ind(first_);
610 template<
class cplx,
class Allocator1,
class Allocator2>
617 int type_factorization = param.GetFactorisationType();
618 int lfil = param.GetFillLevel();
619 typename ClassComplexType<cplx>::Treal zero(0);
620 typename ClassComplexType<cplx>::Treal droptol = param.GetDroppingThreshold();
621 typename ClassComplexType<cplx>::Treal alpha = param.GetDiagonalCoefficient();
622 bool variable_fill =
false;
623 bool standard_dropping =
true;
624 int additional_fill = param.GetAdditionalFillNumber();
625 int mbloc = param.GetPivotBlockInteger();
626 typename ClassComplexType<cplx>::Treal permtol = param.GetPivotThreshold();
627 int print_level = param.GetPrintLevel();
629 if (type_factorization == param.ILUT)
630 standard_dropping =
false;
631 else if (type_factorization == param.ILU_D)
632 standard_dropping =
true;
633 else if (type_factorization == param.ILUT_K)
635 variable_fill =
true;
636 standard_dropping =
false;
638 else if (type_factorization == param.ILU_0)
643 else if (type_factorization == param.MILU_0)
648 else if (type_factorization == param.ILU_K)
655 typename ClassComplexType<cplx>::Treal tnorm;
656 int length_lower, length_upper, jpos, jrow, i_row, j_col;
657 int i, j, k, index_lu, length;
662 cout <<
"Incorrect fill level." << endl;
667 SetComplexZero(czero);
671 IVect Index(n), Row_Ind(n), Index_Diag(n);
678 bool element_dropped; cplx dropsum;
681 int new_percent = 0, old_percent = 0;
682 for (i_row = 0; i_row < n; i_row++)
687 new_percent = int(
double(i_row)/(n-1)*80);
688 for (
int percent = old_percent; percent < new_percent; percent++)
690 cout <<
"#"; cout.flush();
693 old_percent = new_percent;
696 size_row = A.GetRowSize(i_row);
700 for (k = 0 ; k < size_row; k++)
701 if (A.Value(i_row, k) != czero)
702 tnorm += abs(A.Value(i_row, k));
706 cout <<
"Structurally singular matrix." << endl;
707 cout <<
"Norm of row " << i_row <<
" is equal to 0." << endl;
712 tnorm /=
typename ClassComplexType<cplx>::Treal(size_row);
714 lfil = size_row + additional_fill;
719 Row_Ind(i_row) = i_row;
720 Row_Val(i_row) = czero;
721 Index(i_row) = i_row;
723 for (j = 0; j < size_row; j++)
725 k = rperm(A.Index(i_row, j));
727 t = A.Value(i_row,j);
730 Row_Ind(length_lower) = k;
731 Row_Val(length_lower) = t;
732 Index(k) = length_lower;
741 jpos = i_row + length_upper;
753 while (j_col < length_lower)
757 jrow = Row_Ind(j_col);
761 for (j = j_col + 1; j < length_lower; j++)
763 if (Row_Ind(j) < jrow)
774 Row_Ind(j_col) = Row_Ind(k);
781 Row_Val(j_col) = Row_Val(k);
788 element_dropped =
false;
789 if (standard_dropping)
790 if (abs(Row_Val(j_col)) <= droptol*tnorm)
792 dropsum += Row_Val(j_col);
793 element_dropped =
true;
797 if (!element_dropped)
800 fact = Row_Val(j_col) * A.Value(jrow, Index_Diag(jrow));
802 if (!standard_dropping)
804 if (abs(fact) <= droptol)
805 element_dropped =
true;
809 if (!element_dropped)
812 for (k = (Index_Diag(jrow)+1); k < A.GetRowSize(jrow); k++)
814 s = fact * A.Value(jrow,k);
815 j = rperm(A.Index(jrow,k));
826 i = i_row + length_upper;
844 Row_Ind(length_lower) = j;
845 Index(j) = length_lower;
846 Row_Val(length_lower) = -s;
859 Row_Val(length) = fact;
860 Row_Ind(length) = jrow;
868 for (k = 0; k < length_upper; k++)
869 Index(Row_Ind(i_row+k )) = -1;
872 if (!standard_dropping)
874 length_lower = length;
875 length = min(length_lower,lfil);
878 qsplit_ilut(Row_Val, Row_Ind, 0, length_lower, length,tnorm);
882 A.ReallocateRow(i_row,size_row);
886 for (k = 0 ; k < length ; k++)
888 A.Value(i_row,index_lu) = Row_Val(k);
889 A.Index(i_row,index_lu) = iperm(Row_Ind(k));
894 Index_Diag(i_row) = index_lu;
898 for (k = 1; k <= (length_upper-1); k++)
900 if (abs(Row_Val(i_row+k)) > droptol * tnorm)
903 Row_Val(i_row+length) = Row_Val(i_row+k);
904 Row_Ind(i_row+length) = Row_Ind(i_row+k);
907 dropsum += Row_Val(i_row+k);
910 if (!standard_dropping)
912 length_upper = length + 1;
913 length = min(length_upper,lfil);
915 qsplit_ilut(Row_Val, Row_Ind, i_row+1,
916 i_row+length_upper, i_row+length+1, tnorm);
923 typename ClassComplexType<cplx>::Treal xmax = abs(Row_Val(imax));
924 typename ClassComplexType<cplx>::Treal xmax0 = xmax;
925 int icut = i_row + mbloc - 1 - i_row%mbloc;
926 for ( k = i_row + 1; k <= i_row + length - 1; k++)
928 tnorm = abs(Row_Val(k));
929 if ((tnorm > xmax) && (tnorm*permtol > xmax0)
930 && (Row_Ind(k)<= icut))
939 Row_Val(i_row) = Row_Val(imax);
945 iperm(i_row) = iperm(j);
949 rperm(iperm(i_row)) = i_row;
953 int index_diag = index_lu;
954 A.ResizeRow(i_row, size_row+length);
956 for (k = i_row ; k <= i_row + length - 1; k++)
958 A.Index(i_row,index_lu) = iperm(Row_Ind(k));
959 A.Value(i_row,index_lu) = Row_Val(k);
964 if (standard_dropping)
965 Row_Val(i_row) += alpha*dropsum;
967 if (Row_Val(i_row) == czero)
968 Row_Val(i_row) = (droptol +
typename
969 ClassComplexType<cplx>::Treal(1e-4)) * tnorm;
971 A.Value(i_row, index_diag) = cone / Row_Val(i_row);
979 cout <<
"The matrix takes " <<
980 int((A.GetDataSize()*(
sizeof(cplx)+4))/(1024*1024)) <<
" MB" << endl;
982 for (i = 0; i < n; i++ )
983 for (j = 0; j < A.GetRowSize(i); j++)
984 A.Index(i,j) = rperm(A.Index(i,j));
988 template<
class cplx,
class Allocator>
989 void GetIluk(
int lfil, Matrix<cplx, General, ArrayRowSparse, Allocator>& A)
994 IVect jw(3*n), Index_Diag(n);
995 Vector<IVect, VectFull, NewAlloc<IVect> > levs(n);
998 SetComplexZero(czero);
1003 int length_lower,length_upper, jpos, jrow, i_row, j_col;
1004 int i, j, k, index_lu;
1005 bool element_dropped;
1007 int n2 = 2*n, jlev, k_, size_upper;
1011 for (i_row = 0; i_row < n; i_row++)
1013 int size_row = A.GetRowSize(i_row);
1020 jw(n + i_row) = i_row;
1022 for (j = 0; j < size_row; j++)
1024 k = A.Index(i_row,j);
1025 t = A.Value(i_row,j);
1028 jw(length_lower) = k;
1029 w(length_lower) = t;
1030 jw(n + k) = length_lower;
1031 jw(n2+length_lower) = -1;
1034 else if (k == i_row)
1037 jw(n2+length_lower) = -1;
1041 jpos = i_row + length_upper;
1052 while (j_col <length_lower)
1061 for (j = (j_col+1) ; j < length_lower; j++)
1083 jw(n2+j_col) = jw(n2+k);
1095 element_dropped =
false;
1098 fact = w(j_col) * A.Value(jrow,Index_Diag(jrow));
1100 jlev = jw(n2+j_col) + 1;
1102 element_dropped =
true;
1104 if (!element_dropped)
1108 for (k = (Index_Diag(jrow)+1); k < A.GetRowSize(jrow) ; k++)
1110 s = fact * A.Value(jrow,k);
1111 j = A.Index(jrow,k);
1120 i = i_row + length_upper;
1125 jw(n2+i) = jlev + levs(jrow)(k_) + 1;
1132 jw(n2+jpos) = min(jw(n2+jpos),
1133 jlev + levs(jrow)(k_)+1);
1142 jw(length_lower) = j;
1143 jw(n + j) = length_lower;
1144 w(length_lower) = -s;
1145 jw(n2+length_lower) = jlev + levs(jrow)(k_) + 1;
1152 jw(n2+jpos) = min(jw(n2 + jpos),
1153 jlev + levs(jrow)(k_) + 1);
1171 for (k = 0; k < length_upper; k++)
1172 jw(n + jw(i_row + k )) = -1;
1177 for (k = 0; k < length_lower; k++)
1178 if (jw(n2+k) < lfil)
1183 for (k = (i_row+1) ; k <= (i_row+length_upper-1) ; k++)
1184 if (jw(n2+k) < lfil)
1187 size_row += size_upper;
1188 A.ReallocateRow(i_row,size_row);
1189 levs(i_row).Reallocate(size_upper);
1192 for (k = 0; k < length_lower; k++)
1194 if (jw(n2+k) < lfil)
1196 A.Value(i_row,index_lu) = w(k);
1197 A.Index(i_row,index_lu) = jw(k);
1203 Index_Diag(i_row) = index_lu;
1204 A.Value(i_row,index_lu) = cone / w(i_row);
1205 A.Index(i_row,index_lu++) = i_row;
1207 for (k = (i_row+1) ; k <= (i_row+length_upper-1) ; k++)
1209 if (jw(n2+k) < lfil)
1211 A.Index(i_row,index_lu) = jw(k);
1212 A.Value(i_row,index_lu) = w(k);
1213 levs(i_row)(index_lu-Index_Diag(i_row)-1) = jw(n2+k);
1221 template<
class cplx,
class Allocator>
1222 void GetIlu0(Matrix<cplx, General, ArrayRowSparse, Allocator>& A)
1224 int j_col, jrow, jw, n = A.GetM();
1225 IVect Index(n), ju(n);
1228 SetComplexZero(czero);
1229 SetComplexOne(cone);
1232 Index.Fill(-1); ju.Fill(-1);
1236 for (
int i_row = 0 ; i_row < n ; i_row++)
1239 for (
int j = 0 ; j < A.GetRowSize(i_row) ; j++ )
1241 j_col = A.Index(i_row, j);
1248 int jm = ju(i_row)-1;
1251 for (
int j = 0; j <= jm; j++)
1253 jrow = A.Index(i_row, j);
1254 tl = A.Value(i_row, j)*A.Value(jrow, ju(jrow));
1255 A.Value(i_row, j) = tl;
1258 for ( j_col = (ju(jrow)+1); j_col < A.GetRowSize(jrow); j_col++)
1260 jw = Index(A.Index(jrow,j_col));
1262 A.Value(i_row, jw) -= tl*A.Value(jrow, j_col);
1268 if (A.Value(i_row, ju(i_row)) == czero)
1270 cout <<
"Factorization fails because we found a null coefficient"
1271 <<
" on diagonal " << i_row << endl;
1275 A.Value(i_row,ju(i_row)) = cone / A.Value(i_row,ju(i_row));
1279 for (
int i = 0; i < A.GetRowSize(i_row); i++)
1280 Index(A.Index(i_row, i)) = -1;
1286 template<
class cplx,
class Allocator>
1287 void GetMilu0(Matrix<cplx, General, ArrayRowSparse, Allocator>& A)
1289 int j_col, jrow, jw, n = A.GetM();
1290 IVect Index(n), ju(n);
1293 SetComplexZero(czero);
1294 SetComplexOne(cone);
1297 Index.Fill(-1); ju.Fill(-1);
1301 for (
int i_row = 0 ; i_row < n ; i_row++)
1304 for (
int j = 0; j < A.GetRowSize(i_row); j++ )
1306 j_col = A.Index(i_row, j);
1313 int jm = ju(i_row)-1;
1316 cplx s; SetComplexZero(s);
1317 for (
int j = 0; j <= jm; j++)
1319 jrow = A.Index(i_row, j);
1320 tl = A.Value(i_row, j)*A.Value(jrow, ju(jrow));
1321 A.Value(i_row, j) = tl;
1324 for ( j_col = (ju(jrow)+1); j_col < A.GetRowSize(jrow); j_col++ )
1326 jw = Index(A.Index(jrow, j_col));
1328 A.Value(i_row, jw) -= tl*A.Value(jrow, j_col);
1330 s += tl*A.Value(jrow, j_col);
1335 A.Value(i_row, ju(i_row)) -= s;
1336 if (A.Value(i_row, ju(i_row)) == czero)
1338 cout <<
"Factorization fails because we found a null coefficient"
1339 <<
" on diagonal " << i_row << endl;
1343 A.Value(i_row, ju(i_row)) = cone /A.Value(i_row, ju(i_row));
1347 for (
int i = 0; i < A.GetRowSize(i_row); i++)
1348 Index(A.Index(i_row, i)) = -1;
1353 template<
class MatrixSparse,
class T,
class Alloc2>
1354 void GetLU(MatrixSparse& A, IlutPreconditioning<T, Alloc2>& mat_lu,
1355 IVect& permut,
bool keep_matrix, T& x)
1357 mat_lu.FactorizeMatrix(permut, A, keep_matrix);
1361 template<
class MatrixSparse,
class T,
class Alloc2>
1362 void GetLU(MatrixSparse& A, IlutPreconditioning<T, Alloc2>& mat_lu,
1363 IVect& permut,
bool keep_matrix, complex<T>& x)
1365 throw WrongArgument(
string(
"GetLU(Matrix<complex<T> >& A, ") +
1366 "IlutPreconditioning<T>& mat_lu, bool)",
1367 "The LU matrix must be complex");
1371 template<
class MatrixSparse,
class T,
class Alloc2>
1372 void GetLU(MatrixSparse& A, IlutPreconditioning<complex<T>, Alloc2>& mat_lu,
1373 IVect& permut,
bool keep_matrix, T& x)
1375 throw WrongArgument(
string(
"GetLU(Matrix<T>& A, ")+
1376 "IlutPreconditioning<complex<T> >& mat_lu, bool)",
1377 "The sparse matrix must be complex");
1381 template<
class T0,
class Prop,
class Storage,
class Allocator,
1382 class T,
class Alloc2>
1383 void GetLU(Matrix<T0, Prop, Storage, Allocator>& A,
1384 IlutPreconditioning<T, Alloc2>& mat_lu,
1385 IVect& permut,
bool keep_matrix)
1387 typename Matrix<T0, Prop, Storage, Allocator>::entry_type x;
1388 GetLU(A, mat_lu, permut, keep_matrix, x);
1393 #define SELDON_FILE_ILUT_PRECONDITIONING_CXX