19 #ifndef SELDON_FILE_SPARSE_CHOLESKY_FACTORISATION_CXX
22 #include "SparseCholeskyFactorisation.hxx"
33 template<
class T,
class Prop,
class Allocator>
39 int j_col, jrow, index_lu, jpos;
41 IVect Index(n), Row_Ind(n);
59 int new_percent = 0, old_percent = 0;
60 for (
int i_row = 0; i_row < n; i_row++)
65 new_percent = int(
double(i_row) /
double(n-1) * 78.);
66 for (
int percent = old_percent; percent < new_percent; percent++)
72 old_percent = new_percent;
75 int size_row = B.GetRowSize(i_row);
78 int length_lower = 0, length_upper = 1;
79 Row_Ind(i_row) = i_row;
80 Row_Val(i_row) = zero;
83 for (
int j = 0; j < size_row; j++)
85 int k = B.Index(i_row, j);
86 t = B.Value(i_row, j);
89 Row_Ind(length_lower) = k;
90 Row_Val(length_lower) = t;
91 Index(k) = length_lower;
98 jpos = i_row + length_upper;
112 while (j_col < length_lower)
114 jrow = Row_Ind(j_col);
118 for (
int j = (j_col+1) ; j < length_lower; j++)
120 if (Row_Ind(j) < jrow)
131 int j = Row_Ind(j_col);
132 Row_Ind(j_col) = Row_Ind(k);
139 Row_Val(j_col) = Row_Val(k);
145 fact = Row_Val(j_col) * A.
Value(jrow, 0);
150 s = fact * A.
Value(jrow, k);
151 int j = A.
Index(jrow, k);
160 int i = i_row + length_upper;
178 Row_Ind(length_lower) = j;
179 Index(j) = length_lower;
180 Row_Val(length_lower) = -s;
194 Row_Val(length) = fact;
195 Row_Ind(length) = jrow;
200 for (
int k = 0; k < length_upper; k++)
201 Index(Row_Ind(i_row+k )) = -1;
204 size_row = length_upper;
208 if (Row_Val(i_row) <= 0)
210 cout <<
"Error during Cholesky factorization " << endl;
211 cout <<
"Matrix must be definite positive " << endl;
212 cout <<
"but diagonal element of row " << i_row
213 <<
"is equal to " << Row_Val(i_row) << endl;
218 A.
Value(i_row, 0) = one / Row_Val(i_row);
219 A.
Index(i_row, 0) = i_row;
223 for (
int k = (i_row+1); k < (i_row+length_upper); k++)
225 A.
Index(i_row, index_lu) = Row_Ind(k);
226 A.
Value(i_row, index_lu) = Row_Val(k);
234 cout <<
"The matrix takes " <<
235 int((A.
GetDataSize() * (
sizeof(T)+4)) / (1024*1024)) <<
" MB" << endl;
239 for (
int i = 0; i < n; i++)
257 template<
class T0,
class Prop,
class Allocator0,
258 class T1,
class Storage,
class Allocator1>
271 for (
int i = n-1; i >= 0; i--)
274 for (
int k = 1; k < A.GetRowSize(i) ; k++)
277 val -= A.Value(i, k)*x(j);
280 x(i) = val / A.Value(i, 0);
287 for (
int i = 0; i < n; i++)
289 x(i) /= A.Value(i, 0);
290 for (
int k = 1; k < A.GetRowSize(i) ; k++)
293 x(j) -= A.Value(i, k)*x(i);
306 template<
class T0,
class Prop,
class Alloc0,
307 class T1,
class Storage,
class Allocator1>
316 int* ind = A.GetInd();
317 long* ptr = A.GetPtr();
318 T0* data = A.GetData();
324 for (
int i = n - 1; i >= 0; i--)
327 for (
long j = ptr[i] + 1; j < ptr[i+1]; j++)
328 val -= data[j] * X(ind[j]);
330 X(i) = val / data[ptr[i]];
336 for (
int i = 0; i < n; i++)
338 X(i) /= data[ptr[i]];
339 for (
long j = ptr[i] + 1; j < ptr[i+1]; j++)
340 X(ind[j]) -= data[j] * X(i);
352 template<
class T0,
class Prop,
class Allocator0,
353 class T1,
class Storage,
class Allocator1>
366 for (
int i = 0; i < n; i++)
368 T1 val = x(i) * A.Value(i, 0);
369 for (
int k = 1; k < A.GetRowSize(i) ; k++)
372 val += A.Value(i, k)*x(j);
382 for (
int i = n-1; i >= 0; i--)
384 for (
int k = 1; k < A.GetRowSize(i) ; k++)
387 x(j) += A.Value(i, k)*x(i);
390 x(i) *= A.Value(i, 0);
402 template<
class T0,
class Prop,
class Allocator0,
403 class T1,
class Storage,
class Allocator1>
412 int* ind = A.GetInd();
413 long* ptr = A.GetPtr();
414 T0* data = A.GetData();
420 for (
int i = 0; i < n; i++)
422 val = x(i) * data[ptr[i]];
423 for (
long k = ptr[i] + 1; k < ptr[i+1]; k++)
424 val += data[k] * x(ind[k]);
432 for (
int i = n-1; i >= 0; i--)
434 for (
long k = ptr[i] + 1; k < ptr[i+1]; k++)
435 x(ind[k]) += data[k] * x(i);
437 x(i) *= data[ptr[i]];
449 type_ordering = SparseMatrixOrdering::IDENTITY;
451 type_solver = SELDON_SOLVER;
452 #ifdef SELDON_WITH_CHOLMOD
453 type_solver = CHOLMOD;
455 #ifdef SELDON_WITH_PASTIX
456 type_solver = PASTIX;
470 solver->HideMessages();
480 solver->ShowMessages();
490 solver->ShowMessages();
529 size_t taille = mat_sym.GetMemorySize();
530 taille += xtmp.GetMemorySize();
532 taille += solver->GetMemorySize();
542 return type_ordering;
550 type_ordering = SparseMatrixOrdering::USER;
559 type_ordering = type;
586 if (type_solver == CHOLMOD)
588 #ifdef SELDON_WITH_CHOLMOD
591 cout <<
"Seldon compiled without Cholmod support" << endl;
592 cout <<
"SELDON_WITH_CHOLMOD is not defined" << endl;
595 else if (type_solver == PASTIX)
597 #ifdef SELDON_WITH_PASTIX
598 solver =
new MatrixPastix<T>();
600 cout <<
"Seldon compiled without Pastix support" << endl;
601 cout <<
"SELDON_WITH_PASTIX is not defined" << endl;
614 template<
class Prop,
class Storage,
class Allocator>
619 if (type_solver == CHOLMOD)
621 #ifdef SELDON_WITH_CHOLMOD
622 if (print_level >= 1)
623 cout <<
"Calling Cholmod to factorize the matrix" << endl;
628 mat_chol.FactorizeMatrix(A, keep_matrix);
630 throw Error(
"SparseCholeskySolver::Factorize",
631 "Recompile with Cholmod or change solver type.");
634 else if (type_solver == PASTIX)
636 #ifdef SELDON_WITH_PASTIX
637 if (print_level >= 1)
638 cout <<
"Calling Pastix to factorize the matrix" << endl;
643 GetCholesky(A, mat_pastix, keep_matrix);
645 throw Error(
"SparseCholeskySolver::Factorize",
646 "Recompile with Pastix or change solver type.");
656 ApplyInversePermutation(mat_sym, permutation, permutation);
658 GetCholesky(mat_sym, print_level);
665 template<
class T>
template<
class T1>
669 if (type_solver == CHOLMOD)
671 #ifdef SELDON_WITH_CHOLMOD
675 mat_chol.
Solve(TransA, x_solution);
677 throw Error(
"SparseCholeskySolver::Solve",
678 "Recompile with Cholmod or change solver type.");
681 else if (type_solver == PASTIX)
683 #ifdef SELDON_WITH_PASTIX
687 SolveCholesky(TransA, mat_pastix, x_solution);
689 throw Error(
"SparseCholeskySolver::Solve",
690 "Recompile with Pastix or change solver type.");
695 if (TransA.NoTrans())
697 for (
int i = 0; i < x_solution.GetM(); i++)
698 xtmp(permutation(i)) = x_solution(i);
700 SolveCholesky(TransA, mat_sym, xtmp);
701 Copy(xtmp, x_solution);
705 Copy(x_solution, xtmp);
706 SolveCholesky(TransA, mat_sym, xtmp);
708 for (
int i = 0; i < x_solution.GetM(); i++)
709 x_solution(i) = xtmp(permutation(i));
716 template<
class T>
template<
class T1>
720 if (type_solver == CHOLMOD)
722 #ifdef SELDON_WITH_CHOLMOD
726 mat_chol.
Mlt(TransA, x_solution);
728 throw Error(
"SparseCholeskySolver::Mlt",
729 "Recompile with Cholmod or change solver type.");
732 else if (type_solver == PASTIX)
734 #ifdef SELDON_WITH_PASTIX
738 MltCholesky(TransA, mat_pastix, x_solution);
740 throw Error(
"SparseCholeskySolver::Mlt",
741 "Recompile with Pastix or change solver type.");
746 if (TransA.NoTrans())
748 Copy(x_solution, xtmp);
749 MltCholesky(TransA, mat_sym, xtmp);
751 for (
int i = 0; i < x_solution.GetM(); i++)
752 x_solution(i) = xtmp(permutation(i));
756 for (
int i = 0; i < x_solution.GetM(); i++)
757 xtmp(permutation(i)) = x_solution(i);
759 MltCholesky(TransA, mat_sym, xtmp);
760 Copy(xtmp, x_solution);
768 #define SELDON_FILE_SPARSE_CHOLESKY_FACTORISATION_CXX