internal/matrix.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 template <int Rows=-1, int Cols=Rows, class Precision=DefaultPrecision, class Layout = RowMajor>
00034 struct Matrix : public Layout::template MLayout<Rows, Cols, Precision>
00035 {
00036 public:
00037 
00038     using Layout::template MLayout<Rows, Cols, Precision>::my_data;
00039     using Layout::template MLayout<Rows, Cols, Precision>::num_rows;
00040     using Layout::template MLayout<Rows, Cols, Precision>::num_cols;
00041 
00042     //Use Tom's sneaky constructor hack...
00043     Matrix(){}
00044 
00045     Matrix(int rows, int cols) :
00046         Layout::template MLayout<Rows,Cols,Precision>(rows, cols)
00047     {}
00048 
00049     Matrix(Precision* p) :
00050         Layout::template MLayout<Rows, Cols, Precision>(p)
00051     {}
00052 
00053     Matrix(Precision* p, int r, int c) :
00054         Layout::template MLayout<Rows, Cols, Precision>(p, r, c)
00055     {}
00056 
00057     // Internal constructor used by GenericMBase::slice(...)
00058     Matrix(Precision* data, int rows, int cols, int rowstride, int colstride, Internal::Slicing)
00059     :Layout::template MLayout<Rows, Cols, Precision>(data, rows, cols, rowstride, colstride){}
00060 
00061     //See vector.hh and allocator.hh for details about why the
00062     //copy constructor should be default.
00063     template <class Op>
00064     inline Matrix(const Operator<Op>& op)
00065         :Layout::template MLayout<Rows,Cols,Precision>(op)
00066     {
00067         op.eval(*this);
00068     }
00069 
00070     // constructors to allow return value optimisations
00071     // construction from 1-ary operator
00072     template <class T, class Op>
00073     inline Matrix(const T& arg, int rows, int cols, const Operator<Op>&) 
00074     :Layout::template MLayout<Rows,Cols,Precision>(rows, cols) 
00075     {
00076         Op::eval(*this,arg);
00077     }
00078 
00079     // constructor from 2-ary operator
00080     template <class LHS, class RHS, class Op>
00081     inline Matrix(const LHS& lhs, const RHS& rhs, int rows, int cols, const Operator<Op>&)
00082     :Layout::template MLayout<Rows,Cols,Precision>(rows, cols)
00083     {
00084         Op::eval(*this,lhs,rhs);
00085     }
00086 
00087     // constructor from arbitrary matrix
00088     template<int Rows2, int Cols2, typename Precision2, typename Base2>
00089     inline Matrix(const Matrix<Rows2, Cols2,Precision2,Base2>& from)
00090     :Layout::template MLayout<Rows,Cols,Precision>(from.num_rows(), from.num_cols())
00091     {
00092         operator=(from);
00093     }
00094 
00095     // operator = from copy
00096     inline Matrix& operator= (const Matrix& from)
00097     {
00098         SizeMismatch<Rows, Rows>::test(num_rows(), from.num_rows());
00099         SizeMismatch<Cols, Cols>::test(num_cols(), from.num_cols());
00100 
00101         for(int r=0; r < num_rows(); r++)
00102           for(int c=0; c < num_cols(); c++)
00103             (*this)[r][c] = from[r][c];
00104 
00105         return *this;
00106     }
00107 
00108     // operator = 0-ary operator
00109     template<class Op> inline Matrix& operator= (const Operator<Op>& op)
00110     {
00111         op.eval(*this);
00112         return *this;
00113     }
00114 
00115     // operator =
00116     template<int Rows2, int Cols2, typename Precision2, typename Base2>
00117     Matrix& operator= (const Matrix<Rows2, Cols2, Precision2, Base2>& from)
00118     {
00119         SizeMismatch<Rows, Rows2>::test(num_rows(), from.num_rows());
00120         SizeMismatch<Cols, Cols2>::test(num_cols(), from.num_cols());
00121 
00122         for(int r=0; r < num_rows(); r++)
00123           for(int c=0; c < num_cols(); c++)
00124             (*this)[r][c] = from[r][c];
00125 
00126         return *this;
00127     }
00128 
00129     Matrix& operator*=(const Precision& rhs)
00130     {
00131           for(int r=0; r < num_rows(); r++)
00132               for(int c=0; c < num_cols(); c++)
00133                 (*this)[r][c] *= rhs;
00134 
00135           return *this;
00136     }
00137 
00138     Matrix& operator/=(const Precision& rhs)
00139     {
00140           for(int r=0; r < num_rows(); r++)
00141               for(int c=0; c < num_cols(); c++)
00142                 (*this)[r][c] /= rhs;
00143 
00144           return *this;
00145     }
00146 
00147     template<int Rows2, int Cols2, typename Precision2, typename Base2>
00148     Matrix& operator+= (const Matrix<Rows2, Cols2, Precision2, Base2>& from)
00149     {
00150         SizeMismatch<Rows, Rows2>::test(num_rows(), from.num_rows());
00151         SizeMismatch<Cols, Cols2>::test(num_cols(), from.num_cols());
00152 
00153         for(int r=0; r < num_rows(); r++)
00154           for(int c=0; c < num_cols(); c++)
00155             (*this)[r][c] += from[r][c];
00156 
00157         return *this;
00158     }
00159 
00160     template<class Op>
00161     Matrix& operator+=(const Operator<Op>& op)
00162     {
00163         op.plusequals(*this);
00164         return *this;
00165     }
00166 
00167     template<class Op>
00168     Matrix& operator-=(const Operator<Op>& op)
00169     {
00170         op.minusequals(*this);
00171         return *this;
00172     }
00173 
00174     template<int Rows2, int Cols2, typename Precision2, typename Base2>
00175     Matrix& operator-= (const Matrix<Rows2, Cols2, Precision2, Base2>& from)
00176     {
00177         SizeMismatch<Rows, Rows2>::test(num_rows(), from.num_rows());
00178         SizeMismatch<Cols, Cols2>::test(num_cols(), from.num_cols());
00179 
00180         for(int r=0; r < num_rows(); r++)
00181           for(int c=0; c < num_cols(); c++)
00182             (*this)[r][c] -= from[r][c];
00183 
00184         return *this;
00185     }
00186 
00187     template<int Rows2, int Cols2, typename Precision2, typename Base2>
00188     bool operator== (const Matrix<Rows2, Cols2, Precision2, Base2>& rhs)
00189     {
00190         SizeMismatch<Rows, Rows2>::test(num_rows(), rhs.num_rows());
00191         SizeMismatch<Cols, Cols2>::test(num_cols(), rhs.num_cols());
00192 
00193         for(int r=0; r < num_rows(); r++)
00194           for(int c=0; c < num_cols(); c++)
00195             if((*this)[r][c] != rhs[r][c])
00196               return 0;
00197         return 1;
00198     }
00199 
00200     template<int Rows2, int Cols2, typename Precision2, typename Base2>
00201     bool operator!= (const Matrix<Rows2, Cols2, Precision2, Base2>& rhs)
00202     {
00203         SizeMismatch<Rows, Rows2>::test(num_rows(), rhs.num_rows());
00204         SizeMismatch<Cols, Cols2>::test(num_cols(), rhs.num_cols());
00205 
00206         for(int r=0; r < num_rows(); r++)
00207           for(int c=0; c < num_cols(); c++)
00208             if((*this)[r][c] != rhs[r][c])
00209               return 1;
00210         return 0;
00211     }
00212 
00213 
00214     Matrix& ref()
00215     {
00216         return *this;
00217     }
00218 };
00219 
00220 }

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