Go to the documentation of this file.00001
00002
00003 #ifndef diagonal_hh
00004 #define diagonal_hh
00005
00006 #include "matrix.hh"
00007
00008 namespace concepts {
00009
00010
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
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
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
00155
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
00163
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
00174 const uint n = this->dimX();
00175
00176
00177 conceptsAssert(mX.dimX() == n, Assertion());
00178 conceptsAssert(mY.dimX() == n, Assertion());
00179
00180
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 }
00194
00195 #endif // diagonal_hh