00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifndef LASS_GUARDIAN_OF_INCLUSION_NUM_IMPL_MATRIX_EXPRESSIONS_H
00046 #define LASS_GUARDIAN_OF_INCLUSION_NUM_IMPL_MATRIX_EXPRESSIONS_H
00047
00048 #include "../num_common.h"
00049
00050 namespace lass
00051 {
00052 namespace num
00053 {
00054 namespace impl
00055 {
00056
00057
00058
00059 template <typename T>
00060 class MStorage
00061 {
00062 public:
00063 enum { lvalue = true };
00064 typedef typename util::CallTraits<T>::TValue TValue;
00065 typedef typename util::CallTraits<T>::TParam TParam;
00066 typedef typename util::CallTraits<T>::TReference TReference;
00067 typedef typename util::CallTraits<T>::TConstReference TConstReference;
00068 typedef size_t TSize;
00069
00070 MStorage(): storage_(), rows_(0), cols_(0) {}
00071 MStorage(TSize iRows, TSize iCols): storage_(iRows * iCols, T()), rows_(iRows), cols_(iCols) {}
00072 TConstReference operator()(TSize iI, TSize iJ) const { return storage_[iI * cols_ + iJ]; }
00073 TReference operator()(TSize iI, TSize iJ) { return storage_[iI * cols_ + iJ]; }
00074 TSize rows() const { return rows_; }
00075 TSize columns() const { return cols_; }
00076
00077
00078
00079 void resize(TSize iRows, TSize iCols)
00080 {
00081 storage_.resize(iRows * iCols, T());
00082 rows_ = iRows;
00083 cols_ = iCols;
00084 }
00085 void swap(MStorage<T>& iOther)
00086 {
00087 storage_.swap(iOther.storage_);
00088 std::swap(rows_, iOther.rows_);
00089 std::swap(cols_, iOther.cols_);
00090 }
00091
00092 typename std::vector<T>::iterator rowMajor() { return storage_.begin(); }
00093 typename std::vector<T>::const_iterator rowMajor() const { return storage_.begin(); }
00094
00095 private:
00096 std::vector<T> storage_;
00097 TSize rows_;
00098 TSize cols_;
00099 };
00100
00101
00102
00103 template <typename T>
00104 class MScalar
00105 {
00106 public:
00107 enum { lvalue = false };
00108 typedef typename util::CallTraits<T>::TValue TValue;
00109 typedef typename util::CallTraits<T>::TParam TParam;
00110 typedef size_t TSize;
00111
00112 MScalar(TParam iValue, TSize iRows, TSize iCols): value_(iValue), rows_(iRows), cols_(iCols) {}
00113 TParam operator()(TSize iI, TSize iJ) const
00114 {
00115 LASS_ASSERT(iI < rows_ && iJ < cols_);
00116 return value_;
00117 }
00118 TSize rows() const { return rows_; }
00119 TSize columns() const { return cols_; }
00120 private:
00121 TValue value_;
00122 TSize rows_;
00123 TSize cols_;
00124 };
00125
00126
00127
00128 template <typename ExpressionType>
00129 struct MatrixExpressionTraits
00130 {
00131 typedef const ExpressionType& TStorage;
00132 };
00133
00134 template <typename T>
00135 struct MatrixExpressionTraits<MScalar<T> >
00136 {
00137 typedef MScalar<T> TStorage;
00138 };
00139
00140
00141
00142 #define LASS_NUM_MATRIX_BINARY_EXPRESSION(i_name, c_operator)\
00143 template <typename T, typename Operand1, typename Operand2>\
00144 class LASS_CONCATENATE(M, i_name)\
00145 {\
00146 public:\
00147 enum { lvalue = false };\
00148 typedef typename util::CallTraits<T>::TValue TValue;\
00149 typedef size_t TSize;\
00150 LASS_CONCATENATE(M, i_name)(const Operand1& iA, const Operand2& iB):\
00151 operand1_(iA), operand2_(iB)\
00152 {\
00153 LASS_ASSERT(operand1_.rows() == operand2_.rows() &&\
00154 operand1_.columns() == operand2_.columns());\
00155 }\
00156 TValue operator()(TSize iI, TSize iJ) const\
00157 {\
00158 return operand1_(iI, iJ) c_operator operand2_(iI, iJ);\
00159 }\
00160 TSize rows() const { return operand1_.rows(); }\
00161 TSize columns() const { return operand1_.columns(); }\
00162 private:\
00163 typename MatrixExpressionTraits<Operand1>::TStorage operand1_;\
00164 typename MatrixExpressionTraits<Operand2>::TStorage operand2_;\
00165 }
00166
00167 LASS_NUM_MATRIX_BINARY_EXPRESSION(Add, +);
00168 LASS_NUM_MATRIX_BINARY_EXPRESSION(Sub, -);
00169 LASS_NUM_MATRIX_BINARY_EXPRESSION(Mul, *);
00170
00171
00172
00173 #define LASS_NUM_MATRIX_UNARY_EXPRESSION(i_name, c_operator)\
00174 template <typename T, typename Operand1>\
00175 class LASS_CONCATENATE(M, i_name)\
00176 {\
00177 public:\
00178 enum { lvalue = false };\
00179 typedef typename util::CallTraits<T>::TValue TValue;\
00180 typedef size_t TSize;\
00181 LASS_CONCATENATE(M, i_name)(const Operand1& iA):\
00182 operand1_(iA)\
00183 {\
00184 }\
00185 TValue operator()(TSize iRow, TSize iCol) const\
00186 {\
00187 return c_operator operand1_(iRow, iCol);\
00188 }\
00189 TSize rows() const { return operand1_.rows(); }\
00190 TSize columns() const { return operand1_.columns(); }\
00191 private:\
00192 typename MatrixExpressionTraits<Operand1>::TStorage operand1_;\
00193 }
00194
00195 LASS_NUM_MATRIX_UNARY_EXPRESSION(Neg, -);
00196 LASS_NUM_MATRIX_UNARY_EXPRESSION(Rec, ::lass::num::NumTraits<T>::one /);
00197
00198
00199
00200
00201
00202
00203 template <typename T, typename Operand1, typename Operand2>
00204 class MProd
00205 {
00206 public:
00207 enum { lvalue = false };
00208 typedef typename util::CallTraits<T>::TValue TValue;
00209 typedef size_t TSize;
00210 MProd(const Operand1& iA, const Operand2& iB):
00211 operand1_(iA), operand2_(iB), loopSize_(iA.columns())
00212 {
00213 LASS_ASSERT(operand1_.columns() == operand2_.rows());
00214 }
00215 TValue operator()(TSize iI, TSize iJ) const
00216 {
00217 TValue result = TValue();
00218 for (TSize k = 0; k < loopSize_; ++k)
00219 {
00220 result += operand1_(iI, k) * operand2_(k, iJ);
00221 }
00222 return result;
00223 }
00224 TSize rows() const { return operand1_.rows(); }
00225 TSize columns() const { return operand2_.columns(); }
00226 private:
00227 typename MatrixExpressionTraits<Operand1>::TStorage operand1_;
00228 typename MatrixExpressionTraits<Operand2>::TStorage operand2_;
00229 TSize loopSize_;
00230 };
00231
00232
00233
00234
00235
00236 template <typename T, typename Operand1>
00237 class MTrans
00238 {
00239 public:
00240 enum { lvalue = false };
00241 typedef typename util::CallTraits<T>::TParam TParam;
00242 typedef size_t TSize;
00243 MTrans(const Operand1& iA): operand1_(iA) {}
00244 TParam operator()(TSize iI, TSize iJ) const { return operand1_(iJ, iI);
00245 }
00246 TSize rows() const { return operand1_.columns(); }
00247 TSize columns() const { return operand1_.rows(); }
00248 private:
00249 typename MatrixExpressionTraits<Operand1>::TStorage operand1_;
00250 };
00251
00252
00253
00254
00255
00256
00257 template <typename T, typename Operand1>
00258 class MFun
00259 {
00260 public:
00261 enum { lvalue = false };
00262 typedef T (*TOperator)(T);
00263 typedef typename util::CallTraits<T>::TValue TValue;
00264 typedef size_t TSize;
00265 MFun(const Operand1& iA, TOperator iOperator): operand1_(iA),
00266 operator_(iOperator) {}
00267 TValue operator()(TSize iI, TSize iJ) const { return
00268 operator_(operand1_(iI, iJ)); }
00269 TSize rows() const { return operand1_.rows(); }\
00270 TSize columns() const { return operand1_.columns(); }\
00271 private:
00272 typename MatrixExpressionTraits<Operand1>::TStorage operand1_;
00273 TOperator operator_;
00274 };
00275
00276
00277
00278 }
00279
00280 }
00281
00282 }
00283
00284 #endif
00285
00286