Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)

operator/diagonal.hh
Go to the documentation of this file.
00001 // diagonal matrix and solver for it
00002 
00003 #ifndef diagonal_hh
00004 #define diagonal_hh
00005 
00006 #include "matrix.hh"
00007 
00008 namespace concepts {
00009 
00010   // ******************************************************** DiagonalMatrix **
00011 
00017   template<typename F>
00018   class DiagonalMatrix : public Matrix<F> {
00019   public:
00021     typedef typename Realtype<F>::type r_type;
00023     typedef typename Cmplxtype<F>::type c_type;
00024 
00026     template<class G>
00027     DiagonalMatrix(const Space<G>& spc);
00028     DiagonalMatrix(uint dim);
00032     template<class G>
00033     DiagonalMatrix(const Space<G>& spc, const Array<F> entries);
00037     DiagonalMatrix(const Matrix<F>& matrix);
00038     virtual ~DiagonalMatrix();
00039 
00040     virtual void operator()(const Function<r_type>& fncY,
00041                             Function<F>& fncX);
00042     virtual void operator()(const Function<c_type>& fncY,
00043                             Function<c_type>& fncX);
00044 
00045     virtual F operator()(const uint i, const uint j) const;
00046     virtual F& operator()(const uint i, const uint j);
00047 
00048     virtual void transpMult(const Vector<r_type>& fncY, Vector<F>& fncX);
00049     virtual void transpMult(const Vector<c_type>& fncY,
00050                             Vector<c_type>& fncX);
00051 
00053     DiagonalMatrix<F>& operator=(F c);
00054 
00056     DiagonalMatrix<F>& operator+=(const Matrix<F>& d);
00057 
00062     template<class H, class I>
00063     void addInto(Matrix<H>& dest, const I fact);
00064   protected:
00065     virtual std::ostream& info(std::ostream& os) const;
00066   private:
00068     Array<F> entries_;
00070     F dummy_;
00071 
00072     template<typename H, typename I>
00073     void apply_(const Function<H>& fncY, Function<I>& fncX);
00074 
00075     template<typename H, typename I>
00076     void applyT_(const Vector<H>& fncY, Vector<I>& fncX);
00077   };
00078 
00079   template<typename F>
00080   template<typename H, typename I>
00081   void DiagonalMatrix<F>::apply_(const Function<H>& fncY, Function<I>& fncX) {
00082     conceptsAssert(fncY.dim() == this->dimY(), Assertion());
00083     conceptsAssert(fncX.dim() == this->dimX(), Assertion());
00084     const Vector<H>* vecY = dynamic_cast<const Vector<H>*>(&fncY);
00085     Vector<I>* vecX = dynamic_cast<Vector<I>*>(&fncX);
00086     if ((vecY != 0) && (vecY != 0)) {
00087       applyT_(*vecY, *vecX);
00088       return;
00089     }
00090 
00091     // dynamic_casts did not work
00092     for (uint i = 0; i < this->dimX(); ++i)
00093       fncX(i) = fncY(i) * entries_[i];
00094   }
00095 
00096   template<typename F>
00097   template<typename H, typename I>
00098   void DiagonalMatrix<F>::applyT_(const Vector<H>& fncY, Vector<I>& fncX)
00099   {
00100     const H* vecYdata(fncY);
00101     I* vecXdata(fncX);
00102     const F* entryData(entries_);
00103     for (uint i = 0; i < this->dimX(); ++i)
00104       *vecXdata++ = *vecYdata++ * *entryData++;
00105   }
00106 
00107   template<typename F>
00108   template<class H, class I>
00109   void DiagonalMatrix<F>::addInto(Matrix<H>& dest, const I fact) {
00110     conceptsAssert(dest.dimX()  == dest.dimY(), Assertion());
00111     conceptsAssert(this->dimX() == dest.dimX(), Assertion());
00112     for (uint j = 0; j < this->dimX(); ++j)
00113       dest(j, j) += entries_[j] * fact;
00114   }
00115 
00116   // ******************************************************** DiagonalSolver **
00117 
00123   template <typename F>
00124   class DiagonalSolver : public Operator<F> {
00125   public:
00127     typedef typename Realtype<F>::type r_type;
00129     typedef typename Cmplxtype<F>::type c_type;
00130 
00134     DiagonalSolver(const DiagonalMatrix<F>& m);
00135     virtual ~DiagonalSolver();
00136 
00137     virtual void operator()(const Function<r_type>& rhs, Function<F>& sol);
00138     virtual void operator()(const Function<c_type>& rhs,
00139                             Function<c_type>& sol);
00141     void operator()(const Matrix<r_type>& mX, Matrix<F>& mY);
00143     void operator()(const Matrix<c_type>& mX, Matrix<c_type>& mY);
00144 
00145   protected:
00146     virtual std::ostream& info(std::ostream& os) const;
00147   private:
00148     DiagonalMatrix<F> inverse_;
00149 
00150     template <typename H, typename I>
00151     void apply_(const Matrix<H>& mX, Matrix<I>& mY);
00152   };
00153 
00154   // This construction allow the solving of real right hand side for
00155   // both, real and complex diagonal matrices.
00156   template <typename F>
00157   void DiagonalSolver<F>::operator()(const Function<r_type>& rhs,
00158                                      Function<F>& sol) {
00159     inverse_(rhs, sol);
00160   }
00161 
00162   // This construction allow the solving of complex right hand side for
00163   // both, real and complex diagonal matrices.
00164   template <typename F>
00165   void DiagonalSolver<F>::operator()(const Function<c_type>& rhs,
00166                                      Function<c_type>& sol) {
00167     inverse_(rhs, sol);
00168   }
00169 
00170   template <typename F>
00171   template <typename H, typename I>
00172   void DiagonalSolver<F>::apply_(const Matrix<H>& mX, Matrix<I>& mY) {
00173     // number of rows
00174     const uint n = this->dimX();
00175 
00176     // number of rows should be the same as for the solver
00177     conceptsAssert(mX.dimX() == n, Assertion());
00178     conceptsAssert(mY.dimX() == n, Assertion());
00179     // the resulting matrix should have the same number of columns
00180     // then the applicated matrix
00181     conceptsAssert(mX.dimY() == mY.dimY(), Assertion());
00182 
00183     for(uint i = 0; i < n; i++) {
00184       F& d = inverse_(i,i);
00185       for(uint j = 0; j < n; j++) {
00186         const H val = mX(i,j);
00187         if (val != (H)0.0)
00188           mY(i,j) += d * val;
00189       }
00190     }
00191   }
00192 
00193 } // namespace concepts
00194 
00195 #endif // diagonal_hh

Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)