/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* ******** *** SparseLib++ */ /* ******* ** *** *** *** v. 1.5c */ /* ***** *** ******** ******** */ /* ***** *** ******** ******** R. Pozo */ /* ** ******* *** ** *** *** K. Remington */ /* ******** ******** A. Lumsdaine */ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* */ /* */ /* SparseLib++ : Sparse Matrix Library */ /* */ /* National Institute of Standards and Technology */ /* University of Notre Dame */ /* Authors: R. Pozo, K. Remington, A. Lumsdaine */ /* */ /* NOTICE */ /* */ /* Permission to use, copy, modify, and distribute this software and */ /* its documentation for any purpose and without fee is hereby granted */ /* provided that the above notice appear in all copies and supporting */ /* documentation. */ /* */ /* Neither the Institutions (National Institute of Standards and Technology, */ /* University of Notre Dame) nor the Authors make any representations about */ /* the suitability of this software for any purpose. This software is */ /* provided ``as is'' without expressed or implied warranty. */ /* */ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #include #include "diagpre_double_GR.h" // modif GR : découle d'une classe virtuelle // pour avoir une interface standard #include "Mat_pleine.h" #include "MatBand.h" #include "Mat_creuse_CompCol.h" #include "ConstMath.h" #include "MathUtil.h" DiagPreconditioner_double::DiagPreconditioner_double(const CompRow_Mat_double &C) : diag_(C.dim(0)) { int i; if ((i = CopyInvDiagonals(C.dim(0), &C.row_ptr(0), &C.col_ind(0), &C.val(0), &diag(0))) != 0) { cerr << "Diagonal preconditioner failure."; cerr << " Zero detected in element " << i << endl; Sortie(1); } } DiagPreconditioner_double::DiagPreconditioner_double(const CompCol_Mat_double &C) : diag_ (C.dim (0)) { int i; if ((i = CopyInvDiagonals(C.dim(0), &C.col_ptr(0), &C.row_ind(0), &C.val(0), &diag(0))) != 0) { cerr << "Diagonal preconditioner failure."; cerr << " Zero detected in element " << i << endl; Sortie(1); } } // cas d'une matrice abstraite DiagPreconditioner_double::DiagPreconditioner_double(const Mat_abstraite &A) : diag_ (A.Nb_ligne()) { int i; switch (A.Type_matrice()) { case CREUSE_COMPRESSEE_LIGNE : {const CompRow_Mat_double &C = (CompRow_Mat_double &) A; // ici il y aura une modif a faire comme pour les matrices compressées colonne // il faut passer la matrice dérivée et non la matrice mère cout << "\n problème dans DiagPreconditioner_double(.. " << "voir le source .cpp, il y a du travail a faire"; Sortie(1); if ((i = CopyInvDiagonals(C.dim(0), &C.row_ptr(0), &C.col_ind(0), &C.val(0), &diag(0))) != 0) { cerr << "Diagonal preconditioner failure."; cerr << " Zero detected in element " << i << endl; Sortie(1); } break; } case CREUSE_COMPRESSEE_COLONNE : {const Mat_creuse_CompCol &C = (Mat_creuse_CompCol &) A; if ((i = CopyInvDiagonals(C.dim(0), &C.col_ptr(0), &C.row_ind(0), &C.val(0), &diag(0))) != 0) { cerr << "Diagonal preconditioner failure."; cerr << " Zero detected in element " << i << endl; Sortie(1); } break; } default : {if ((i = CopyInvDiagonals(A)) != 0) { cerr << "Diagonal preconditioner failure."; cerr << " Zero detected in element " << i << endl; Sortie(1); } } }; }; int DiagPreconditioner_double::CopyInvDiagonals (int n, const int *pntr, const int *indx ,const double *sa, double *diag) { int i, j; for (i = 0; i < n; i++) diag[i] = 0; /* Find the diagonal elements */ for (i = 0; i < n; i++) { for (j = pntr[i]; j < pntr[i+1]; j++) { if (indx[j] == i) { if (sa[j] == 0) return i; diag[i] = 1. / sa[j]; break; } } if (diag[i] == 0) return -i; } return 0; } // surcharge de la fonction pour les matrices carrées et/ou bande int DiagPreconditioner_double::CopyInvDiagonals(const Mat_abstraite& A) { switch (A.Type_matrice()) { case CARREE : break; case CARREE_LAPACK : break; case BANDE_SYMETRIQUE : case CARREE_SYMETRIQUE : break; case RECTANGLE : break; case BANDE_NON_SYMETRIQUE: break; case CARREE_SYMETRIQUE_LAPACK : break; case RECTANGLE_LAPACK : break; case BANDE_SYMETRIQUE_LAPACK : break; case BANDE_NON_SYMETRIQUE_LAPACK : break; case CREUSE_NON_COMPRESSEE : break; case CREUSE_COMPRESSEE_COLONNE : break; case CREUSE_COMPRESSEE_LIGNE : break; case DIAGONALE : break; default : cout << "\nErreur : valeur incorrecte du type de matrice !" << " = " << A.Type_matrice() << " , ce tye n'est pas encore " << " pris en compte dans le préconditionnement diagonal\n"; cout << "\n CopyInvDiagonals(Mat_abstraite& A, double *diag)\n"; Sortie(1); }; int n = A.Nb_ligne(); for (int i = 1; i <= n; i++) if (Abs(A(i,i)) < ConstMath::trespetit) return -1; else diag(i-1) = 1./A(i,i); return 0; }; VECTOR_double DiagPreconditioner_double::solve (const VECTOR_double &x) const { VECTOR_double y(x.size()); for (int i = 0; i < x.size(); i++) y(i) = x(i) * diag(i); return y; } VECTOR_double DiagPreconditioner_double::trans_solve (const VECTOR_double &x) const { VECTOR_double y(x.size()); for (int i = 0; i < x.size(); i++) y(i) = x(i) * diag(i); return y; }