00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00030 #ifdef _MSC_VER
00031
00032 # if _MSC_VER < 1300
00033 # pragma warning( disable : 4786 )
00034 # endif // VC6
00035 # pragma once
00036 # pragma warning( push )
00037 # pragma warning( disable : 4100 4127 4239 4244 4512 4786 )
00038 #endif // _MSC_VER
00039
00040
00041 #ifndef _EXMAT_MAT_H
00042 #define _EXMAT_MAT_H
00043
00044 #include <iterator>
00045 #include <sstream>
00046 #include <iostream>
00047 #include <algorithm>
00048 #include "PlatformSpec.h"
00049 #include "Config.h"
00050 #include "ErrorCheck.h"
00051 #include "TypeTraits.h"
00052 #include "Commainit.h"
00053 #include "Assignment.h"
00054 #include "SIMD/SIMD.h"
00055
00056
00057 namespace exmat {
00058 template<class Rep, class ErrChecker_> class Mat;
00059 template<class Rep, class ErrChecker_> class Vec;
00060 }
00061
00062
00064 namespace exmat {
00065
00067 namespace PNS {
00068 template<class Mat, typename IdxT> EXMAT_INLINE2 static
00069 void IOResize(Mat& m, IdxT r, IdxT c, Int2Type<true>, Int2Type<true>) {
00070 m.resize(r, c);
00071 }
00072 template<class Mat, typename IdxT> EXMAT_INLINE2 static
00073 void IOResize(Mat& m, IdxT r, IdxT c, Int2Type<true>, Int2Type<false>) {
00074 m.resizeRow(r);
00075 }
00076 template<class Mat, typename IdxT> EXMAT_INLINE2 static
00077 void IOResize(Mat& m, IdxT r, IdxT c, Int2Type<false>, Int2Type<true>) {
00078 m.resizeCol(c);
00079 }
00080 template<class Mat, typename IdxT> EXMAT_INLINE2 static
00081 void IOResize(Mat& m, IdxT r, IdxT c, Int2Type<false>, Int2Type<false>) {
00082 }
00083 };};
00084
00086 template<class Rep, class ErrChecker> EXMAT_INLINE0
00087 std::istream& operator>>(std::istream &is, exmat::Mat<Rep, ErrChecker>& mat) {
00088 typedef exmat::Mat<Rep, ErrChecker> mat_type;
00089 typedef typename mat_type::index_type index_type;
00090 index_type rs=0, cs=0;
00091
00092 if(mat_type::IsDR) is >> rs;
00093
00094 if(mat_type::IsDC) is >> cs;
00095
00096 exmat::PNS::IOResize(mat, rs, cs,
00097 exmat::Int2Type<mat_type::IsDR>(), exmat::Int2Type<mat_type::IsDC>());
00098 for(index_type i=0; i<mat.rows(); ++i) {
00099 for(index_type j=0; j<mat.cols(); ++j)
00100 is >> mat.setAt(i, j);
00101 }
00102 return is;
00103 }
00104
00106 template<class Rep, class ErrChecker> EXMAT_INLINE0
00107 std::ostream& operator<<(std::ostream &os, const exmat::Mat<Rep, ErrChecker>& mat) {
00108 typedef typename exmat::Mat<Rep, ErrChecker>::index_type index_type;
00109 for(index_type i=0; i<mat.rows(); ++i) {
00110 for(index_type j=0; j<mat.cols(); ++j)
00111 os << mat.getAt(i, j) << " ";
00112 os << std::endl;
00113 }
00114 return os;
00115 }
00116
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 #if EXMAT_VC6 || EXMAT_VC7
00133
00134
00135 #define Mak_Op(LT, RT, OT, op, OpName) \
00136 template<class L, class R, class LC, class RC> EXMAT_INLINE2 \
00137 const exmat::OT<exmat::ExpMat<exmat::OpName<L::rep_type, R::rep_type> >, exmat::ResultantChecker<LC,RC>::RET> \
00138 op (const exmat::LT<L,LC>& A, const exmat::RT<R,RC>& B) { \
00139 using namespace exmat; \
00140 typedef ExpMat<OpName<L::rep_type, R::rep_type> > RETType; \
00141 return RETType(A, B); \
00142 }
00143
00144 #define Mak_ScalarOp1(OT, op, OpName) \
00145 template<class L, class EC> EXMAT_INLINE2 \
00146 const exmat::OT<exmat::ExpMat<exmat::OpName<L::rep_type,exmat::ScalarCon<L::value_type> > >, EC> \
00147 op (const exmat::OT<L,EC>& A, L::const_param_type scalar) { \
00148 using namespace exmat; \
00149 typedef ExpMat<OpName<L::rep_type,ScalarCon<L::value_type> > > RETType; \
00150 return RETType(A, ScalarCon<L::value_type>(scalar)); \
00151 }
00152
00153 #define Mak_ScalarOp2(OT, op, OpName) \
00154 template<class L, class EC> EXMAT_INLINE2 \
00155 const exmat::OT<exmat::ExpMat<exmat::OpName<exmat::ScalarCon<L::value_type>, L::rep_type> >, EC> \
00156 op (typename L::const_param_type scalar, const exmat::OT<L,EC>& A) { \
00157 using namespace exmat; \
00158 typedef ExpMat<OpName<ScalarCon<L::value_type>, L::rep_type> > RETType; \
00159 return RETType(ScalarCon<L::value_type>(scalar), A); \
00160 }
00161
00162 #else
00163
00165 #define Mak_Op(LT, RT, OT, op, OpName) \
00166 template<class L, class R, class LC, class RC> EXMAT_INLINE2 static \
00167 const exmat::OT<exmat::ExpMat<typename exmat::OpName<typename L::rep_type, typename R::rep_type>::rep_type>, typename exmat::ResultantChecker<LC,RC>::RET> \
00168 op (const exmat::LT<L,LC>& A, const exmat::RT<R,RC>& B) { \
00169 using namespace exmat; \
00170 typedef ExpMat<TTYPENAME OpName<TTYPENAME L::rep_type,TTYPENAME R::rep_type>::rep_type> RETType; \
00171 return RETType(A, B); \
00172 }
00173
00174 #define Mak_ScalarOp1(OT, op, OpName) \
00175 template<class L, class EC> EXMAT_INLINE2 static \
00176 const exmat::OT<exmat::ExpMat<typename exmat::OpName<typename L::rep_type,exmat::ScalarCon<typename L::value_type> >::rep_type>, EC> \
00177 op (const exmat::OT<L,EC>& A, typename L::const_param_type scalar) { \
00178 using namespace exmat; \
00179 typedef ExpMat<TTYPENAME OpName<TTYPENAME L::rep_type,ScalarCon<TTYPENAME L::value_type> >::rep_type> RETType; \
00180 return RETType(A, ScalarCon<TTYPENAME L::value_type>(scalar)); \
00181 }
00182
00183 #define Mak_ScalarOp2(OT, op, OpName) \
00184 template<class L, class EC> EXMAT_INLINE2 static \
00185 const exmat::OT<exmat::ExpMat<typename exmat::OpName<exmat::ScalarCon<typename L::value_type>, typename L::rep_type>::rep_type>, EC> \
00186 op (typename L::const_param_type scalar, const exmat::OT<L,EC>& A) { \
00187 using namespace exmat; \
00188 typedef ExpMat<TTYPENAME OpName<ScalarCon<TTYPENAME L::value_type>, TTYPENAME L::rep_type>::rep_type> RETType; \
00189 return RETType(ScalarCon<TTYPENAME L::value_type>(scalar), A); \
00190 }
00191
00192 #endif // EXMAT_VC6 || EXMAT_VC7
00193
00194
00203
00204 Mak_Op(Mat, Mat, Mat, operator+, AddExp);
00206 Mak_Op(Vec, Vec, Vec, operator+, AddExp);
00207
00208
00210 Mak_ScalarOp1(Mat, operator+, AddExp);
00212 Mak_ScalarOp2(Mat, operator+, AddExp);
00213
00214
00216 Mak_ScalarOp1(Vec, operator+, AddExp);
00218 Mak_ScalarOp2(Vec, operator+, AddExp);
00220
00221
00225
00226 Mak_Op(Mat, Mat, Mat, operator-, SubExp);
00228 Mak_Op(Vec, Vec, Vec, operator-, SubExp);
00229
00230
00232 Mak_ScalarOp1(Mat, operator-, SubExp);
00234 Mak_ScalarOp2(Mat, operator-, SubExp);
00235
00236
00238 Mak_ScalarOp1(Vec, operator-, SubExp);
00240 Mak_ScalarOp2(Vec, operator-, SubExp);
00242
00243
00247
00248 Mak_Op(Mat, Mat, Mat, operator*, MulExp);
00250 Mak_ScalarOp1(Mat, operator*, ScalarMulExp);
00252 Mak_ScalarOp2(Mat, operator*, ScalarMulExp);
00254 Mak_Op(Vec, Vec, Vec, operator*, MulExp);
00256 Mak_Op(Mat, Vec, Vec, operator*, MulExp);
00258 Mak_Op(Vec, Mat, Vec, operator*, MulExp);
00260 Mak_ScalarOp1(Vec, operator*, ScalarMulExp);
00262 Mak_ScalarOp2(Vec, operator*, ScalarMulExp);
00264
00268
00269 Mak_ScalarOp1(Mat, operator/, ScalarDivExp);
00271 Mak_ScalarOp1(Vec, operator/, ScalarDivExp);
00273
00274
00275 #undef Mak_Op
00276 #undef Mak_ScalarOp1
00277 #undef Mak_ScalarOp2
00278
00280
00281
00282 namespace exmat {
00283
00285
00288 template<class MAT>
00289 struct ConstErrChkedRow {
00290 typedef typename MAT::index_type index_type;
00291 typedef typename MAT::reference reference;
00292 typedef typename MAT::const_reference const_reference;
00293 typedef typename MAT::ErrChecker ErrChecker;
00294
00295 EXMAT_INLINE2 ConstErrChkedRow(const MAT& mat_, index_type i)
00296 : mat(mat_), row(i) {}
00297 EXMAT_INLINE2 const_reference operator[](const index_type i) const {
00298 ErrChecker::AssertBounds(index_type(0), index_type(mat.cols()-1), i);
00299 return mat.getAt(row, i);
00300 }
00301 const MAT& mat;
00302 index_type row;
00303 };
00304
00306
00309 template<class MAT>
00310 struct ErrChkedRow {
00311 typedef typename MAT::index_type index_type;
00312 typedef typename MAT::reference reference;
00313 typedef typename MAT::const_reference const_reference;
00314 typedef typename MAT::ErrChecker ErrChecker;
00315
00316 EXMAT_INLINE2 ErrChkedRow(MAT& mat_, index_type i)
00317 : mat(mat_), row(i) {}
00318 EXMAT_INLINE2 reference operator[](const index_type i) {
00319 ErrChecker::AssertBounds(index_type(0), index_type(mat.cols()-1), i);
00320 return mat.setAt(row, i);
00321 }
00322 EXMAT_INLINE2 const_reference operator[](const index_type i) const {
00323 ErrChecker::AssertBounds(index_type(0), index_type(mat.cols()-1), i);
00324 return mat.getAt(row, i);
00325 }
00326 MAT& mat;
00327 index_type row;
00328 };
00329
00330
00332
00335 template<class Rep, class ErrChecker_=DefaultErrorChecker>
00336 class Mat : public Rep {
00337 public:
00338 typedef Rep super_type;
00339 typedef Mat<Rep, ErrChecker_> self_type;
00340 enum {
00341 IsFullErrorChecker = ISSAMETYPE<ErrChecker_,FullErrorChecker>::RET,
00342
00343 IsDR = (Rep::ROWS == 0),
00344 IsDC = (Rep::COLS == 0)
00345 };
00346 typedef typename
00347 IF<IsFullErrorChecker, ErrChkedRow<self_type>, typename Rep::row_type
00348 >::RET row_type;
00349 typedef typename
00350 IF<IsFullErrorChecker, ConstErrChkedRow<self_type>, typename Rep::const_row_type
00351 >::RET const_row_type;
00352 typedef typename Rep::col_type col_type;
00353 typedef typename Rep::value_type value_type;
00354 typedef typename Rep::index_type index_type;
00355 typedef typename Rep::reference reference;
00356 typedef typename Rep::const_reference const_reference;
00357 typedef typename Rep::param_type param_type;
00358 typedef typename Rep::const_param_type const_param_type;
00359 typedef ErrChecker_ ErrChecker;
00360 typedef typename Rep::rep_type rep_type;
00361
00362 private:
00364
00367 EXMAT_INLINE2 row_type IndexOp(index_type i, Int2Type<true>) {
00368 ErrChecker::AssertBounds(index_type(0), index_type(Rep::rows()-1), i);
00369 return row_type(*this, i);
00370 }
00371 EXMAT_INLINE2 row_type IndexOp(index_type i, Int2Type<false>) {
00372 return Rep::operator[](i);
00373 }
00374 EXMAT_INLINE2 const_row_type IndexOp(index_type i, Int2Type<true>) const {
00375 ErrChecker::AssertBounds(index_type(0), index_type(Rep::rows()-1), i);
00376 return const_row_type(*this, i);
00377 }
00378 EXMAT_INLINE2 const_row_type IndexOp(index_type i, Int2Type<false>) const {
00379 return Rep::operator[](i);
00380 }
00382
00383 private:
00385
00388 EXMAT_INLINE2 void CTORresizer(size_t r, size_t c, Int2Type<true>, Int2Type<true>)
00389 { Rep::resize(r, c); }
00390 EXMAT_INLINE2 void CTORresizer(size_t r, size_t c, Int2Type<true>, Int2Type<false>)
00391 { Rep::resize(r); }
00392 EXMAT_INLINE2 void CTORresizer(size_t r, size_t c, Int2Type<false>, Int2Type<true>)
00393 { Rep::resize(c); }
00394 EXMAT_INLINE2 void CTORresizer(size_t r, size_t c, Int2Type<false>, Int2Type<false>)
00395 {}
00397
00398 public:
00399
00401 EXMAT_INLINE2 Mat() {}
00402
00403
00404 template<typename T>
00405 struct _AlwaysTrue { enum {RET=true}; };
00410 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00411 Mat(const Mat<Rep2, ErrChk2>& A
00412 #if !EXMAT_NO_SFINAE
00413 ,typename DisableIf_c<
00414 IsDerivedFrom<Rep,ViewTag>::RET && _AlwaysTrue<Rep2>::RET
00415 >::RET* dummy=NULL
00416 #endif
00417 ) {
00418
00419 CTORresizer(A.rows(), A.cols(), Int2Type<IsDR>(), Int2Type<IsDC>());
00420 assign(*this, A);
00421
00422 }
00423
00425
00426 template<class Rep2> EXMAT_INLINE2
00427 Mat(ExpMat<Rep2>& A) : Rep(A) {}
00428 template<class Rep2> EXMAT_INLINE2
00429 Mat(const ExpMat<Rep2>& A) : Rep(A) {}
00431
00433
00434
00435
00437
00441 EXMAT_INLINE2 Mat(const std::string& s) {
00442
00443
00444 std::istringstream ins(s);
00445 ::operator>>(ins, *this);
00446 }
00447
00449
00450 template<class T1, class T2>
00451 EXMAT_INLINE2 Mat(T1& t1, T2& t2) : Rep(t1, t2) {}
00452 template<class T1, class T2, class T3>
00453 EXMAT_INLINE2 Mat(T1& t1, T2& t2, T3& t3) : Rep(t1, t2, t3) {}
00454 template<class T1, class T2, class T3, class T4>
00455 EXMAT_INLINE2 Mat(T1& t1, T2& t2, T3& t3, T4& t4) : Rep(t1, t2, t3, t4) {}
00456 template<class T1, class T2, class T3, class T4, class T5>
00457 EXMAT_INLINE2 Mat(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) : Rep(t1, t2, t3, t4, t5) {}
00458 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
00459 EXMAT_INLINE2 Mat(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9) : Rep(t1, t2, t3, t4, t5, t6, t7, t8, t9) {}
00460 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15, class T16>
00461 EXMAT_INLINE2 Mat(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9, T10 t10, T11& t11, T12& t12, T13& t13, T14& t14, T15& t15, T16& t16) : Rep(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16) {}
00462
00463 #if HAVE_PARTIAL_SPECIALIZATION
00464 template<class T1, class T2>
00465 EXMAT_INLINE2 Mat(const T1& t1, const T2& t2) : Rep(t1, t2) {}
00466 template<class T1, class T2, class T3>
00467 EXMAT_INLINE2 Mat(const T1& t1, const T2& t2, const T3& t3) : Rep(t1, t2, t3) {}
00468 template<class T1, class T2, class T3, class T4>
00469 EXMAT_INLINE2 Mat(const T1& t1, const T2& t2, const T3& t3, const T4& t4) : Rep(t1, t2, t3, t4) {}
00470 template<class T1, class T2, class T3, class T4, class T5>
00471 EXMAT_INLINE2 Mat(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) : Rep(t1, t2, t3, t4, t5) {}
00472 #endif // HAVE_PARTIAL_SPECIALIZATION
00473
00474
00476
00477 EXMAT_INLINE2 explicit Mat(const Dim& d) : Rep(d) {}
00478 EXMAT_INLINE2 explicit Mat(const Dim& d1, const Dim& d2, const_param_type s) : Rep(d1, d2, s) {}
00480
00481 EXMAT_INLINE2 Mat(const_param_type s) : Rep(s) {}
00482
00483
00487
00488
00489
00490
00491
00492
00493
00494
00495 EXMAT_INLINE2 self_type& ScalarInit(const_param_type s) {
00496 (*static_cast<Rep*>(this)) = s;
00497 return *this;
00498 }
00501 EXMAT_INLINE2 CommaInitializer<self_type> operator=(const_param_type s) {
00502 return CommaInitializer<self_type>(*this, s);
00503 }
00504
00506 template<class Res, class Exp> EXMAT_INLINE2 static
00507 void AssignDispatcher(Res& res, const Exp& exp) {
00508 enum {
00509 IsSIMD =
00510
00511 IsDerivedFrom<Res,SIMDTag>::RET &&
00512 IsDerivedFrom<Exp,SIMDTag>::RET &&
00513
00514 (ENABLE_TMP_ANALYSIS || Exp::IsLinearRecursive)
00515 };
00516 #if ENABLE_UNROLLING
00517 typedef LinearBinExpSize<Res, Exp> BINEXPSize;
00518 enum {
00519
00520 UnrollRow =
00521 BINEXPSize::ROWS > 0 &&
00522 (unsigned int)(Exp::ENOP * BINEXPSize::COLS) < (unsigned int)MAX_UROLLROW_NOP
00523 };
00524 enum {
00525 UnrollCol =
00526 BINEXPSize::COLS > 0 &&
00527 (unsigned int)Exp::TNOP < (unsigned int)MAX_FULLUROLL_NOP
00528 };
00529
00530 enum {
00531 AssignDispatchID =
00532 IsSIMD ? exmat::PNS::ASSIGN_TYPE::Ass_SIMD :
00533 UnrollRow + 2*UnrollCol
00534 };
00535 #else
00536 enum {
00537 AssignDispatchID =
00538 IsSIMD ? exmat::PNS::ASSIGN_TYPE::Ass_SIMD :
00539 PNS::ASSIGN_TYPE::Ass_NoUnRoll
00540 };
00541 #endif
00542
00543
00544 ErrChecker::AssertCompat(res.rows() == exp.rows() && res.cols() == exp.cols());
00545
00546 exmat::PNS::Assign(res, exp, Int2Type<AssignDispatchID>());
00547
00548
00549
00550
00551
00552
00553
00554 }
00555
00557 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00558 Mat& AssignNoAna(const Mat<Rep2, ErrChk2>& A) {
00559 AssignDispatcher(*this, A);
00560 return *this;
00561 }
00563 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00564 Mat& operator=(const Mat<Rep2, ErrChk2>& A) {
00565
00566 assign(*this, A, EXMAT_DEFAULT_ANALYSIS);
00567 return *this;
00568 }
00570 EXMAT_INLINE2 Mat& operator=(const self_type& A) {
00571
00572 *((Rep*)(this)) = A;
00573 return *this;
00574 }
00576
00577
00589 EXMAT_INLINE2 reference operator() (index_type r, index_type c) {
00590 ErrChecker::AssertBounds(index_type(0), index_type(Rep::rows()-1), r);
00591 ErrChecker::AssertBounds(index_type(0), index_type(Rep::cols()-1), c);
00592 return setAt(r, c);
00593 }
00594 EXMAT_INLINE2 const_reference operator() (index_type r, index_type c) const {
00595 ErrChecker::AssertBounds(index_type(0), index_type(Rep::rows()-1), r);
00596 ErrChecker::AssertBounds(index_type(0), index_type(Rep::cols()-1), c);
00597 return getAt(r, c);
00598 }
00600
00610 EXMAT_INLINE2 row_type operator[] (index_type r) {
00611 return IndexOp(r, Int2Type<IsFullErrorChecker>());
00612 }
00613 EXMAT_INLINE2 const_row_type operator[] (index_type r) const {
00614 return IndexOp(r, Int2Type<IsFullErrorChecker>());
00615 }
00617
00618
00622
00623 EXMAT_INLINE2 self_type& operator+=(const_param_type s) {
00624 *this = ::operator+(*this, s);
00625 return *this;
00626 }
00628 EXMAT_INLINE2 self_type& operator-=(const_param_type s) {
00629 *this = ::operator-(*this, s);
00630 return *this;
00631 }
00633 EXMAT_INLINE2 self_type& operator*=(const_param_type s) {
00634 *this = ::operator*(*this, s);
00635 return *this;
00636 }
00638 EXMAT_INLINE2 self_type& operator/=(const_param_type s) {
00639 *this = ::operator/(*this, s);
00640 return *this;
00641 }
00643 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00644 self_type& operator+=(const Mat<Rep2,ErrChk2>& A) {
00645 *this = ::operator+(*this, A);
00646 return *this;
00647 }
00649 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00650 self_type& operator-=(const Mat<Rep2,ErrChk2>& A) {
00651 *this = ::operator-(*this, A);
00652 return *this;
00653 }
00655 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00656 self_type& operator*=(const Mat<Rep2,ErrChk2>& A) {
00657
00658 self_type tmp( ::operator*(*this, A) );
00659 *this = tmp;
00660 return *this;
00661 }
00663
00664
00672 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00673 bool operator!=(const Mat<Rep2,ErrChk2>& A) const {
00674 return !(*this == A);
00675 }
00680 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00681 bool operator==(const Mat<Rep2,ErrChk2>& A) const
00682 {
00683 typedef typename Rep2::value_type T2;
00684
00685 if(Rep::rows() != A.rows() || Rep::cols() != A.cols())
00686 return false;
00687 typedef LEleType(value_type,T2) lower_type;
00688 for(index_type i=Rep::rows(); i--; ) {
00689 for(index_type j=Rep::cols(); j--; )
00690 if( lower_type(getAt(i,j)) != lower_type(A.getAt(i,j)) )
00691 return false;
00692 }
00693 return true;
00694 }
00699 EXMAT_INLINE2 bool operator!=(const value_type& s) const {
00700 return !(*this == s);
00701 }
00702 friend EXMAT_INLINE2 bool operator!=(const value_type& lhs, const self_type& rhs) {
00703 return rhs != lhs;
00704 }
00709 EXMAT_INLINE2 bool operator==(const value_type& s) const
00710 {
00711 for(index_type i=Rep::rows(); i--; ) {
00712 for(index_type j=Rep::cols(); j--; )
00713 if( getAt(i,j) != s )
00714 return false;
00715 }
00716 return true;
00717 }
00718 friend EXMAT_INLINE2 bool operator==(const value_type& lhs, const self_type& rhs) {
00719 return rhs == lhs;
00720 }
00722
00723
00724
00730 EXMAT_INLINE2 reference setAt(index_type i)
00731 { return Rep::setAt(i); }
00732 EXMAT_INLINE2 const_reference getAt(index_type i) const
00733 { return Rep::getAt(i); }
00734 EXMAT_INLINE2 reference setAt(index_type r, index_type c)
00735 { return Rep::setAt(r, c); }
00736 EXMAT_INLINE2 const_reference getAt(index_type r, index_type c) const
00737 { return Rep::getAt(r, c); }
00739
00740
00741
00742
00743 };
00744
00745
00746
00748 template<class Rep, class ErrChecker> EXMAT_INLINE2 static
00749 const Mat<ExpMat<SubExp<ScalarCon<typename Rep::value_type>, Rep> >, ErrChecker>
00750 operator-(const Mat<Rep, ErrChecker>& mat) {
00751 typedef typename Rep::value_type value_type;
00752
00753 return Mat<ExpMat<SubExp<ScalarCon<value_type>, Rep> >, ErrChecker>(ScalarCon<value_type>(0), mat);
00754 }
00755
00756
00758
00761 template<class Rep, class ErrChecker_=DefaultErrorChecker>
00762 class Vec : public Mat<Rep, ErrChecker_> {
00763 public:
00764 typedef Mat<Rep, ErrChecker_> super_type;
00765 typedef Vec<Rep, ErrChecker_> self_type;
00766 typedef typename Rep::row_type row_type;
00767 typedef typename Rep::const_row_type const_row_type;
00768 typedef typename Rep::col_type col_type;
00769 typedef typename Rep::value_type value_type;
00770 typedef typename Rep::index_type index_type;
00771 typedef typename Rep::reference reference;
00772 typedef typename Rep::const_reference const_reference;
00773 typedef typename Rep::param_type param_type;
00774 typedef typename Rep::const_param_type const_param_type;
00775 typedef ErrChecker_ ErrChecker;
00776 typedef typename Rep::rep_type rep_type;
00777
00778 enum {
00780 IsRowVec = (Rep::ROWS == 1),
00782 IsColVec = (Rep::COLS == 1)
00783 };
00784
00785 public:
00786
00787
00789 EXMAT_INLINE2 Vec() {}
00790
00792
00793 #if defined( EXMAT_VC6 ) || defined( EXMAT_VC7 )
00794
00795
00796 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00797 Vec(Vec<Rep2, ErrChk2>& vec) : super_type(vec) {}
00798 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00799 Vec(const Vec<Rep2, ErrChk2>& vec) : super_type(vec) {}
00800 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00801 Vec(Mat<Rep2, ErrChk2>& vec) : super_type(vec) {}
00802 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00803 Vec(const Mat<Rep2, ErrChk2>& vec) : super_type(vec) {}
00804 template<class Rep2> EXMAT_INLINE2
00805 Vec(ExpMat<Rep2>& A) : super_type(A) {}
00806 template<class Rep2> EXMAT_INLINE2
00807 Vec(const ExpMat<Rep2>& A) : super_type(A) {}
00808 EXMAT_INLINE2 Vec(const std::string& s) : super_type(s) {}
00810 EXMAT_INLINE2 Vec(const Dim& d) : super_type(d) {}
00811 #else
00812 template<typename T1> EXMAT_INLINE2
00813 Vec(T1& t1) : super_type(t1) {}
00814 template<typename T1> EXMAT_INLINE2
00815 Vec(const T1& t1) : super_type(t1) {}
00816
00817
00818
00819
00820 #endif
00821 template<typename T1, typename T2> EXMAT_INLINE2
00822 Vec(const T1& t1, const T2& t2) : super_type(t1, t2) {}
00823 template<typename T1, typename T2, typename T3> EXMAT_INLINE2
00824 Vec(T1& t1, T2& t2, T3& t3) : super_type(t1, t2, t3) {}
00825 template<typename T1, typename T2, typename T3, typename T4> EXMAT_INLINE2
00826 Vec(T1& t1, T2& t2, T3& t3, T4& t4) : super_type(t1, t2, t3, t4) {}
00828
00830 EXMAT_INLINE2 Vec(const_param_type s) : super_type(s) {}
00831
00832
00836
00837 EXMAT_INLINE2 CommaInitializer<self_type> operator=(const_param_type v_) {
00838 return CommaInitializer<self_type>(*this, v_);
00839 }
00841 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00842 Vec& operator=(const Vec<Rep2, ErrChk2>& A) {
00843 ((super_type*)(this))->operator=(A);
00844 return *this;
00845 }
00847 template<class Rep2, class ErrChk2> EXMAT_INLINE2
00848 Vec& operator=(const Mat<Rep2, ErrChk2>& A) {
00849 ((super_type*)(this))->operator=(A);
00850 return *this;
00851 }
00853 EXMAT_INLINE2 Vec& operator=(const self_type& A) {
00854
00855 ((super_type*)(this))->operator=(A);
00856 return *this;
00857 }
00859
00860
00870 EXMAT_INLINE2 reference operator() (index_type i) {
00871 ErrChecker::AssertBounds(index_type(0), index_type(this->size()-1), i);
00872 return setAt(i);
00873 }
00874 EXMAT_INLINE2 const_reference operator() (index_type i) const {
00875 ErrChecker::AssertBounds(index_type(0), index_type(this->size()-1), i);
00876 return getAt(i);
00877 }
00878 EXMAT_INLINE2 reference operator[] (index_type i) {
00879 ErrChecker::AssertBounds(index_type(0), index_type(this->size()-1), i);
00880 return setAt(i);
00881 }
00882 EXMAT_INLINE2 const_reference operator[] (index_type i) const {
00883 ErrChecker::AssertBounds(index_type(0), index_type(this->size()-1), i);
00884 return getAt(i);
00885 }
00887
00888 };
00889
00890
00892 template<class Rep, class ErrChecker> EXMAT_INLINE2 static
00893 const Vec<ExpMat<SubExp<ScalarCon<typename Rep::value_type>, typename Rep::rep_type> >, ErrChecker>
00894 operator-(const Vec<Rep, ErrChecker>& vec) {
00895 typedef typename Rep::value_type value_type;
00896
00897 return Vec<ExpMat<SubExp<ScalarCon<value_type>, TTYPENAME Rep::rep_type> >, ErrChecker>(ScalarCon<value_type>(0), vec);
00898 }
00899
00900 }
00901
00902
00906 #define EXMAT_DERIVEDCLASS_IMP(NAME, MatOrVec) \
00907 public: \
00908 typedef typename super_type::rep_type rep_type; \
00909 typedef typename super_type::ErrChecker ErrChecker; \
00910 typedef typename super_type::value_type value_type; \
00911 EXMAT_INLINE2 NAME(value_type s) : super_type(s) {} \
00912 EXMAT_INLINE2 NAME(const std::string& s) : super_type(s) {} \
00913 template<class Rep2, class EC2> EXMAT_INLINE2 \
00914 NAME(::exmat::MatOrVec<Rep2,EC2>& A) : super_type(A) {} \
00915 template<class Rep2, class EC2> EXMAT_INLINE2 \
00916 NAME(const ::exmat::MatOrVec<Rep2,EC2>& A) : super_type(A) {} \
00917 template<class Rep2> EXMAT_INLINE2 \
00918 NAME(::exmat::ExpMat<Rep2>& A) : super_type(A) {} \
00919 template<class Rep2> EXMAT_INLINE2 \
00920 NAME(const ::exmat::ExpMat<Rep2>& A) : super_type(A) {} \
00921 template<class T1, class T2> EXMAT_INLINE2 \
00922 NAME(const T1& t1, const T2& t2) : super_type(t1, t2) {} \
00923 template<class T1, class T2, class T3> EXMAT_INLINE2 \
00924 NAME(const T1& t1, const T2& t2, const T3& t3) \
00925 : super_type(t1, t2, t3) {} \
00926 template<class T1, class T2, class T3, class T4> EXMAT_INLINE2 \
00927 NAME(const T1& t1, const T2& t2, const T3& t3, const T4& t4) \
00928 : super_type(t1, t2, t3, t4) {} \
00929 private:
00930
00931 #define EXMAT_DERIVEDCLASS_ASSIGNOP(NAME, MatOrVec) \
00932 public: \
00933 template<class Rep2, class EC> EXMAT_INLINE2 \
00934 self_type& operator=(const ::exmat::MatOrVec<Rep2, EC>& v) \
00935 { super_type::operator=(v); return *this; } \
00936 EXMAT_INLINE2 self_type& operator=(value_type s) \
00937 { super_type::operator=(s); return *this; }
00938
00939
00941 #define EXMAT_DERIVEDCLASS_Mak_Op(LT, RT, OT, op, OpName) \
00942 template<class L, class R, class LC, class RC> EXMAT_INLINE2 \
00943 const OT< ::exmat::ExpMat<OpName<typename L::rep_type,typename R::rep_type> >, typename ::exmat::ResultantChecker<LC,RC>::RET> > \
00944 op (const LT<L,LC> >& A, const RT<R,RC> >& B) { \
00945 typedef ::exmat::ExpMat<OpName<TTYPENAME L::rep_type,TTYPENAME R::rep_type> > RETType; \
00946 return RETType(A, B); \
00947 }
00948 #define EXMAT_DERIVEDCLASS_Mak_ScalarOp1(OT, op, OpName) \
00949 template<class L, class ErrChk> EXMAT_INLINE2 \
00950 const OT< ::exmat::ExpMat<OpName<typename L::rep_type,::exmat::ScalarCon<typename L::value_type> > >, ErrChk> > \
00951 op (const OT<L,ErrChk> >& A, typename L::const_param_type scalar) { \
00952 typedef ::exmat::ExpMat<OpName<TTYPENAME L::rep_type,::exmat::ScalarCon<TTYPENAME L::value_type> > > RETType; \
00953 return RETType(A, ::exmat::ScalarCon<TTYPENAME L::value_type>(scalar)); \
00954 }
00955 #define EXMAT_DERIVEDCLASS_Mak_ScalarOp2(OT, op, OpName) \
00956 template<class L, class ErrChk> EXMAT_INLINE2 \
00957 const OT< ::exmat::ExpMat<OpName< ::exmat::ScalarCon<typename L::value_type>, typename L::rep_type> >, ErrChk> > \
00958 op (typename L::const_param_type scalar, const OT<L,ErrChk> >& A) { \
00959 typedef ::exmat::ExpMat<OpName< ::exmat::ScalarCon<TTYPENAME L::value_type>, TTYPENAME L::rep_type> > RETType; \
00960 return RETType(exmat::ScalarCon<TTYPENAME L::value_type>(scalar), A); \
00961 }
00962
00963 #define EXMAT_DERIVEDCLASS_DEFALUTOPS(ClassName, MatOrVec) \
00964 EXMAT_DERIVEDCLASS_Mak_Op(ClassName< ::exmat::MatOrVec, ClassName< ::exmat::MatOrVec, ClassName< ::exmat::MatOrVec, operator+, ::exmat::AddExp); \
00965 EXMAT_DERIVEDCLASS_Mak_ScalarOp1(ClassName< ::exmat::MatOrVec, operator+, ::exmat::AddExp); \
00966 EXMAT_DERIVEDCLASS_Mak_ScalarOp2(ClassName< ::exmat::MatOrVec, operator+, ::exmat::AddExp); \
00967 EXMAT_DERIVEDCLASS_Mak_Op(ClassName< ::exmat::MatOrVec, ClassName< ::exmat::MatOrVec, ClassName< ::exmat::MatOrVec, operator-, ::exmat::SubExp); \
00968 EXMAT_DERIVEDCLASS_Mak_ScalarOp1(ClassName< ::exmat::MatOrVec, operator-, ::exmat::SubExp); \
00969 EXMAT_DERIVEDCLASS_Mak_ScalarOp2(ClassName< ::exmat::MatOrVec, operator-, ::exmat::SubExp); \
00970 EXMAT_DERIVEDCLASS_Mak_ScalarOp1(ClassName< ::exmat::MatOrVec, operator*, ::exmat::ScalarMulExp); \
00971 EXMAT_DERIVEDCLASS_Mak_ScalarOp2(ClassName< ::exmat::MatOrVec, operator*, ::exmat::ScalarMulExp); \
00972 EXMAT_DERIVEDCLASS_Mak_ScalarOp1(ClassName< ::exmat::MatOrVec, operator/, ::exmat::ScalarDivExp); \
00973 EXMAT_DERIVEDCLASS_Mak_ScalarOp2(ClassName< ::exmat::MatOrVec, operator/, ::exmat::ScalarDivExp);
00974
00975
00976 #ifdef _MSC_VER
00977 # pragma warning( pop )
00978 #endif // _MSC_VER
00979
00980
00981 #endif // _EXMAT_MAT_H