TooN: internal/mbase.hh Source File

TooN 2.0.0-beta8

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List

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
    00041 ////////////////////////////////////////////////////////////////////////////////
    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         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     // this is the type of vector obtained by [ ]
    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     //Generic matrix slicing
    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         //Always pass the size and stride as a run-time parameter. It will be ignored
    00180         //by SliceHolder (above) if it is statically determined.
    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         //Always pass the size and stride as a run-time parameter. It will be ignored
    00194         //by SliceHolder (above) if it is statically determined.
    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     //Special cases of slicing
    00203     template<int Rstart, int Cstart, int Rlength, int Clength>
    00204     Matrix<Rlength, Clength, Precision, Slice<SliceRowStride,SliceColStride> > slice()
    00205     {
    00206         //Extra checking in the static case
    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     //Other slice related functions.
    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
    00253 ////////////////////////////////////////////////////////////////////////////////
    00254 //
    00255 // Classes for Matrices owning memory
    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         //Optional constructors.
    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         //Optional constructors.
    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