internal/mbase.hh

00001 // -*- c++ -*-
00002 
00003 // Copyright (C) 2009 Tom Drummond (twd20@cam.ac.uk),
00004 // Ed Rosten (er258@cam.ac.uk)
00005 //
00006 // This file is part of the TooN Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 namespace TooN {
00032 
00033 namespace Internal
00034 {
00035 // As usual, a positive integer means static and -1 means dynamic.
00036 // The new case is that for strides, -2 means that the stride is 
00037 // the same as num_cols/num_rows, which must be dynamically sized.
00038 
00039 template<int, int, class, int, int, class> struct GenericMBase;
00040 
00042 //Closure used to acquire strides
00043 //-1 means dynamic stride
00044 //-2 means dynamic stride is tied to size for a normal matrix
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     //Slices can never have tied strides
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) { //Normal tied stride
00092             return num_cols();
00093         } else {
00094             return RowStrideHolder<RowStride>::stride();
00095         }
00096     }
00097 
00098     int colstride() const {
00099         if(ColStride == -2) { //Normal tied stride
00100             return num_rows();
00101         } else {
00102             return ColStrideHolder<ColStride>::stride();
00103         }
00104     }
00105 
00106     //Optional constructors
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     // this is the type of vector obtained by [ ]
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         //Always pass the size and stride as a run-time parameter. It will be ignored
00161         //by SliceHolder (above) if it is statically determined.
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 // Classes for Matrices owning memory
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         //Optional constructors.
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         //Optional constructors.
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 

Generated on Thu May 7 20:28:40 2009 for TooN by  doxygen 1.5.3