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 return my_data[r*rowstride() + c*colstride()];
00136 }
00137
00138 const Precision& operator()(int r, int c) const {
00139 return my_data[r*rowstride() + c*colstride()];
00140 }
00141
00142
00143 typedef Vector<Cols, Precision, SliceVBase<SliceColStride> > Vec;
00144
00145 Vec operator[](int r) {
00146 Internal::check_index(num_rows(), r);
00147 return Vec(my_data + rowstride()* r, num_cols(), colstride(), Slicing());
00148 }
00149
00150 const Vec operator[](int r) const {
00151 Internal::check_index(num_rows(), r);
00152 return Vec(const_cast<Precision*>(my_data + rowstride()* r), num_cols(), colstride(), Slicing());
00153 }
00154
00155
00156
00157 template<int Rstart, int Cstart, int Rlength, int Clength>
00158 Matrix<Rlength, Clength, Precision, Slice<SliceRowStride,SliceColStride> > slice()
00159 {
00160
00161
00162 Internal::CheckStaticSlice<Rows, Rstart, Rlength>::check(num_rows());
00163 Internal::CheckStaticSlice<Cols, Cstart, Clength>::check(num_cols());
00164 return Matrix<Rlength, Clength, Precision, Slice<SliceRowStride,SliceColStride> >(my_data+rowstride()*Rstart + colstride()*Cstart, Rlength, Clength, rowstride(), colstride(), Slicing());
00165 }
00166
00167 template<int Rstart, int Cstart, int Rlength, int Clength>
00168 const Matrix<Rlength, Clength, Precision, Slice<SliceRowStride,SliceColStride> > slice() const
00169 {
00170 Internal::CheckStaticSlice<Rows, Rstart, Rlength>::check(num_rows());
00171 Internal::CheckStaticSlice<Cols, Cstart, Clength>::check(num_cols());
00172 return Matrix<Rlength, Clength, Precision, Slice<SliceRowStride,SliceColStride> >(const_cast<Precision*>(my_data+rowstride()*Rstart + colstride()*Cstart), Rlength, Clength, rowstride(), colstride(), Slicing());
00173 }
00174
00175 Matrix<-1, -1, Precision, Slice<SliceRowStride,SliceColStride> > slice(int rs, int cs, int rl, int cl){
00176 Internal::CheckDynamicSlice::check(num_rows(), rs, rl);
00177 Internal::CheckDynamicSlice::check(num_cols(), cs, cl);
00178 return Matrix<-1, -1, Precision, Slice<SliceRowStride,SliceColStride> >(my_data+rowstride()*rs +colstride()*cs, rl, cl, rowstride(), colstride(), Slicing());
00179 }
00180
00181 const Matrix<-1, -1, Precision, Slice<SliceRowStride,SliceColStride> > slice(int rs, int cs, int rl, int cl) const {
00182 Internal::CheckDynamicSlice::check(num_rows(), rs, rl);
00183 Internal::CheckDynamicSlice::check(num_cols(), cs, cl);
00184 return Matrix<-1, -1, Precision, Slice<SliceRowStride,SliceColStride> >(const_cast<Precision*>(my_data+rowstride()*rs +colstride()*cs), rl, cl, rowstride(), colstride(), Slicing());
00185 }
00186
00187
00188 Matrix<Cols, Rows, Precision, Slice<SliceColStride,SliceRowStride> > T(){
00189 return Matrix<Cols, Rows, Precision, Slice<SliceColStride,SliceRowStride> >(my_data, num_cols(), num_rows(), colstride(), rowstride(), Slicing());
00190 }
00191
00192 const Matrix<Cols, Rows, Precision, Slice<SliceColStride,SliceRowStride> > T() const{
00193 return Matrix<Cols, Rows, Precision, Slice<SliceColStride,SliceRowStride> >(const_cast<Precision*>(my_data), num_cols(), num_rows(), colstride(), rowstride(), Slicing());
00194 }
00195
00196 static const int DiagSize = Internal::DiagSize<Rows, Cols>::size;
00197 static const int DiagStride = Internal::DiagStride<SliceRowStride, SliceColStride>::stride;
00198
00199 Vector<DiagSize, Precision, SliceVBase<DiagStride> > diagonal_slice()
00200 {
00201 return Vector<DiagSize, Precision, SliceVBase<DiagStride> >(my_data, std::min(num_cols(), num_rows()), rowstride() + colstride(), Slicing());
00202 }
00203 };
00204
00205 }
00206
00208
00209
00210
00211
00212 struct RowMajor
00213 {
00214 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> >
00215 {
00216
00217
00218 MLayout(){}
00219
00220 MLayout(int rows, int cols)
00221 :Internal::GenericMBase<Rows, Cols, Precision, (Cols == -1 ? -2 : Cols), 1, Internal::MatrixAlloc<Rows, Cols, Precision> >(rows, cols)
00222 {}
00223
00224 template<class Op>
00225 MLayout(const Operator<Op>& op)
00226 :Internal::GenericMBase<Rows, Cols, Precision, (Cols == -1 ? -2 : Cols), 1, Internal::MatrixAlloc<Rows, Cols, Precision> >(op)
00227 {}
00228
00229 };
00230 };
00231
00232 struct ColMajor
00233 {
00234 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> >
00235 {
00236
00237
00238 MLayout(){}
00239
00240 MLayout(int rows, int cols)
00241 :Internal::GenericMBase<Rows, Cols, Precision, 1, (Rows == -1 ? -2 : Rows), Internal::MatrixAlloc<Rows, Cols, Precision> >(rows, cols)
00242 {}
00243
00244 template<class Op>
00245 MLayout(const Operator<Op>& op)
00246 :Internal::GenericMBase<Rows, Cols, Precision, 1, (Rows == -1 ? -2 : Rows), Internal::MatrixAlloc<Rows, Cols, Precision> >(op)
00247 {}
00248
00249 };
00250 };
00251
00252 }
00253