00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef _DIAGONAL_PRECONDITIONER_H_
00032 #define _DIAGONAL_PRECONDITIONER_H_
00033
00034 #include "Preconditioner.h"
00035 #include "SparseRowMatrix.h"
00036 #include "RealVector.h"
00037 #include <string>
00038
00039 namespace FDDlib {
00040
00046 class DiagonalPreconditioner : public Preconditioner
00047 {
00048 private:
00050 double* invDiag_;
00051
00052 public:
00053
00057 DiagonalPreconditioner(SparseRowMatrix<double>& SRMD)
00058 {
00059 int i;
00060
00061 len_ = SRMD.getNumRows();
00062 invDiag_ = new double[len_];
00063 for (i = 0; i < len_; i++)
00064 {
00065 invDiag_[i] = 1 / SRMD.val(i,i);
00066 }
00067 }
00068
00070 DiagonalPreconditioner()
00071 {
00072 len_ = 0;
00073 invDiag_ = (double*) NULL;
00074 }
00075
00079 void init(SparseRowMatrix<double>& SRMD) throw(std::string)
00080 {
00081 int i;
00082
00083 len_ = SRMD.getNumRows();
00084 if (invDiag_ != (double*) NULL)
00085 delete invDiag_;
00086 invDiag_ = new double[len_];
00087 for (i = 0; i < len_; i++)
00088 {
00089 if (SRMD.val(i,i) == 0)
00090 throw std::string("DiagonalPreconditioner::init: zero on matrix diagonal.");
00091 invDiag_[i] = 1 / SRMD.val(i,i);
00092 }
00093 }
00094
00096 ~DiagonalPreconditioner()
00097 {
00098 if (invDiag_ != (double*) NULL)
00099 delete[] invDiag_;
00100 }
00101
00106 RealVector<double> solve(const RealVector<double>& x) const
00107 {
00108
00109 RealVector<double> r(len_);
00110 int i;
00111
00112 for (i = 0; i < len_; i++)
00113 {
00114 r(i) = invDiag_[i]*x(i);
00115 }
00116
00117 return r;
00118 }
00119
00120
00121
00122 };
00123
00124
00125 }
00126 #endif