NiHu  2.0
block_product.hpp
Go to the documentation of this file.
1 // This file is a part of NiHu, a C++ BEM template library.
2 //
3 // Copyright (C) 2012-2014 Peter Fiala <fiala@hit.bme.hu>
4 // Copyright (C) 2012-2014 Peter Rucz <rucz@hit.bme.hu>
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
24 #ifndef BLOCK_PRODUCT_HPP_INCLUDED
25 #define BLOCK_PRODUCT_HPP_INCLUDED
26 
27 #include "eigen_utils.hpp"
28 #include "plain_type.hpp"
29 #include "product_type.hpp"
30 
31 #include <iostream>
32 
33 namespace NiHu
34 {
35 
36 namespace internal
37 {
38 template <class leftDerived, class mat, class rightDerived,
39  bool isEigen = is_eigen<mat>::value>
40 class block_product_impl;
41 
43 template <class leftDerived, class Scalar, class rightDerived>
44 class block_product_impl<leftDerived, Scalar, rightDerived, false>
45 {
46 public:
47  typedef typename plain_type<
48  typename product_type<
49  Scalar,
50  typename plain_type<
51  typename product_type<leftDerived, Eigen::Transpose<rightDerived> >::type
52  >::type
53  >::type
54  >::type result_type;
55 
56  static result_type eval(
57  Eigen::MatrixBase<leftDerived> const &v1,
58  Scalar const &m,
59  Eigen::MatrixBase<rightDerived> const &v2
60  )
61  {
62  return m * (v1 * v2.transpose());
63  }
64 };
65 
67 template <class leftDerived, class matDerived, class rightDerived>
68 class block_product_impl<leftDerived, matDerived, rightDerived, true>
69 {
70  typedef typename leftDerived::Scalar scalar1;
71  typedef typename matDerived::Scalar scalar2;
72  typedef typename rightDerived::Scalar scalar3;
73  enum {
74  N1 = leftDerived::RowsAtCompileTime,
75  N21 = matDerived::RowsAtCompileTime, N22 = matDerived::ColsAtCompileTime,
76  N3 = rightDerived::RowsAtCompileTime
77  };
78  typedef typename product_type<
79  scalar1,
81  >::type scalar;
82 
83 public:
84  typedef Eigen::Matrix<scalar, N1*N21, N22*N3> result_type;
85 
86  static result_type eval(
87  Eigen::MatrixBase<leftDerived> const &v1,
88  Eigen::MatrixBase<matDerived> const &m,
89  Eigen::MatrixBase<rightDerived> const &v2)
90  {
91  result_type result;
92  for (size_t row = 0; row < N1; ++row)
93  for (size_t col = 0; col < N3; ++col)
94  result.template block<N21, N22>(row*N21, col*N22) =
95  m * static_cast<scalar>(v1(row, 0) * v2(col, 0));
96  return result;
97  }
98 };
99 
100 
101 template <class mat, class rightDerived,
102  bool isEigen = is_eigen<mat>::value>
103 class semi_block_product_impl;
104 
105 template <class mat, class rightDerived>
106 class semi_block_product_impl<mat, rightDerived, false>
107 {
108 public:
109  typedef typename plain_type<
110  typename product_type<
111  mat,
112  Eigen::Transpose<rightDerived>
113  >::type
114  >::type result_type;
115 
116  static result_type eval(mat const &m, Eigen::MatrixBase<rightDerived> const &v2)
117  {
118  return m * v2.transpose();
119  }
120 };
121 
122 
123 template <class mat, class rightDerived>
124 class semi_block_product_impl<mat, rightDerived, true>
125 {
126  typedef typename mat::Scalar scalar2;
127  typedef typename rightDerived::Scalar scalar3;
128  enum {
129  N21 = mat::RowsAtCompileTime,
130  N22 = mat::ColsAtCompileTime,
131  N3 = rightDerived::RowsAtCompileTime
132  };
133  typedef typename product_type<scalar2, scalar3>::type scalar;
134 public:
135  typedef Eigen::Matrix<scalar, N21, N22*N3> result_type;
136 
137  static result_type eval(
138  Eigen::MatrixBase<Eigen::Matrix<scalar2, N21, N22> > const &m,
139  Eigen::MatrixBase<rightDerived> const &v2)
140  {
141  result_type result;
142  for (int col = 0; col < N3; ++col)
143  result.template block<N21, N22>(0, col*N22) = m * v2(col, 0);
144  return result;
145  }
146 };
147 
148 } // end of namespace internal
149 
150 
151 
153 template <class leftDerived, class mat, class rightDerived>
155 {
156  typedef typename internal::block_product_impl<leftDerived, mat, rightDerived>::result_type type;
157 };
158 
168 template <class leftDerived, class mat, class rightDerived>
169 typename block_product_result_type<leftDerived, mat, rightDerived>::type
171  Eigen::MatrixBase<leftDerived> const &l,
172  mat const &m,
173  Eigen::MatrixBase<rightDerived> const &r)
174 {
175  return internal::block_product_impl<leftDerived, mat, rightDerived>::eval(l, m, r);
176 }
177 
179 template <class mat, class rightDerived>
181 {
182  typedef typename internal::semi_block_product_impl<mat, rightDerived>::result_type type;
183 };
184 
192 template <class mat, class rightDerived>
193 typename semi_block_product_result_type<mat, rightDerived>::type
195  mat const &m,
196  Eigen::MatrixBase<rightDerived> const &r)
197 {
198  return internal::semi_block_product_impl<mat, rightDerived>::eval(m, r);
199 }
200 
201 } // end of namespace NiHu
202 
203 #endif // BLOCK_PRODUCT_HPP_INCLUDED
204 
product_type.hpp
Product type calculations.
NiHu::product_type::type
decltype((*static_cast< typename std::decay< Lhs >::type * >((void *) 10)) *(*static_cast< typename std::decay< Rhs >::type * >((void *) 10))) typede type)
Return type computed by decltype (void *)10 is an arbitrary pointer. Only the return type is computed...
Definition: product_type.hpp:47
NiHu::semi_block_product
semi_block_product_result_type< mat, rightDerived >::type semi_block_product(mat const &m, Eigen::MatrixBase< rightDerived > const &r)
compute semi block product of a matrix and a vector m * v^T
Definition: block_product.hpp:194
eigen_utils.hpp
Implementation of Eigen related utility classes.
plain_type.hpp
Plain type calculations.
NiHu::semi_block_product_result_type
metafunction returning the value type of a semi block product
Definition: block_product.hpp:180
NiHu::block_product
block_product_result_type< leftDerived, mat, rightDerived >::type block_product(Eigen::MatrixBase< leftDerived > const &l, mat const &m, Eigen::MatrixBase< rightDerived > const &r)
compute a block product l * m * r^T
Definition: block_product.hpp:170
NiHu::block_product_result_type
metafunction returning the value type of a block product
Definition: block_product.hpp:154