TooN 2.1
|
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 00032 00033 namespace TooN { 00034 00035 namespace Internal 00036 { 00037 //Dummy struct for Diagonal operator 00038 template<int Size, typename Precision, typename Base> 00039 struct DiagMatrixOp; 00040 } 00041 00042 template<int Size, typename Precision, typename Base> 00043 struct Operator<Internal::DiagMatrixOp<Size, Precision, Base> > 00044 { 00045 public: 00046 ///@name Constructors 00047 ///@{ 00048 00049 00050 inline Operator() {} 00051 inline Operator(int size_in) : my_vector(size_in) {} 00052 inline Operator(Precision* data) : my_vector(data) {} 00053 inline Operator(Precision* data, int size_in) : my_vector(data,size_in) {} 00054 inline Operator(Precision* data_in, int size_in, int stride_in, Internal::Slicing) 00055 : my_vector(data_in, size_in, stride_in, Internal::Slicing() ) {} 00056 00057 // constructors to allow return value optimisations 00058 // construction from 0-ary operator 00059 ///my_vector constructed from a TooN::Operator 00060 template <class Op> 00061 inline Operator(const Operator<Op>& op) 00062 : my_vector (op) 00063 { 00064 op.eval(my_vector); 00065 } 00066 00067 // constructor from arbitrary vector 00068 template<int Size2, typename Precision2, typename Base2> 00069 inline Operator(const Vector<Size2,Precision2,Base2>& from) 00070 : my_vector(from.size()) 00071 { 00072 my_vector=from; 00073 } 00074 ///@} 00075 00076 00077 ///@name Operator members 00078 ///@{ 00079 template<int R, int C, class P, class B> 00080 void eval(Matrix<R,C,P,B>& m) const { 00081 SizeMismatch<Size, Size>::test(m.num_rows(), m.num_cols()); 00082 m = Zeros; 00083 m.diagonal_slice() = my_vector; 00084 } 00085 00086 ///The vector used to hold the leading diagonal. 00087 Vector<Size,Precision,Base> my_vector; 00088 }; 00089 00090 /** 00091 @class DiagonalMatrix 00092 A diagonal matrix 00093 00094 Support is limited but diagonal matrices can be multiplied by vectors, matrices 00095 or diagonal matrices on either side. 00096 00097 Diagonal matrices can be created from vectors by using the <code> as_diagonal() 00098 </code> member function: 00099 00100 @code 00101 Vector<3> v = makeVector(1,2,3); 00102 Vector<3> v2 = v.as_diagonal() * v; // v2 = (1,4,9) 00103 @endcode 00104 00105 A vector can be obtained from the diagonal matrix by using the 00106 <code> diagonal_slice() </code> member function. 00107 @ingroup gLinAlg 00108 **/ 00109 template<int Size=Dynamic, typename Precision=DefaultPrecision, typename Base=Internal::VBase> 00110 struct DiagonalMatrix: public Operator<Internal::DiagMatrixOp<Size, Precision, Base> > { 00111 public: 00112 ///@name Constructors 00113 ///@{ 00114 00115 inline DiagonalMatrix() {} 00116 inline DiagonalMatrix(int size_in) : Operator<Internal::DiagMatrixOp<Size, Precision, Base> >(size_in) {} 00117 inline DiagonalMatrix(Precision* data) : Operator<Internal::DiagMatrixOp<Size, Precision, Base> >(data) {} 00118 inline DiagonalMatrix(Precision* data, int size_in) : Operator<Internal::DiagMatrixOp<Size, Precision, Base> >(data,size_in) {} 00119 inline DiagonalMatrix(Precision* data_in, int size_in, int stride_in, Internal::Slicing) 00120 : Operator<Internal::DiagMatrixOp<Size, Precision, Base> >(data_in, size_in, stride_in, Internal::Slicing() ) {} 00121 00122 // constructors to allow return value optimisations 00123 // construction from 0-ary operator 00124 ///my_vector constructed from a TooN::Operator 00125 template <class Op> 00126 inline DiagonalMatrix(const Operator<Op>& op) 00127 : Operator<Internal::DiagMatrixOp<Size, Precision, Base> > (op) 00128 { 00129 op.eval(this->my_vector); 00130 } 00131 00132 // constructor from arbitrary vector 00133 template<int Size2, typename Precision2, typename Base2> 00134 inline DiagonalMatrix(const Vector<Size2,Precision2,Base2>& from) 00135 : Operator<Internal::DiagMatrixOp<Size, Precision, Base> >(from.size()) 00136 { 00137 this->my_vector=from; 00138 } 00139 ///@} 00140 00141 00142 00143 ///Index the leading elements on the diagonal 00144 Precision& operator[](int i){return this->my_vector[i];} 00145 ///Index the leading elements on the diagonal 00146 const Precision& operator[](int i) const {return this->my_vector[i];} 00147 00148 ///Return the leading diagonal as a vector. 00149 typename Vector<Size, Precision, Base>::as_slice_type diagonal_slice() { 00150 return this->my_vector.as_slice(); 00151 } 00152 00153 ///Return the leading diagonal as a vector. 00154 const typename Vector<Size, Precision, Base>::as_slice_type diagonal_slice() const { 00155 return this->my_vector.as_slice(); 00156 } 00157 00158 DiagonalMatrix<Size, Precision> operator-() const 00159 { 00160 return -this->my_vector; 00161 } 00162 }; 00163 00164 00165 template<int S1, typename P1, typename B1, int S2, typename P2, typename B2> 00166 inline Vector<Internal::Sizer<S1,S2>::size, typename Internal::MultiplyType<P1,P2>::type> 00167 operator*(const DiagonalMatrix<S1,P1,B1>& d, const Vector<S2,P2,B2>& v){ 00168 return diagmult(d.my_vector,v); 00169 } 00170 00171 template<int S1, typename P1, typename B1, int S2, typename P2, typename B2> 00172 inline Vector<Internal::Sizer<S1,S2>::size, typename Internal::MultiplyType<P1,P2>::type> 00173 operator*( const Vector<S1,P1,B1>& v, const DiagonalMatrix<S2,P2,B2>& d){ 00174 return diagmult(v,d.my_vector); 00175 } 00176 00177 // perhaps not the safest way to do this as we're returning the same operator used to normally make vectors 00178 template<int S1, typename P1, typename B1, int S2, typename P2, typename B2> 00179 inline DiagonalMatrix<Internal::Sizer<S1,S2>::size, typename Internal::MultiplyType<P1,P2>::type> 00180 operator*( const DiagonalMatrix<S1,P1,B1>& d1, const DiagonalMatrix<S2,P2,B2>& d2){ 00181 SizeMismatch<S1,S2>::test(d1.my_vector.size(),d2.my_vector.size()); 00182 return Operator<Internal::VPairwise<Internal::Multiply,S1,P1,B1,S2,P2,B2> >(d1.my_vector,d2.my_vector); 00183 } 00184 00185 template<int R, int C, int Size, typename P1, typename P2, typename B1, typename B2> 00186 Matrix<R, C, typename Internal::MultiplyType<P1,P2>::type> 00187 operator* (const Matrix<R, C, P1, B1>& m, const DiagonalMatrix<Size, P2, B2>& d){ 00188 return diagmult(m,d.my_vector); 00189 } 00190 00191 template<int R, int C, typename P1, typename B1, int Size, typename P2, typename B2> 00192 Matrix<R, C, typename Internal::MultiplyType<P1,P2>::type> 00193 operator* (const DiagonalMatrix<Size,P1,B1>& d, const Matrix<R,C,P2,B2>& m) 00194 { 00195 return diagmult(d.my_vector, m); 00196 } 00197 00198 }