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 namespace TooN {
00032
00033 namespace Internal
00034 {
00035
00036
00037
00038
00039 template<int, int, class, int, int, class> struct GenericMBase;
00040
00042
00043
00044
00045 template<int RowStride, int ColStride> struct Slice
00046 {
00047
00048 template<int Rows, int Cols, class Precision> struct MLayout: public GenericMBase<Rows, Cols, Precision, RowStride, ColStride, MatrixSlice<Rows, Cols, Precision> >
00049 {
00050 MLayout(Precision* p, int rows, int cols, int rowstride, int colstride)
00051 :GenericMBase<Rows,Cols,Precision,RowStride,ColStride,MatrixSlice<Rows, Cols, Precision> >(p, rows, cols, rowstride, colstride)
00052 {
00053 }
00054 };
00055 };
00056
00057
00058 template<int Rows, int Cols, bool D = (Rows == Dynamic || Cols == Dynamic)>
00059 struct DiagSize
00060 {
00061 static const int size = Dynamic;
00062 };
00063 template<int Rows, int Cols>
00064 struct DiagSize<Rows, Cols, 0>
00065 {
00066 static const int size = (Rows<Cols?Rows:Cols);
00067 };
00068
00069 template<int Rs, int Cs, bool D = (Rs == Dynamic || Cs == Dynamic)>
00070 struct DiagStride
00071 {
00072 static const int stride = Dynamic;
00073 };
00074 template<int Rs, int Cs>
00075 struct DiagStride<Rs, Cs, 0>
00076 {
00077 static const int stride = Rs + Cs;
00078 };
00079
00080
00081 template<int Rows, int Cols, class Precision, int RowStride, int ColStride, class Mem> struct GenericMBase
00082 : public Mem,
00083 RowStrideHolder<RowStride>,
00084 ColStrideHolder<ColStride>
00085 {
00086
00087 static const int SliceRowStride = RowStride == -2?-1: RowStride;
00088 static const int SliceColStride = ColStride == -2?-1: ColStride;
00089
00090 int rowstride() const {
00091 if(RowStride == -2) {
00092 return num_cols();
00093 } else {
00094 return RowStrideHolder<RowStride>::stride();
00095 }
00096 }
00097
00098 int colstride() const {
00099 if(ColStride == -2) {
00100 return num_rows();
00101 } else {
00102 return ColStrideHolder<ColStride>::stride();
00103 }
00104 }
00105
00106
00107 GenericMBase(){}
00108
00109 GenericMBase(Precision* p)
00110 :Mem(p)
00111 {}
00112
00113
00114 GenericMBase(Precision* p, int r, int c, int rowstride, int colstride)
00115 :Mem(p, r, c),
00116 RowStrideHolder<RowStride>(rowstride),
00117 ColStrideHolder<ColStride>(colstride)
00118 {}
00119
00120 GenericMBase(int r, int c)
00121 :Mem(r, c) {}
00122
00123 template<class Op>
00124 GenericMBase(const Operator<Op>& op)
00125 : Mem(op),
00126 RowStrideHolder<RowStride>(op),
00127 ColStrideHolder<ColStride>(op)
00128 {}
00129
00130 using Mem::my_data;
00131 using Mem::num_cols;
00132 using Mem::num_rows;
00133
00134 Precision& operator()(int r, int c){
00135 Internal::check_index(num_rows(), r);
00136 Internal::check_index(num_cols(), c);
00137 return my_data[r*rowstride() + c*colstride()];
00138 }
00139
00140 const Precision& operator()(int r, int c) const {
00141 Internal::check_index(num_rows(), r);
00142 Internal::check_index(num_cols(), c);
00143 return my_data[r*rowstride() + c*colstride()];
00144 }
00145
00146 Precision& operator[](const std::pair<int, int>& index) {
00147 Internal::check_index(num_rows(), index.first);
00148 Internal::check_index(num_cols(), index.second);
00149 return (*this)(index.first, index.second);
00150 }
00151
00152 const Precision& operator[](const std::pair<int, int>& index) const {
00153 Internal::check_index(num_rows(), index.first);
00154 Internal::check_index(num_cols(), index.second);
00155 return (*this)(index.first, index.second);
00156 }
00157
00158
00159 typedef Vector<Cols, Precision, SliceVBase<SliceColStride> > Vec;
00160 typedef Vector<Cols, const Precision, SliceVBase<SliceColStride> > CVec;
00161
00162 Vec operator[](int r) {
00163 Internal::check_index(num_rows(), r);
00164 return Vec(my_data + rowstride()* r, num_cols(), colstride(), Slicing());
00165 }
00166
00167 const CVec operator[](int r) const {
00168 Internal::check_index(num_rows(), r);
00169 return CVec(my_data + rowstride()* r, num_cols(), colstride(), Slicing());
00170 }
00171
00172
00173
00174 template<int Rstart, int Cstart, int Rlength, int Clength>
00175 Matrix<Rlength, Clength, Precision, Slice<SliceRowStride,SliceColStride> > slice(int rs, int cs, int rl, int cl){
00176 Internal::CheckSlice<Rows, Rstart, Rlength>::check(num_rows(), rs, rl);
00177 Internal::CheckSlice<Cols, Cstart, Clength>::check(num_cols(), cs, cl);
00178
00179
00180
00181 return Matrix<Rlength, Clength, Precision, Slice<SliceRowStride,SliceColStride> >(
00182 my_data+rowstride()*(Rstart==Dynamic?rs:Rstart) + colstride()*(Cstart==Dynamic?cs:Cstart),
00183 Rlength==Dynamic?rl:Rlength,
00184 Clength==Dynamic?cl:Clength,
00185 rowstride(), colstride(), Slicing());
00186 }
00187
00188 template<int Rstart, int Cstart, int Rlength, int Clength>
00189 const Matrix<Rlength, Clength, const Precision, Slice<SliceRowStride,SliceColStride> > slice(int rs, int cs, int rl, int cl) const{
00190 Internal::CheckSlice<Rows, Rstart, Rlength>::check(num_rows(), rs, rl);
00191 Internal::CheckSlice<Cols, Cstart, Clength>::check(num_cols(), cs, cl);
00192
00193
00194
00195 return Matrix<Rlength, Clength, const Precision, Slice<SliceRowStride,SliceColStride> >(
00196 my_data+rowstride()*(Rstart==Dynamic?rs:Rstart) + colstride()*(Cstart==Dynamic?cs:Cstart),
00197 Rlength==Dynamic?rl:Rlength,
00198 Clength==Dynamic?cl:Clength,
00199 rowstride(), colstride(), Slicing());
00200 }
00201
00202
00203 template<int Rstart, int Cstart, int Rlength, int Clength>
00204 Matrix<Rlength, Clength, Precision, Slice<SliceRowStride,SliceColStride> > slice()
00205 {
00206
00207 Internal::CheckSlice<Rows, Rstart, Rlength>::check();
00208 Internal::CheckSlice<Cols, Cstart, Clength>::check();
00209 return slice<Rstart, Cstart, Rlength, Clength>(Rstart, Cstart, Rlength, Clength);
00210 }
00211
00212 template<int Rstart, int Cstart, int Rlength, int Clength>
00213 const Matrix<Rlength, Clength, const Precision, Slice<SliceRowStride,SliceColStride> > slice() const
00214 {
00215 Internal::CheckSlice<Rows, Rstart, Rlength>::check();
00216 Internal::CheckSlice<Cols, Cstart, Clength>::check();
00217 return slice<Rstart, Cstart, Rlength, Clength>(Rstart, Cstart, Rlength, Clength);
00218 }
00219
00220 Matrix<-1, -1, Precision, Slice<SliceRowStride,SliceColStride> > slice(int rs, int cs, int rl, int cl){
00221 return slice<Dynamic, Dynamic, Dynamic, Dynamic>(rs, cs, rl, cl);
00222 }
00223
00224 const Matrix<-1, -1, const Precision, Slice<SliceRowStride,SliceColStride> > slice(int rs, int cs, int rl, int cl) const {
00225 return slice<Dynamic, Dynamic, Dynamic, Dynamic>(rs, cs, rl, cl);
00226 }
00227
00228
00229 Matrix<Cols, Rows, Precision, Slice<SliceColStride,SliceRowStride> > T(){
00230 return Matrix<Cols, Rows, Precision, Slice<SliceColStride,SliceRowStride> >(my_data, num_cols(), num_rows(), colstride(), rowstride(), Slicing());
00231 }
00232
00233 const Matrix<Cols, Rows, const Precision, Slice<SliceColStride,SliceRowStride> > T() const{
00234 return Matrix<Cols, Rows, const Precision, Slice<SliceColStride,SliceRowStride> >(my_data, num_cols(), num_rows(), colstride(), rowstride(), Slicing());
00235 }
00236
00237 static const int DiagSize = Internal::DiagSize<Rows, Cols>::size;
00238 static const int DiagStride = Internal::DiagStride<SliceRowStride, SliceColStride>::stride;
00239
00240 Vector<DiagSize, Precision, SliceVBase<DiagStride> > diagonal_slice()
00241 {
00242 return Vector<DiagSize, Precision, SliceVBase<DiagStride> >(my_data, std::min(num_cols(), num_rows()), rowstride() + colstride(), Slicing());
00243 }
00244
00245 Vector<DiagSize, const Precision, SliceVBase<DiagStride> > diagonal_slice() const
00246 {
00247 return Vector<DiagSize, const Precision, SliceVBase<DiagStride> >(my_data, std::min(num_cols(), num_rows()), rowstride() + colstride(), Slicing());
00248 }
00249 };
00250
00251 }
00252
00254
00255
00256
00257
00258 struct RowMajor
00259 {
00260 template<int Rows, int Cols, class Precision> struct MLayout: public Internal::GenericMBase<Rows, Cols, Precision, (Cols==-1?-2:Cols), 1, Internal::MatrixAlloc<Rows, Cols, Precision> >
00261 {
00262
00263
00264 MLayout(){}
00265
00266 MLayout(int rows, int cols)
00267 :Internal::GenericMBase<Rows, Cols, Precision, (Cols == -1 ? -2 : Cols), 1, Internal::MatrixAlloc<Rows, Cols, Precision> >(rows, cols)
00268 {}
00269
00270 template<class Op>
00271 MLayout(const Operator<Op>& op)
00272 :Internal::GenericMBase<Rows, Cols, Precision, (Cols == -1 ? -2 : Cols), 1, Internal::MatrixAlloc<Rows, Cols, Precision> >(op)
00273 {}
00274
00275 };
00276 };
00277
00278 struct ColMajor
00279 {
00280 template<int Rows, int Cols, class Precision> struct MLayout: public Internal::GenericMBase<Rows, Cols, Precision, 1, (Rows==-1?-2:Rows), Internal::MatrixAlloc<Rows, Cols, Precision> >
00281 {
00282
00283
00284 MLayout(){}
00285
00286 MLayout(int rows, int cols)
00287 :Internal::GenericMBase<Rows, Cols, Precision, 1, (Rows == -1 ? -2 : Rows), Internal::MatrixAlloc<Rows, Cols, Precision> >(rows, cols)
00288 {}
00289
00290 template<class Op>
00291 MLayout(const Operator<Op>& op)
00292 :Internal::GenericMBase<Rows, Cols, Precision, 1, (Rows == -1 ? -2 : Rows), Internal::MatrixAlloc<Rows, Cols, Precision> >(op)
00293 {}
00294
00295 };
00296 };
00297
00298 }
00299