/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* ******** *** 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 "fatalerror.h" #include "stdlib.h" #include "diagpre_double.h" int 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; } 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; fatalerror(); } } 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; fatalerror(); } } 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; }