1 #ifndef DUNE_MultiTypeMATRIX_HH
2 #define DUNE_MultiTypeMATRIX_HH
10 #ifdef HAVE_BOOST_FUSION
12 #include <boost/fusion/sequence.hpp>
13 #include <boost/fusion/container.hpp>
14 #include <boost/fusion/iterator.hpp>
15 #include <boost/typeof/typeof.hpp>
16 #include <boost/fusion/algorithm.hpp>
18 namespace mpl=boost::mpl;
19 namespace fusion=boost::fusion;
24 template<
typename T1,
typename T2=fusion::void_,
typename T3=fusion::void_,
typename T4=fusion::void_,
25 typename T5=fusion::void_,
typename T6=fusion::void_,
typename T7=fusion::void_,
26 typename T8=fusion::void_,
typename T9=fusion::void_>
27 class MultiTypeBlockMatrix;
29 template<
int I,
int crow,
int remain_row>
30 class MultiTypeBlockMatrix_Solver;
54 template<
int crow,
int remain_rows,
int ccol,
int remain_cols,
56 class MultiTypeBlockMatrix_Print {
62 static void print(
const TMatrix& m) {
63 std::cout <<
"\t(" << crow <<
", " << ccol <<
"): \n" << fusion::at_c<ccol>( fusion::at_c<crow>(m));
64 MultiTypeBlockMatrix_Print<crow,remain_rows,ccol+1,remain_cols-1,TMatrix>::print(m);
67 template<
int crow,
int remain_rows,
int ccol,
typename TMatrix>
68 class MultiTypeBlockMatrix_Print<crow,remain_rows,ccol,0,TMatrix> {
69 public:
static void print(
const TMatrix& m) {
71 MultiTypeBlockMatrix_Print<crow+1,remain_rows-1,0,xlen,TMatrix>::print(m);
75 template<
int crow,
int ccol,
int remain_cols,
typename TMatrix>
76 class MultiTypeBlockMatrix_Print<crow,0,ccol,remain_cols,TMatrix> {
78 static void print(
const TMatrix& m)
79 {std::cout << std::endl;}
85 template<
int count,
typename T1,
typename T2>
86 class MultiTypeBlockVector_Ident;
101 template<
int rowcount,
typename T1,
typename T2>
102 class MultiTypeBlockMatrix_Ident {
109 static void equalize(T1& a,
const T2& b) {
110 MultiTypeBlockVector_Ident< mpl::size<
typename mpl::at_c<T1,rowcount-1>
::type >::value ,T1,T2>::equalize(a,b);
111 MultiTypeBlockMatrix_Ident<rowcount-1,T1,T2>::equalize(a,b);
116 template<
typename T1,
typename T2>
117 class MultiTypeBlockMatrix_Ident<0,T1,T2> {
119 static void equalize (T1& a,
const T2& b)
128 template<
int crow,
int remain_rows,
int ccol,
int remain_cols,
129 typename TVecY,
typename TMatrix,
typename TVecX>
130 class MultiTypeBlockMatrix_VectMul {
136 static void umv(TVecY& y,
const TMatrix&
A,
const TVecX& x) {
137 fusion::at_c<ccol>( fusion::at_c<crow>(
A) ).umv( fusion::at_c<ccol>(x), fusion::at_c<crow>(y) );
138 MultiTypeBlockMatrix_VectMul<crow,remain_rows,ccol+1,remain_cols-1,TVecY,TMatrix,TVecX>::umv(y,
A, x);
144 static void mmv(TVecY& y,
const TMatrix&
A,
const TVecX& x) {
145 fusion::at_c<ccol>( fusion::at_c<crow>(
A) ).mmv( fusion::at_c<ccol>(x), fusion::at_c<crow>(y) );
146 MultiTypeBlockMatrix_VectMul<crow,remain_rows,ccol+1,remain_cols-1,TVecY,TMatrix,TVecX>::mmv(y,
A, x);
149 template<
typename AlphaType>
150 static void usmv(
const AlphaType& alpha, TVecY& y,
const TMatrix&
A,
const TVecX& x) {
151 fusion::at_c<ccol>( fusion::at_c<crow>(
A) ).usmv(alpha, fusion::at_c<ccol>(x), fusion::at_c<crow>(y) );
152 MultiTypeBlockMatrix_VectMul<crow,remain_rows,ccol+1,remain_cols-1,TVecY,TMatrix,TVecX>::usmv(alpha,y,
A, x);
159 template<
int crow,
int remain_rows,
int ccol,
typename TVecY,
160 typename TMatrix,
typename TVecX>
161 class MultiTypeBlockMatrix_VectMul<crow,remain_rows,ccol,0,TVecY,TMatrix,TVecX> {
167 static void umv(TVecY& y,
const TMatrix&
A,
const TVecX& x) {
169 MultiTypeBlockMatrix_VectMul<crow+1,remain_rows-1,0,rowlen,TVecY,TMatrix,TVecX>::umv(y, A, x);
175 static void mmv(TVecY& y,
const TMatrix&
A,
const TVecX& x) {
177 MultiTypeBlockMatrix_VectMul<crow+1,remain_rows-1,0,rowlen,TVecY,TMatrix,TVecX>::mmv(y, A, x);
180 template <
typename AlphaType>
181 static void usmv(
const AlphaType& alpha, TVecY& y,
const TMatrix&
A,
const TVecX& x) {
183 MultiTypeBlockMatrix_VectMul<crow+1,remain_rows-1,0,rowlen,TVecY,TMatrix,TVecX>::usmv(alpha,y, A, x);
188 template<
int crow,
int ccol,
int remain_cols,
typename TVecY,
189 typename TMatrix,
typename TVecX>
190 class MultiTypeBlockMatrix_VectMul<crow,0,ccol,remain_cols,TVecY,TMatrix,TVecX> {
193 static void umv(TVecY& y,
const TMatrix&
A,
const TVecX& x) {}
194 static void mmv(TVecY& y,
const TMatrix&
A,
const TVecX& x) {}
196 template<
typename AlphaType>
197 static void usmv(
const AlphaType& alpha, TVecY& y,
const TMatrix&
A,
const TVecX& x) {}
213 template<
typename T1,
typename T2,
typename T3,
typename T4,
214 typename T5,
typename T6,
typename T7,
typename T8,
typename T9>
215 class MultiTypeBlockMatrix :
public fusion::vector<T1, T2, T3, T4, T5, T6, T7, T8, T9> {
222 typedef MultiTypeBlockMatrix<T1, T2, T3, T4, T5, T6, T7, T8, T9>
type;
230 void operator= (
const T& newval) {MultiTypeBlockMatrix_Ident<mpl::size<type>::value,
type,T>::equalize(*
this, newval); }
235 template<
typename X,
typename Y>
236 void mv (
const X& x, Y& y)
const {
237 BOOST_STATIC_ASSERT(mpl::size<X>::value == mpl::size<T1>::value);
238 BOOST_STATIC_ASSERT(mpl::size<Y>::value == mpl::size<type>::value);
241 MultiTypeBlockMatrix_VectMul<0,mpl::size<type>::value,0,mpl::size<T1>::value,Y,
type,X>::umv(y, *
this, x);
247 template<
typename X,
typename Y>
248 void umv (
const X& x, Y& y)
const {
249 BOOST_STATIC_ASSERT(mpl::size<X>::value == mpl::size<T1>::value);
250 BOOST_STATIC_ASSERT(mpl::size<Y>::value == mpl::size<type>::value);
252 MultiTypeBlockMatrix_VectMul<0,mpl::size<type>::value,0,mpl::size<T1>::value,Y,
type,X>::umv(y, *
this, x);
258 template<
typename X,
typename Y>
259 void mmv (
const X& x, Y& y)
const {
260 BOOST_STATIC_ASSERT(mpl::size<X>::value == mpl::size<T1>::value);
261 BOOST_STATIC_ASSERT(mpl::size<Y>::value == mpl::size<type>::value);
263 MultiTypeBlockMatrix_VectMul<0,mpl::size<type>::value,0,mpl::size<T1>::value,Y,
type,X>::mmv(y, *
this, x);
267 template<
typename AlphaType,
typename X,
typename Y>
268 void usmv (
const AlphaType& alpha,
const X& x, Y& y)
const {
269 BOOST_STATIC_ASSERT(mpl::size<X>::value == mpl::size<T1>::value);
270 BOOST_STATIC_ASSERT(mpl::size<Y>::value == mpl::size<type>::value);
272 MultiTypeBlockMatrix_VectMul<0,mpl::size<type>::value,0,mpl::size<T1>::value,Y,
type,X>::usmv(alpha,y, *
this, x);
287 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
288 typename T6,
typename T7,
typename T8,
typename T9>
289 std::ostream& operator<< (std::ostream& s, const MultiTypeBlockMatrix<T1,T2,T3,T4,T5,T6,T7,T8,T9>& m) {
290 static const int i = mpl::size<MultiTypeBlockMatrix<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::value;
291 static const int j = mpl::size< typename mpl::at_c<MultiTypeBlockMatrix<T1,T2,T3,T4,T5,T6,T7,T8,T9>,0>
::type >::value;
292 MultiTypeBlockMatrix_Print<0,i,0,j,MultiTypeBlockMatrix<T1,T2,T3,T4,T5,T6,T7,T8,T9> >::print(m);
302 struct algmeta_itsteps;
315 template<
int I,
int crow,
int ccol,
int remain_col>
316 class MultiTypeBlockMatrix_Solver_Col {
321 template <
typename Trhs,
typename TVector,
typename TMatrix,
typename K>
322 static void calc_rhs(
const TMatrix&
A, TVector& x, TVector& v, Trhs& b,
const K& w) {
323 fusion::at_c<ccol>( fusion::at_c<crow>(
A) ).mmv( fusion::at_c<ccol>(x), b );
324 MultiTypeBlockMatrix_Solver_Col<I, crow, ccol+1, remain_col-1>::calc_rhs(
A,x,v,b,w);
328 template<
int I,
int crow,
int ccol>
329 class MultiTypeBlockMatrix_Solver_Col<I,crow,ccol,0> {
331 template <
typename Trhs,
typename TVector,
typename TMatrix,
typename K>
332 static void calc_rhs(
const TMatrix&
A, TVector& x, TVector& v, Trhs& b,
const K& w) {}
343 template<
int I,
int crow,
int remain_row>
344 class MultiTypeBlockMatrix_Solver {
350 template <
typename TVector,
typename TMatrix,
typename K>
351 static void dbgs(
const TMatrix&
A, TVector& x,
const TVector& b,
const K& w) {
358 template <
typename TVector,
typename TMatrix,
typename K>
359 static void dbgs(
const TMatrix& A, TVector& x, TVector& v,
const TVector& b,
const K& w) {
361 rhs = fusion::at_c<crow> (b);
374 template <
typename TVector,
typename TMatrix,
typename K>
375 static void bsorf(
const TMatrix& A, TVector& x,
const TVector& b,
const K& w) {
381 template <
typename TVector,
typename TMatrix,
typename K>
382 static void bsorf(
const TMatrix& A, TVector& x, TVector& v,
const TVector& b,
const K& w) {
384 rhs = fusion::at_c<crow> (b);
389 fusion::at_c<crow>(x).axpy(w,fusion::at_c<crow>(v));
396 template <
typename TVector,
typename TMatrix,
typename K>
397 static void bsorb(
const TMatrix& A, TVector& x,
const TVector& b,
const K& w) {
403 template <
typename TVector,
typename TMatrix,
typename K>
404 static void bsorb(
const TMatrix& A, TVector& x, TVector& v,
const TVector& b,
const K& w) {
406 rhs = fusion::at_c<crow> (b);
411 fusion::at_c<crow>(x).axpy(w,fusion::at_c<crow>(v));
419 template <
typename TVector,
typename TMatrix,
typename K>
420 static void dbjac(
const TMatrix& A, TVector& x,
const TVector& b,
const K& w) {
426 template <
typename TVector,
typename TMatrix,
typename K>
427 static void dbjac(
const TMatrix& A, TVector& x, TVector& v,
const TVector& b,
const K& w) {
429 rhs = fusion::at_c<crow> (b);
441 template<
int I,
int crow>
442 class MultiTypeBlockMatrix_Solver<I,crow,0> {
444 template <
typename TVector,
typename TMatrix,
typename K>
445 static void dbgs(
const TMatrix& A, TVector& x, TVector& v,
446 const TVector& b,
const K& w) {}
448 template <
typename TVector,
typename TMatrix,
typename K>
449 static void bsorf(
const TMatrix& A, TVector& x, TVector& v,
450 const TVector& b,
const K& w) {}
452 template <
typename TVector,
typename TMatrix,
typename K>
453 static void bsorb(
const TMatrix& A, TVector& x, TVector& v,
454 const TVector& b,
const K& w) {}
456 template <
typename TVector,
typename TMatrix,
typename K>
457 static void dbjac(
const TMatrix& A, TVector& x, TVector& v,
458 const TVector& b,
const K& w) {}
463 #endif // HAVE_BOOST_FUSION