00001
00002
00003
00004
00005
00006
00007
00008
00016 #ifndef matrix_expr_h
00017 #define matrix_expr_h
00018
00019
00020 #include <cml/et/size_checking.h>
00021 #include <cml/matrix/matrix_traits.h>
00022 #include <cml/matrix/matrix_promotions.h>
00023
00024
00025
00026
00027
00028
00029 #define MATXPR_ARG_TYPE const et::MatrixXpr<XprT>&
00030 #define MATXPR_ARG_TYPE_N(_N_) const et::MatrixXpr<XprT##_N_>&
00031
00032
00033
00034
00035 namespace cml {
00036 namespace et {
00037
00039 template<class ExprT>
00040 class MatrixXpr
00041 {
00042 public:
00043
00044 typedef MatrixXpr<ExprT> expr_type;
00045
00046
00047 typedef expr_type expr_const_reference;
00048
00049 typedef typename ExprT::value_type value_type;
00050 typedef matrix_result_tag result_tag;
00051 typedef typename ExprT::size_tag size_tag;
00052
00053
00054 typedef ExprTraits<ExprT> expr_traits;
00055
00056
00057 typedef typename expr_traits::const_reference expr_reference;
00058
00059
00060 typedef typename expr_traits::result_type result_type;
00061
00062
00063 typedef typename result_type::basis_orient basis_orient;
00064
00065
00066 typedef typename result_type::temporary_type temporary_type;
00067
00068
00069 typedef cml::et::not_assignable_tag assignable_tag;
00070
00071
00072 public:
00073
00075 enum { array_rows = ExprT::array_rows, array_cols = ExprT::array_cols };
00076
00077
00078 public:
00079
00081 matrix_size size() const {
00082 return matrix_size(this->rows(),this->cols());
00083 }
00084
00086 size_t rows() const {
00087 return expr_traits().rows(m_expr);
00088 }
00089
00091 size_t cols() const {
00092 return expr_traits().cols(m_expr);
00093 }
00094
00096 expr_reference expression() const { return m_expr; }
00097
00099 value_type operator()(size_t i, size_t j) const {
00100 return expr_traits().get(m_expr,i,j);
00101 }
00102
00104 value_type basis_element(size_t i, size_t j) const {
00105 return basis_element(i,j,basis_orient());
00106 }
00107
00108
00109 public:
00110
00112 explicit MatrixXpr(expr_reference expr) : m_expr(expr) {}
00113
00115 MatrixXpr(const expr_type& e) : m_expr(e.m_expr) {}
00116
00117
00118 protected:
00119
00120 value_type basis_element(size_t i, size_t j, row_basis) const {
00121 return (*this)(i,j);
00122 }
00123
00124 value_type basis_element(size_t i, size_t j, col_basis) const {
00125 return (*this)(j,i);
00126 }
00127
00128
00129 protected:
00130
00131 expr_reference m_expr;
00132
00133
00134 private:
00135
00136
00137 expr_type& operator=(const expr_type&);
00138 };
00139
00141 template<class ExprT>
00142 struct ExprTraits< MatrixXpr<ExprT> >
00143 {
00144 typedef MatrixXpr<ExprT> expr_type;
00145 typedef ExprT arg_type;
00146
00147 typedef typename expr_type::value_type value_type;
00148 typedef typename expr_type::expr_const_reference const_reference;
00149 typedef typename expr_type::result_tag result_tag;
00150 typedef typename expr_type::size_tag size_tag;
00151 typedef typename expr_type::result_type result_type;
00152 typedef typename expr_type::assignable_tag assignable_tag;
00153 typedef expr_node_tag node_tag;
00154
00155 value_type get(const expr_type& e, size_t i, size_t j) const {
00156 return e(i,j);
00157 }
00158
00159
00160 matrix_size size(const expr_type& e) const { return e.size(); }
00161 size_t rows(const expr_type& e) const { return e.rows(); }
00162 size_t cols(const expr_type& e) const { return e.cols(); }
00163 };
00164
00165
00170 template<class ExprT, class OpT>
00171 class UnaryMatrixOp
00172 {
00173 public:
00174
00175 typedef UnaryMatrixOp<ExprT,OpT> expr_type;
00176
00177
00178 typedef unary_expression expr_ary;
00179
00180
00181 typedef expr_type expr_const_reference;
00182
00183 typedef typename OpT::value_type value_type;
00184 typedef matrix_result_tag result_tag;
00185 typedef typename ExprT::size_tag size_tag;
00186
00187
00188 typedef ExprTraits<ExprT> expr_traits;
00189
00190
00191 typedef typename expr_traits::const_reference expr_reference;
00192
00193
00194 typedef typename expr_traits::result_type result_type;
00195
00196
00197 typedef typename result_type::temporary_type temporary_type;
00198
00199
00200 typedef cml::et::not_assignable_tag assignable_tag;
00201
00202
00203 public:
00204
00206 enum { array_rows = ExprT::array_rows, array_cols = ExprT::array_cols };
00207
00208
00209 public:
00210
00212 matrix_size size() const {
00213 return matrix_size(this->rows(),this->cols());
00214 }
00215
00217 size_t rows() const {
00218 return expr_traits().rows(m_expr);
00219 }
00220
00222 size_t cols() const {
00223 return expr_traits().cols(m_expr);
00224 }
00225
00227 value_type operator()(size_t i, size_t j) const {
00228
00229
00230
00231
00232 return OpT().apply(expr_traits().get(m_expr,i,j));
00233 }
00234
00235
00236 public:
00237
00239 explicit UnaryMatrixOp(expr_reference expr) : m_expr(expr) {}
00240
00242 UnaryMatrixOp(const expr_type& e) : m_expr(e.m_expr) {}
00243
00244
00245 protected:
00246
00247 expr_reference m_expr;
00248
00249
00250 private:
00251
00252
00253 expr_type& operator=(const expr_type&);
00254 };
00255
00257 template<class ExprT, class OpT>
00258 struct ExprTraits< UnaryMatrixOp<ExprT,OpT> >
00259 {
00260 typedef UnaryMatrixOp<ExprT,OpT> expr_type;
00261 typedef ExprT arg_type;
00262
00263 typedef typename expr_type::value_type value_type;
00264 typedef typename expr_type::expr_const_reference const_reference;
00265 typedef typename expr_type::result_tag result_tag;
00266 typedef typename expr_type::size_tag size_tag;
00267 typedef typename expr_type::result_type result_type;
00268 typedef typename expr_type::assignable_tag assignable_tag;
00269 typedef expr_node_tag node_tag;
00270
00271 value_type get(const expr_type& e, size_t i, size_t j) const {
00272 return e(i,j);
00273 }
00274
00275 matrix_size size(const expr_type& e) const { return e.size(); }
00276 size_t rows(const expr_type& e) const { return e.rows(); }
00277 size_t cols(const expr_type& e) const { return e.cols(); }
00278 };
00279
00280
00282 template<class LeftT, class RightT, class OpT>
00283 class BinaryMatrixOp
00284 {
00285 public:
00286
00287 typedef BinaryMatrixOp<LeftT,RightT,OpT> expr_type;
00288
00289
00290
00291
00292 typedef expr_type expr_const_reference;
00293
00294 typedef typename OpT::value_type value_type;
00295 typedef matrix_result_tag result_tag;
00296
00297
00298 typedef cml::et::not_assignable_tag assignable_tag;
00299
00300
00301 typedef ExprTraits<LeftT> left_traits;
00302 typedef ExprTraits<RightT> right_traits;
00303
00304
00305 typedef typename left_traits::const_reference left_reference;
00306 typedef typename right_traits::const_reference right_reference;
00307
00308
00309 typedef typename left_traits::result_type left_result;
00310 typedef typename right_traits::result_type right_result;
00311 typedef typename MatrixPromote<left_result,right_result>::type result_type;
00312 typedef typename result_type::size_tag size_tag;
00313
00314
00315 typedef typename result_type::temporary_type temporary_type;
00316
00317
00318 typedef GetCheckedSize<LeftT,RightT,size_tag> checked_size;
00319
00320
00321 public:
00322
00327 enum {
00328 array_rows = result_type::array_rows,
00329 array_cols = result_type::array_cols
00330 };
00331
00332
00333 public:
00334
00336 matrix_size size() const {
00337 return CheckedSize(m_left,m_right,size_tag());
00338 }
00339
00346 size_t rows() const {
00347 #if defined(CML_CHECK_MATRIX_EXPR_SIZES)
00348 return this->size().first;
00349 #else
00350 return left_traits().rows(m_left);
00351 #endif
00352 }
00353
00360 size_t cols() const {
00361 #if defined(CML_CHECK_MATRIX_EXPR_SIZES)
00362 return this->size().second;
00363 #else
00364 return right_traits().cols(m_right);
00365 #endif
00366 }
00367
00369 value_type operator()(size_t i, size_t j) const {
00370
00371
00372
00373
00374 return OpT().apply(
00375 left_traits().get(m_left,i,j),
00376 right_traits().get(m_right,i,j));
00377 }
00378
00379
00380 public:
00381
00387 explicit BinaryMatrixOp(left_reference left, right_reference right)
00388 : m_left(left), m_right(right) {}
00389
00391 BinaryMatrixOp(const expr_type& e)
00392 : m_left(e.m_left), m_right(e.m_right) {}
00393
00394
00395 protected:
00396
00397 left_reference m_left;
00398 right_reference m_right;
00399
00400
00401 private:
00402
00403
00404 typename checked_size::check_type _dummy;
00405
00406
00407 private:
00408
00409
00410 expr_type& operator=(const expr_type&);
00411 };
00412
00414 template<class LeftT, class RightT, class OpT>
00415 struct ExprTraits< BinaryMatrixOp<LeftT,RightT,OpT> >
00416 {
00417 typedef BinaryMatrixOp<LeftT,RightT,OpT> expr_type;
00418 typedef LeftT left_type;
00419 typedef RightT right_type;
00420
00421 typedef typename expr_type::value_type value_type;
00422 typedef typename expr_type::expr_const_reference const_reference;
00423 typedef typename expr_type::result_tag result_tag;
00424 typedef typename expr_type::size_tag size_tag;
00425 typedef typename expr_type::result_type result_type;
00426 typedef typename expr_type::assignable_tag assignable_tag;
00427 typedef expr_node_tag node_tag;
00428
00429 value_type get(const expr_type& e, size_t i, size_t j) const {
00430 return e(i,j);
00431 }
00432
00433 matrix_size size(const expr_type& e) const { return e.size(); }
00434 size_t rows(const expr_type& e) const { return e.rows(); }
00435 size_t cols(const expr_type& e) const { return e.cols(); }
00436 };
00437
00438
00439 template<typename LeftTraits, typename RightTraits>
00440 struct MatrixExpressions
00441 {
00442
00443 typedef typename LeftTraits::result_tag left_result;
00444 typedef typename RightTraits::result_tag right_result;
00445 enum { is_true = (same_type<left_result,et::matrix_result_tag>::is_true
00446 && same_type<right_result,et::matrix_result_tag>::is_true) };
00447 };
00448
00449 namespace detail {
00450
00451
00452
00453
00454 template<typename MatT, typename MT> inline
00455 void Resize(MatT&, size_t, size_t, fixed_size_tag, MT) {}
00456
00457 template<typename MatT> inline
00458 void Resize(MatT& m,
00459 size_t R, size_t C, dynamic_size_tag, dynamic_memory_tag)
00460 {
00461 m.resize(R,C);
00462 }
00463
00464 template<typename MatT> inline
00465 void Resize(MatT& m, size_t R, size_t C) {
00466 Resize(m, R, C, typename MatT::size_tag(), typename MatT::memory_tag());
00467 }
00468
00469 template<typename MatT> inline
00470 void Resize(MatT& m, matrix_size N) {
00471 Resize(m, N.first, N.second,
00472 typename MatT::size_tag(), typename MatT::memory_tag());
00473 }
00474
00475 }
00476
00477 }
00478 }
00479
00480 #endif
00481
00482
00483