00001 #ifndef DUNE_SCALED_IDENTITY_MATRIX_HH
00002 #define DUNE_SCALED_IDENTITY_MATRIX_HH
00003
00010 #include<cmath>
00011 #include<cstddef>
00012 #include<complex>
00013 #include<iostream>
00014 #include <dune/common/exceptions.hh>
00015 #include <dune/common/fmatrix.hh>
00016 #include <dune/istl/diagonalmatrix.hh>
00017
00018 namespace Dune {
00019
00023 template<class K, int n>
00024 class ScaledIdentityMatrix
00025 {
00026
00027 public:
00028
00029
00031 typedef K field_type;
00032
00034 typedef K block_type;
00035
00037 typedef std::size_t size_type;
00038
00040 enum {
00042 blocklevel = 1
00043 };
00044
00046 typedef DiagonalRowVector<K,n> row_type;
00047 typedef row_type reference;
00048 typedef DiagonalRowVectorConst<K,n> const_row_type;
00049 typedef const_row_type const_reference;
00050
00052 enum {
00054 rows = n,
00056 cols = n
00057 };
00058
00059
00062 ScaledIdentityMatrix () {}
00063
00066 ScaledIdentityMatrix (const K& k)
00067 : p_(k)
00068 {}
00069
00070
00071 ScaledIdentityMatrix& operator= (const K& k)
00072 {
00073 p_ = k;
00074 return *this;
00075 }
00076
00077
00078 bool identical(const ScaledIdentityMatrix<K,n>& other) const
00079 {
00080 return (this==&other);
00081 }
00082
00083
00085 typedef ReferenceStorageIterator<ScaledIdentityMatrix<K,n>,reference,reference,ScaledIdentityMatrix<K,n>&> Iterator;
00087 typedef Iterator iterator;
00089 typedef Iterator RowIterator;
00091 typedef typename row_type::Iterator ColIterator;
00092
00094 Iterator begin ()
00095 {
00096 return Iterator(*this,0);
00097 }
00098
00100 Iterator end ()
00101 {
00102 return Iterator(*this,n);
00103 }
00104
00106 Iterator rbegin ()
00107 {
00108 return Iterator(*this,n-1);
00109 }
00110
00112 Iterator rend ()
00113 {
00114 return Iterator(*this,-1);
00115 }
00116
00117
00119 typedef ReferenceStorageIterator<const ScaledIdentityMatrix<K,n>,const_reference,const_reference,const ScaledIdentityMatrix<K,n>&> ConstIterator;
00121 typedef ConstIterator const_iterator;
00123 typedef ConstIterator ConstRowIterator;
00125 typedef typename const_row_type::ConstIterator ConstColIterator;
00126
00128 ConstIterator begin () const
00129 {
00130 return ConstIterator(*this,0);
00131 }
00132
00134 ConstIterator end () const
00135 {
00136 return ConstIterator(*this,n);
00137 }
00138
00140 ConstIterator rbegin () const
00141 {
00142 return ConstIterator(*this,n-1);
00143 }
00144
00146 ConstIterator rend () const
00147 {
00148 return ConstIterator(*this,-1);
00149 }
00150
00151
00152
00154 ScaledIdentityMatrix& operator+= (const ScaledIdentityMatrix& y)
00155 {
00156 p_ += y.p_;
00157 return *this;
00158 }
00159
00161 ScaledIdentityMatrix& operator-= (const ScaledIdentityMatrix& y)
00162 {
00163 p_ -= y.p_;
00164 return *this;
00165 }
00166
00168 ScaledIdentityMatrix& operator+= (const K& k)
00169 {
00170 p_ += k;
00171 return *this;
00172 }
00173
00175 ScaledIdentityMatrix& operator-= (const K& k)
00176 {
00177 p_ -= k;
00178 return *this;
00179 }
00181 ScaledIdentityMatrix& operator*= (const K& k)
00182 {
00183 p_ *= k;
00184 return *this;
00185 }
00186
00188 ScaledIdentityMatrix& operator/= (const K& k)
00189 {
00190 p_ /= k;
00191 return *this;
00192 }
00193
00194
00195
00197 template<class X, class Y>
00198 void mv (const X& x, Y& y) const
00199 {
00200 #ifdef DUNE_FMatrix_WITH_CHECKING
00201 if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00202 if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00203 #endif
00204 for (size_type i=0; i<n; ++i)
00205 y[i] = p_ * x[i];
00206 }
00207
00209 template<class X, class Y>
00210 void umv (const X& x, Y& y) const
00211 {
00212 #ifdef DUNE_FMatrix_WITH_CHECKING
00213 if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00214 if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00215 #endif
00216 for (size_type i=0; i<n; ++i)
00217 y[i] += p_ * x[i];
00218 }
00219
00221 template<class X, class Y>
00222 void umtv (const X& x, Y& y) const
00223 {
00224 #ifdef DUNE_FMatrix_WITH_CHECKING
00225 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00226 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00227 #endif
00228 for (size_type i=0; i<n; ++i)
00229 y[i] += p_ * x[i];
00230 }
00231
00233 template<class X, class Y>
00234 void umhv (const X& x, Y& y) const
00235 {
00236 #ifdef DUNE_FMatrix_WITH_CHECKING
00237 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00238 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00239 #endif
00240 for (size_type i=0; i<n; i++)
00241 y[i] += fm_ck(p_)*x[i];
00242 }
00243
00245 template<class X, class Y>
00246 void mmv (const X& x, Y& y) const
00247 {
00248 #ifdef DUNE_FMatrix_WITH_CHECKING
00249 if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00250 if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00251 #endif
00252 for (size_type i=0; i<n; ++i)
00253 y[i] -= p_ * x[i];
00254 }
00255
00257 template<class X, class Y>
00258 void mmtv (const X& x, Y& y) const
00259 {
00260 #ifdef DUNE_FMatrix_WITH_CHECKING
00261 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00262 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00263 #endif
00264 for (size_type i=0; i<n; ++i)
00265 y[i] -= p_ * x[i];
00266 }
00267
00269 template<class X, class Y>
00270 void mmhv (const X& x, Y& y) const
00271 {
00272 #ifdef DUNE_FMatrix_WITH_CHECKING
00273 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00274 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00275 #endif
00276
00277 for (size_type i=0; i<n; i++)
00278 y[i] -= fm_ck(p_)*x[i];
00279 }
00280
00282 template<class X, class Y>
00283 void usmv (const K& alpha, const X& x, Y& y) const
00284 {
00285 #ifdef DUNE_FMatrix_WITH_CHECKING
00286 if (x.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00287 if (y.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00288 #endif
00289 for (size_type i=0; i<n; i++)
00290 y[i] += alpha * p_ * x[i];
00291 }
00292
00294 template<class X, class Y>
00295 void usmtv (const K& alpha, const X& x, Y& y) const
00296 {
00297 #ifdef DUNE_FMatrix_WITH_CHECKING
00298 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00299 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00300 #endif
00301 for (size_type i=0; i<n; i++)
00302 y[i] += alpha * p_ * x[i];
00303 }
00304
00306 template<class X, class Y>
00307 void usmhv (const K& alpha, const X& x, Y& y) const
00308 {
00309 #ifdef DUNE_FMatrix_WITH_CHECKING
00310 if (x.N()!=N()) DUNE_THROW(FMatrixError,"index out of range");
00311 if (y.N()!=M()) DUNE_THROW(FMatrixError,"index out of range");
00312 #endif
00313 for (size_type i=0; i<n; i++)
00314 y[i] += alpha * fm_ck(p_) * x[i];
00315 }
00316
00317
00318
00320 double frobenius_norm () const
00321 {
00322 return std::sqrt(n*p_*p_);
00323 }
00324
00326 double frobenius_norm2 () const
00327 {
00328 return n*p_*p_;
00329 }
00330
00332 double infinity_norm () const
00333 {
00334 return std::fabs(p_);
00335 }
00336
00338 double infinity_norm_real () const
00339 {
00340 return fvmeta_absreal(p_);
00341 }
00342
00343
00344
00347 template<class V>
00348 void solve (V& x, const V& b) const {
00349 for (int i=0; i<n; i++)
00350 x[i] = b[i]/p_;
00351 }
00352
00355 void invert() {
00356 p_ = 1/p_;
00357 }
00358
00360 K determinant () const {
00361 return std::pow(p_,n);
00362 }
00363
00364
00365
00367 size_type N () const
00368 {
00369 return n;
00370 }
00371
00373 size_type M () const
00374 {
00375 return n;
00376 }
00377
00378
00379
00381 bool exists (size_type i, size_type j) const
00382 {
00383 #ifdef DUNE_FMatrix_WITH_CHECKING
00384 if (i<0 || i>=n) DUNE_THROW(FMatrixError,"row index out of range");
00385 if (j<0 || j>=m) DUNE_THROW(FMatrixError,"column index out of range");
00386 #endif
00387 return i==j;
00388 }
00389
00390
00391
00393
00394
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00409 friend std::ostream& operator<< (std::ostream& s, const ScaledIdentityMatrix<K,n>& a)
00410 {
00411 for (size_type i=0; i<n; i++) {
00412 for (size_type j=0; j<n; j++)
00413 s << ((i==j) ? a.p_ : 0) << " ";
00414 s << std::endl;
00415 }
00416 return s;
00417 }
00418
00420 reference operator[](size_type i)
00421 {
00422 return reference(const_cast<K*>(&p_), i);
00423 }
00424
00426 const_reference operator[](size_type i) const
00427 {
00428 return const_reference(const_cast<K*>(&p_), i);
00429 }
00430
00432 const K& diagonal(size_type i) const
00433 {
00434 return p_;
00435 }
00436
00438 K& diagonal(size_type i)
00439 {
00440 return p_;
00441 }
00442
00445 const K& scalar() const
00446 {
00447 return p_;
00448 }
00449
00452 K& scalar()
00453 {
00454 return p_;
00455 }
00456
00457 private:
00458
00459 K p_;
00460
00461 };
00462
00463 template<class K, int n>
00464 void istl_assign_to_fmatrix(FieldMatrix<K,n,n>& fm, const ScaledIdentityMatrix<K,n>& s)
00465 {
00466 fm = K();
00467 for(int i=0; i<n; ++i)
00468 fm[i][i] = s.scalar();
00469 }
00470
00471 }
00472
00473 #endif