33 #include <boost/numeric/ublas/storage.hpp>
47 template<u
int16_type Dim,
template<u
int16_type D>
class Type,
bool is_transposed,
bool diag =
false>
59 template<u
int16_type Dim,
bool transpose,
bool diag>
60 class Shape<Dim,Scalar,transpose,diag>
68 static const uint16_type nDim = Dim;
69 static const uint16_type M = 1;
70 static const uint16_type N = 1;
71 static const uint16_type O = 1;
72 static const bool is_transposed = transpose;
73 static const bool is_diagonalized = diag;
74 static const uint16_type rank = Scalar<nDim>::rank;
76 static const bool is_scalar = Scalar<nDim>::is_scalar;
77 static const bool is_vectorial = Scalar<nDim>::is_vectorial;
78 static const bool is_tensor2 = Scalar<nDim>::is_tensor2;
79 static const bool is_tensor3 = Scalar<nDim>::is_tensor3;
86 typedef Shape<Dim,Scalar,transpose, is_diagonalized> shape_type;
98 template<u
int16_type Dim,
bool transpose,
bool diag>
99 class Shape<Dim,Vectorial,transpose, diag>
107 static const uint16_type nDim = Dim;
108 static const uint16_type M = mpl::if_<mpl::equal_to<mpl::bool_<transpose>, mpl::bool_<true> >,
109 mpl::int_<1>, mpl::int_<nDim> >::type::value;
110 static const uint16_type N = mpl::if_<mpl::equal_to<mpl::bool_<transpose>, mpl::bool_<true> >, mpl::int_<nDim>, mpl::int_<1> >::type::value;
111 static const uint16_type O = 1;
112 static const bool is_transposed = transpose;
113 static const bool is_diagonalized = diag;
114 static const uint16_type rank = Vectorial<nDim>::rank;
116 static const bool is_scalar = Vectorial<nDim>::is_scalar;
117 static const bool is_vectorial = Vectorial<nDim>::is_vectorial;
118 static const bool is_tensor2 = Vectorial<nDim>::is_tensor2;
119 static const bool is_tensor3 = Vectorial<nDim>::is_tensor3;
126 typedef Shape<Dim,Vectorial,transpose, is_diagonalized> shape_type;
137 template<u
int16_type Dim,
bool transpose,
bool diag>
138 class Shape<Dim,Tensor2,transpose,diag>
146 static const uint16_type nDim = Dim;
147 static const uint16_type M = nDim;
148 static const uint16_type N = nDim;
149 static const uint16_type O = 1;
150 static const bool is_transposed = transpose;
151 static const bool is_diagonalized = diag;
152 static const uint16_type rank = Tensor2<nDim>::rank;
154 static const bool is_scalar = Tensor2<nDim>::is_scalar;
155 static const bool is_vectorial = Tensor2<nDim>::is_vectorial;
156 static const bool is_tensor2 = Tensor2<nDim>::is_tensor2;
157 static const bool is_tensor3 = Tensor2<nDim>::is_tensor3;
164 typedef Shape<Dim,Tensor2,transpose,diag> shape_type;
175 template<u
int16_type Dim,
bool transpose,
bool diag>
176 class Shape<Dim,Tensor3,transpose,diag>
184 static const uint16_type nDim = Dim;
185 static const uint16_type M = nDim;
186 static const uint16_type N = nDim;
187 static const uint16_type O = nDim;
188 static const bool is_transposed = transpose;
189 static const bool is_diagonalized = diag;
190 static const uint16_type rank = Tensor3<nDim>::rank;
192 static const bool is_scalar = Tensor3<nDim>::is_scalar;
193 static const bool is_vectorial = Tensor3<nDim>::is_vectorial;
194 static const bool is_tensor2 = Tensor3<nDim>::is_tensor2;
195 static const bool is_tensor3 = Tensor3<nDim>::is_tensor3;
202 typedef Shape<Dim,Tensor3,transpose,diag> shape_type;
207 template<
typename TheShape>
215 typedef TheShape original_shape_type;
217 typedef typename mpl::if_<mpl::bool_<original_shape_type::is_scalar>,
218 mpl::identity<Shape<original_shape_type::nDim,Scalar,!original_shape_type::is_transposed,original_shape_type::is_diagonalized> >,
219 typename mpl::if_<mpl::bool_<original_shape_type::is_vectorial>,
220 mpl::identity<Shape<original_shape_type::nDim,Vectorial,!original_shape_type::is_transposed,original_shape_type::is_diagonalized> >,
221 typename mpl::if_<mpl::bool_<original_shape_type::is_tensor2>,
222 mpl::identity<Shape<original_shape_type::nDim,Tensor2,!original_shape_type::is_transposed,original_shape_type::is_diagonalized> >,
223 mpl::identity<Shape<original_shape_type::nDim,Tensor3,!original_shape_type::is_transposed,original_shape_type::is_diagonalized> >
224 >::type >::type >::type::type type;
230 template<
typename TheShape>
238 typedef TheShape original_shape_type;
240 typedef typename mpl::if_<mpl::bool_<original_shape_type::is_scalar>,
241 mpl::identity<Shape<original_shape_type::nDim,Scalar,original_shape_type::is_transposed,original_shape_type::is_diagonalized> >,
242 typename mpl::if_<mpl::bool_<original_shape_type::is_vectorial>,
243 mpl::identity<Shape<original_shape_type::nDim,Tensor2,original_shape_type::is_transposed,original_shape_type::is_diagonalized> >,
244 mpl::identity<Shape<original_shape_type::nDim,Vectorial,original_shape_type::is_transposed,original_shape_type::is_diagonalized> >
245 >::type >::type::type type;
251 template<
typename Left,
typename Right>
252 struct shape_op_samerank
254 static const bool is_rank_ok = ( ( Left::M == Right::M ) && ( Left::N == Right::N ) );
255 BOOST_MPL_ASSERT_MSG( mpl::bool_<is_rank_ok>::value,
256 INVALID_TENSOR_OPERATION_SHOULD_BE_OF_SAME_RANK,
257 ( mpl::int_<Left::M>, mpl::int_<Left::N>,
258 mpl::int_<Right::M>, mpl::int_<Right::N>,
262 static const uint16_type nDim = Left::nDim;
263 static const bool is_diagonalized = Left::is_diagonalized && Right::is_diagonalized;
264 static const bool is_transposed = Left::is_transposed && Right::is_transposed;
266 typedef typename mpl::if_<mpl::bool_<Left::is_scalar>,
267 mpl::identity<Shape<nDim,Scalar,is_transposed,is_diagonalized> >,
268 typename mpl::if_<mpl::bool_<Left::is_vectorial>,
269 mpl::identity<Shape<nDim,Vectorial,is_transposed,is_diagonalized> >,
270 typename mpl::if_<mpl::bool_<Left::is_tensor2>,
271 mpl::identity<Shape<nDim,Tensor2,is_transposed,is_diagonalized> >,
272 mpl::identity<Shape<nDim,Tensor3,is_transposed,is_diagonalized> >
273 >::type >::type >::type::type type;
275 static const int op = 0;
277 template<
bool left_is_zero,
bool right_is_zero>
280 static const bool value = ( left_is_zero && right_is_zero );
281 static const bool update_and_eval_left = !left_is_zero;
282 static const bool update_and_eval_right = !right_is_zero;
286 template<
typename Left,
typename Right>
289 static const uint16_type nDim = Left::nDim;
290 static const bool is_diagonalized = Left::is_diagonalized && Right::is_diagonalized;
291 static const bool is_transposed = Left::is_transposed && Right::is_transposed;
293 typedef typename mpl::if_<mpl::bool_<Left::is_scalar>,
294 mpl::identity<Shape<nDim,Scalar,is_transposed,is_diagonalized> >,
295 typename mpl::if_<mpl::bool_<Left::is_vectorial>,
296 mpl::identity<Shape<nDim,Vectorial,is_transposed,is_diagonalized> >,
297 typename mpl::if_<mpl::bool_<Left::is_tensor2>,
298 mpl::identity<Shape<nDim,Tensor2,is_transposed,is_diagonalized> >,
299 mpl::identity<Shape<nDim,Tensor3,is_transposed,is_diagonalized> >
300 >::type >::type >::type::type type;
302 static const int op = 0;
304 template<
bool left_is_zero,
bool right_is_zero>
307 static const bool value = ( left_is_zero||right_is_zero );
308 static const bool update_and_eval_left = !value;
309 static const bool update_and_eval_right = !value;
313 struct INVALID_MULTIPLICATION {};
314 template<
int D, u
int16_type M, u
int16_type N>
317 typedef typename mpl::if_<mpl::greater<mpl::int_<M>,
319 mpl::identity<Shape<D, Vectorial, false, false> >,
320 typename mpl::if_<mpl::greater<mpl::int_<N>,
322 mpl::identity<Shape<D, Vectorial, true, false> >,
323 typename mpl::if_<mpl::equal_to<mpl::int_<N>,
325 mpl::identity<Shape<D, Scalar, false,false> >,
326 mpl::identity<Shape<D, Tensor2, false,false> > >::type>::type>::type::type type;
331 template<
typename Left,
typename Right>
335 typedef typename mpl::if_<mpl::bool_<Left::is_scalar>,
336 mpl::identity<Right>,
337 typename mpl::if_<mpl::bool_<Right::is_scalar>,
341 typename mpl::if_<mpl::equal_to<mpl::int_<Left::N>,
342 mpl::int_<Right::M> >,
343 mpl::identity<
typename mn_to_shape<Left::nDim,
346 mpl::identity<typename shape_op_id<Left, Right>::type> >::type >::type>::type::type type;
348 static const int op = mpl::if_<mpl::or_<mpl::bool_<Left::is_scalar>,
349 mpl::bool_<Right::is_scalar> >,
351 mpl::int_<1> >::type::value;
352 template<
bool left_is_zero,
bool right_is_zero>
355 static const bool value = ( left_is_zero||right_is_zero );
356 static const bool update_and_eval_left = !value;
357 static const bool update_and_eval_right = !value;
362 template<
typename Left,
typename Right>
366 BOOST_MPL_ASSERT_MSG( mpl::bool_<Right::is_scalar>::value,
367 INVALID_TENSOR_RANK_FOR_DIVISION_SHOULD_BE_0,
370 typedef typename mpl::if_<mpl::bool_<Right::is_scalar>,
371 mpl::identity<mpl::identity<Left> >,
372 mpl::identity<shape_op_id<Left, Right> > >::type::type::type type;
374 static const int op = 0;
376 template<
bool left_is_zero,
bool right_is_zero>
380 static const bool value = left_is_zero;
381 static const bool update_and_eval_left = !value;
382 static const bool update_and_eval_right = !value;
386 template<u
int16_type Dim,
template<u
int16_type D>
class Type,
bool is_transposed,
bool diag>
387 std::ostream& operator<<( std::ostream& os, Shape<Dim, Type, is_transposed, diag>
const& shape )
389 os <<
"shape = [ndim = " << shape.nDim <<
", rank = " << shape.rank <<
", M = " << shape.M <<
", N = " << shape.N <<
"]";