00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_ASHAPE_INCLUDE
00013 #define MTL_ASHAPE_INCLUDE
00014
00015 #include <boost/static_assert.hpp>
00016 #include <boost/type_traits.hpp>
00017 #include <boost/mpl/if.hpp>
00018
00019 #include <boost/numeric/mtl/mtl_fwd.hpp>
00020 #include <boost/numeric/mtl/utility/tag.hpp>
00021 #include <boost/numeric/mtl/concept/collection.hpp>
00022
00023 namespace mtl {
00024
00026 namespace ashape {
00027
00028
00029
00031 struct scal {};
00033 template <typename Value> struct rvec {};
00035 template <typename Value> struct cvec {};
00037 template <typename Value> struct mat {};
00039 struct ndef {};
00040
00042
00046 template <typename T>
00047 struct ashape
00048 {
00049 typedef scal type;
00050 };
00051
00052
00053
00054 template <typename T>
00055 struct ashape<const T>
00056 {
00057 typedef typename ashape<T>::type type;
00058 };
00059
00060
00062 template <typename Value, typename Parameters>
00063 struct ashape<dense_vector<Value, Parameters> >
00064 {
00065 typedef typename boost::mpl::if_<
00066 boost::is_same<typename Parameters::orientation, row_major>
00067 , rvec<typename ashape<Value>::type>
00068 , cvec<typename ashape<Value>::type>
00069 >::type type;
00070 };
00071
00073 template <typename Value, typename Parameters>
00074 struct ashape<vector::strided_vector_ref<Value, Parameters> >
00075 : ashape<dense_vector<Value, Parameters> > {};
00076
00078 template <typename Value, unsigned Rows>
00079 struct ashape<Value[Rows]>
00080 {
00081 typedef rvec<typename ashape<Value>::type> type;
00082 };
00083
00085 template <typename Value>
00086 struct ashape<Value*>
00087 {
00088 typedef rvec<typename ashape<Value>::type> type;
00089 };
00090
00091 template <typename E1, typename E2, typename SFunctor>
00092 struct ashape< vector::vec_vec_pmop_expr<E1, E2, SFunctor> >
00093 {
00094 BOOST_STATIC_ASSERT((boost::is_same<typename ashape<E1>::type,
00095 typename ashape<E2>::type>::value));
00096 typedef typename ashape<E1>::type type;
00097 };
00098
00099 template <typename E1, typename E2, typename SFunctor>
00100 struct ashape< vector::vec_vec_op_expr<E1, E2, SFunctor> >
00101 {
00102 #if 0 // not sure if this is true in all operations
00103 BOOST_STATIC_ASSERT((boost::is_same<typename ashape<E1>::type,
00104 typename ashape<E2>::type>::value));
00105 #endif
00106 typedef typename ashape<E1>::type type;
00107 };
00108
00109 template <typename E1, typename E2>
00110 struct ashape< vector::vec_vec_plus_asgn_expr<E1, E2> >
00111 {
00112 BOOST_STATIC_ASSERT((boost::is_same<typename ashape<E1>::type,
00113 typename ashape<E2>::type>::value));
00114 typedef typename ashape<E1>::type type;
00115 };
00116
00117 template <typename E1, typename E2>
00118 struct ashape< vector::vec_vec_minus_asgn_expr<E1, E2> >
00119 {
00120 BOOST_STATIC_ASSERT((boost::is_same<typename ashape<E1>::type,
00121 typename ashape<E2>::type>::value));
00122 typedef typename ashape<E1>::type type;
00123 };
00124
00125 template <typename E1, typename E2>
00126 struct ashape< vector::vec_vec_times_asgn_expr<E1, E2> >
00127 {
00128 typedef typename ashape<E1>::type type;
00129 };
00130
00131 template <typename E1, typename E2, typename SFunctor>
00132 struct ashape< vector::vec_vec_aop_expr<E1, E2, SFunctor> >
00133 {
00134 typedef typename ashape<E1>::type type;
00135 };
00136
00137 template <typename E1, typename E2, typename SFunctor>
00138 struct ashape< vector::vec_scal_aop_expr<E1, E2, SFunctor> >
00139 {
00140 typedef typename ashape<E1>::type type;
00141 };
00142
00143 template <typename E1, typename E2>
00144 struct ashape< vector::vec_scal_asgn_expr<E1, E2> >
00145 {
00146 typedef typename ashape<E1>::type type;
00147 };
00148
00149 template <typename E1, typename E2>
00150 struct ashape< vector::vec_scal_times_asgn_expr<E1, E2> >
00151 {
00152 typedef typename ashape<E1>::type type;
00153 };
00154
00155 template <typename E1, typename E2>
00156 struct ashape< vector::vec_scal_div_asgn_expr<E1, E2> >
00157 {
00158 typedef typename ashape<E1>::type type;
00159 };
00160
00161 template <typename Vector>
00162 struct ashape< vector::vec_const_ref_expr<Vector> >
00163 {
00164 typedef typename ashape<Vector>::type type;
00165 };
00166
00167 template <typename E1>
00168 struct ashape< vector::negate_view<E1> >
00169 {
00170 typedef typename ashape<E1>::type type;
00171 };
00172
00173
00174
00175
00176
00177
00178 template <typename Value, typename Parameters>
00179 struct ashape<compressed2D<Value, Parameters> >
00180 {
00181 typedef mat<typename ashape<Value>::type> type;
00182 };
00183
00184 template <typename Value, typename Parameters>
00185 struct ashape<dense2D<Value, Parameters> >
00186 {
00187 typedef mat<typename ashape<Value>::type> type;
00188 };
00189
00190 template <typename Value, unsigned long Mask, typename Parameters>
00191 struct ashape<morton_dense<Value, Mask, Parameters> >
00192 {
00193 typedef mat<typename ashape<Value>::type> type;
00194 };
00195
00197 template <typename Value, unsigned Rows, unsigned Cols>
00198 struct ashape<Value[Rows][Cols]>
00199 {
00200 typedef mat<typename ashape<Value>::type> type;
00201 };
00202
00204 template <typename Value, unsigned Cols>
00205 struct ashape<Value (*)[Cols]>
00206 {
00207 typedef mat<typename ashape<Value>::type> type;
00208 };
00209
00210 template <typename Vector>
00211 struct ashape<multi_vector<Vector> >
00212 {
00213 typedef mat<typename ashape<typename mtl::Collection<multi_vector<Vector> >::value_type>::type> type;
00214 };
00215
00216 template <typename E1, typename E2>
00217 struct ashape< matrix::mat_mat_plus_expr<E1, E2> >
00218 {
00219 BOOST_STATIC_ASSERT((boost::is_same<typename ashape<E1>::type,
00220 typename ashape<E2>::type>::value));
00221 typedef typename ashape<E1>::type type;
00222 };
00223
00224 template <typename E1, typename E2>
00225 struct ashape< matrix::mat_mat_minus_expr<E1, E2> >
00226 {
00227 BOOST_STATIC_ASSERT((boost::is_same<typename ashape<E1>::type,
00228 typename ashape<E2>::type>::value));
00229 typedef typename ashape<E1>::type type;
00230 };
00231
00232 template <typename E1, typename E2>
00233 struct ashape< matrix::mat_mat_ele_times_expr<E1, E2> >
00234 {
00235 BOOST_STATIC_ASSERT((boost::is_same<typename ashape<E1>::type,
00236 typename ashape<E2>::type>::value));
00237 typedef typename ashape<E1>::type type;
00238 };
00239
00240
00241
00242
00243
00244
00245
00246 template <typename Functor, typename Coll>
00247 struct ashape<matrix::map_view<Functor, Coll> >
00248 {
00249 typedef typename ashape<Coll>::type type;
00250 };
00251
00252 template <typename Functor, typename Coll>
00253 struct ashape<vector::map_view<Functor, Coll> >
00254 {
00255 typedef typename ashape<Coll>::type type;
00256 };
00257
00258 template <typename Scaling, typename Coll>
00259 struct ashape<matrix::scaled_view<Scaling, Coll> >
00260 {
00261 typedef typename ashape<Coll>::type type;
00262 };
00263
00264
00265 template <typename Coll, typename RScaling>
00266 struct ashape<matrix::rscaled_view<Coll,RScaling> >
00267 {
00268 typedef typename ashape<Coll>::type type;
00269 };
00270
00271
00272 template <typename Coll, typename Divisor>
00273 struct ashape<matrix::divide_by_view<Coll,Divisor> >
00274 {
00275 typedef typename ashape<Coll>::type type;
00276 };
00277
00278 template <typename Scaling, typename Coll>
00279 struct ashape<vector::scaled_view<Scaling, Coll> >
00280 {
00281 typedef typename ashape<Coll>::type type;
00282 };
00283
00284
00285 template <typename Coll, typename RScaling>
00286 struct ashape<vector::rscaled_view<Coll,RScaling> >
00287 {
00288 typedef typename ashape<Coll>::type type;
00289 };
00290
00291
00292 template <typename Coll, typename Divisor>
00293 struct ashape<vector::divide_by_view<Coll,Divisor> >
00294 {
00295 typedef typename ashape<Coll>::type type;
00296 };
00297
00298 template <typename Coll>
00299 struct ashape<matrix::conj_view<Coll> >
00300 {
00301 typedef typename ashape<Coll>::type type;
00302 };
00303
00304 template <typename Coll>
00305 struct ashape<vector::conj_view<Coll> >
00306 {
00307 typedef typename ashape<Coll>::type type;
00308 };
00309
00310 template <typename Matrix>
00311 struct ashape<transposed_view<Matrix> >
00312 {
00313 typedef typename ashape<Matrix>::type type;
00314 };
00315
00316 template <typename Matrix>
00317 struct ashape<matrix::hermitian_view<Matrix> >
00318 {
00319 typedef typename ashape<Matrix>::type type;
00320 };
00321
00322 template <typename Matrix>
00323 struct ashape<matrix::banded_view<Matrix> >
00324 {
00325 typedef typename ashape<Matrix>::type type;
00326 };
00327
00328
00329
00330 template <typename IFStream, typename OFStream>
00331 struct ashape<io::matrix_file<IFStream, OFStream> >
00332 {
00333 typedef ndef type;
00334 };
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 struct scal_scal_mult {};
00347 struct cvec_rvec_mult {};
00348 struct rvec_cvec_mult {};
00349 struct rvec_mat_mult {};
00350 struct mat_cvec_mult {};
00351 struct mat_mat_mult {};
00352 struct scal_rvec_mult {};
00353 struct scal_cvec_mult {};
00354 struct scal_mat_mult {};
00355 struct rvec_scal_mult {};
00356 struct cvec_scal_mult {};
00357 struct mat_scal_mult {};
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00381
00385 template <typename Shape1, typename Shape2>
00386 struct emult_shape
00387 {
00388 typedef ndef type;
00389 };
00390
00392
00394 template <typename Shape1, typename Shape2>
00395 struct emult_op
00396 {
00397 typedef ndef type;
00398 };
00399
00400
00401
00402 template <>
00403 struct emult_shape<scal, scal>
00404 {
00405 typedef scal type;
00406 };
00407
00408 template <>
00409 struct emult_op<scal, scal>
00410 {
00411 typedef scal_scal_mult type;
00412 };
00413
00414
00415 template <typename Value1, typename Value2>
00416 struct emult_shape<cvec<Value1>, rvec<Value2> >
00417 {
00418 typedef mat<typename emult_shape<Value1, Value2>::type> type;
00419 };
00420
00421 template <typename Value1, typename Value2>
00422 struct emult_op<cvec<Value1>, rvec<Value2> >
00423 {
00424
00425 typedef typename boost::mpl::if_<
00426 boost::is_same<typename emult_op<Value1, Value2>::type, ndef>
00427 , ndef
00428 , cvec_rvec_mult
00429 >::type type;
00430 };
00431
00432
00433
00434 template <typename Value1, typename Value2>
00435 struct emult_shape<rvec<Value1>, cvec<Value2> >
00436 {
00437 typedef typename emult_shape<Value1, Value2>::type type;
00438 };
00439
00440 template <typename Value1, typename Value2>
00441 struct emult_op<rvec<Value1>, cvec<Value2> >
00442 {
00443
00444 typedef typename boost::mpl::if_<
00445 boost::is_same<typename emult_op<Value1, Value2>::type, ndef>
00446 , ndef
00447 , rvec_cvec_mult
00448 >::type type;
00449 };
00450
00451
00452 template <typename Value1, typename Value2>
00453 struct emult_shape<rvec<Value1>, mat<Value2> >
00454 {
00455 typedef rvec<typename emult_shape<Value1, Value2>::type> type;
00456 };
00457
00458
00459 template <typename Value1, typename Value2>
00460 struct emult_op<rvec<Value1>, mat<Value2> >
00461 {
00462
00463 typedef typename boost::mpl::if_<
00464 boost::is_same<typename emult_op<Value1, Value2>::type, ndef>
00465 , ndef
00466 , rvec_mat_mult
00467 >::type type;
00468 };
00469
00470
00471 template <typename Value1, typename Value2>
00472 struct emult_shape<mat<Value1>, cvec<Value2> >
00473 {
00474 typedef cvec<typename emult_shape<Value1, Value2>::type> type;
00475 };
00476
00477 template <typename Value1, typename Value2>
00478 struct emult_op<mat<Value1>, cvec<Value2> >
00479 {
00480
00481 typedef typename boost::mpl::if_<
00482 boost::is_same<typename emult_op<Value1, Value2>::type, ndef>
00483 , ndef
00484 , mat_cvec_mult
00485 >::type type;
00486 };
00487
00488
00489
00490 template <typename Value1, typename Value2>
00491 struct emult_shape<mat<Value1>, mat<Value2> >
00492 {
00493 typedef mat<typename emult_shape<Value1, Value2>::type> type;
00494 };
00495
00496 template <typename Value1, typename Value2>
00497 struct emult_op<mat<Value1>, mat<Value2> >
00498 {
00499
00500 typedef typename boost::mpl::if_<
00501 boost::is_same<typename emult_op<Value1, Value2>::type, ndef>
00502 , ndef
00503 , mat_mat_mult
00504 >::type type;
00505 };
00506
00507
00508
00509
00510
00511
00512
00513
00514 template <typename Shape1, typename Shape2>
00515 struct mult_shape
00516 : public emult_shape<Shape1, Shape2>
00517 {};
00518
00519 template <typename Shape1, typename Shape2>
00520 struct mult_op
00521 : public emult_op<Shape1, Shape2>
00522 {};
00523
00524
00525
00526 template <typename Shape2>
00527 struct mult_shape<scal, Shape2>
00528 {
00529 typedef Shape2 type;
00530 };
00531
00532 template <typename Value2>
00533 struct mult_op<scal, rvec<Value2> >
00534 {
00535 typedef scal_rvec_mult type;
00536 };
00537
00538 template <typename Value2>
00539 struct mult_op<scal, cvec<Value2> >
00540 {
00541 typedef scal_cvec_mult type;
00542 };
00543
00544 template <typename Value2>
00545 struct mult_op<scal, mat<Value2> >
00546 {
00547 typedef scal_mat_mult type;
00548 };
00549
00550
00551
00552 template <typename Shape1>
00553 struct mult_shape<Shape1, scal>
00554 {
00555 typedef Shape1 type;
00556 };
00557
00558 template <typename Value1>
00559 struct mult_op<rvec<Value1>, scal>
00560 {
00561 typedef rvec_scal_mult type;
00562 };
00563
00564 template <typename Value1>
00565 struct mult_op<cvec<Value1>, scal>
00566 {
00567 typedef cvec_scal_mult type;
00568 };
00569
00570 template <typename Value1>
00571 struct mult_op<mat<Value1>, scal>
00572 {
00573 typedef mat_scal_mult type;
00574 };
00575
00576
00577 template <>
00578 struct mult_shape<scal, scal>
00579 {
00580 typedef scal type;
00581 };
00582
00583
00584
00585
00586 template <typename E1, typename E2>
00587 struct ashape< matrix::mat_mat_times_expr<E1, E2> >
00588 {
00589
00590 typedef typename mult_shape<typename ashape<E1>::type,
00591 typename ashape<E2>::type>::type type;
00592 };
00593
00594
00595
00596
00597 template <typename E1, typename E2>
00598 struct ashape< mat_cvec_times_expr<E1, E2> >
00599 {
00600
00601 typedef typename ashape<E2>::type type;
00602 };
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 struct scal_scal_div {};
00615 struct cvec_scal_div {};
00616 struct rvec_scal_div {};
00617 struct mat_scal_div {};
00618
00619 template < typename Shape1, typename Shape2 >
00620 struct div_shape
00621 {
00622 typedef ndef type;
00623 };
00624
00625 template < typename Shape1, typename Shape2 >
00626 struct div_op
00627 {
00628 typedef ndef type;
00629 };
00630
00631 template <>
00632 struct div_shape<scal,scal>
00633 {
00634 typedef scal type;
00635 };
00636
00637 template<>
00638 struct div_op<scal,scal>
00639 {
00640 typedef scal type;
00641 };
00642
00643 template < typename Value1 >
00644 struct div_shape < rvec<Value1>, scal >
00645 {
00646 typedef typename boost::mpl::if_<
00647 typename boost::is_same<typename div_shape<Value1,scal>::type,ndef>::type,
00648 ndef,
00649 rvec<typename div_shape<Value1,scal>::type>
00650 >::type type;
00651 };
00652
00653 template < typename Value1 >
00654 struct div_op< rvec<Value1>, scal >
00655 {
00656 typedef typename boost::mpl::if_<
00657 typename boost::is_same<typename div_shape<rvec<Value1>,scal>::type,ndef>::type,
00658 ndef,
00659 rvec_scal_div
00660 >::type type;
00661 };
00662
00663 template < typename Value1 >
00664 struct div_shape < cvec<Value1>, scal >
00665 {
00666 typedef typename boost::mpl::if_<
00667 typename boost::is_same<typename div_shape<Value1,scal>::type,ndef>::type,
00668 ndef,
00669 cvec<typename div_shape<Value1,scal>::type>
00670 >::type type;
00671 };
00672
00673 template < typename Value1 >
00674 struct div_op< cvec<Value1>, scal >
00675 {
00676 typedef typename boost::mpl::if_<
00677 typename boost::is_same<typename div_shape<cvec<Value1>,scal>::type,ndef>::type,
00678 ndef,
00679 cvec_scal_div
00680 >::type type;
00681 };
00682
00683 template < typename Value1 >
00684 struct div_shape < mat<Value1>, scal >
00685 {
00686 typedef typename boost::mpl::if_<
00687 typename boost::is_same<typename div_shape<Value1,scal>::type,ndef>::type,
00688 ndef,
00689 mat<typename div_shape<Value1,scal>::type>
00690 >::type type;
00691 };
00692
00693 template < typename Value1 >
00694 struct div_op < mat<Value1>, scal >
00695 {
00696 typedef typename boost::mpl::if_<
00697 typename boost::is_same<typename div_shape<mat<Value1>,scal>::type,ndef>::type,
00698 ndef,
00699 mat_scal_div
00700 >::type type;
00701 };
00702
00703
00704
00705
00706
00707 }}
00708
00709 #endif // MTL_ASHAPE_INCLUDE