TooN 2.0.0-beta8
|
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 00036 /** 00037 @class DiagonalMatrix 00038 A diagonal matrix 00039 00040 Support is limited but diagonal matrices can be multiplied by vectors, matrices 00041 or diagonal matrices on either side. 00042 00043 Diagonal matrices can be created from vectors by using the <code> as_diagonal() 00044 </code> member function: 00045 00046 @code 00047 Vector<3> v = makeVector(1,2,3); 00048 Vector<3> v2 = v.as_diagonal() * v; // v2 = (1,4,9) 00049 @endcode 00050 00051 A vector can be obtained from the diagonal matrix by using the 00052 <code> diagonal_slice() </code> member function. 00053 @ingroup gLinAlg 00054 **/ 00055 template<int Size=Dynamic, typename Precision=DefaultPrecision, typename Base=Internal::VBase> 00056 struct DiagonalMatrix { 00057 public: 00058 ///@name Constructors 00059 ///@{ 00060 00061 inline DiagonalMatrix() {} 00062 inline DiagonalMatrix(int size_in) : my_vector(size_in) {} 00063 inline DiagonalMatrix(Precision* data) : my_vector(data) {} 00064 inline DiagonalMatrix(Precision* data, int size_in) : my_vector(data,size_in) {} 00065 inline DiagonalMatrix(Precision* data_in, int size_in, int stride_in, Internal::Slicing) 00066 : my_vector(data_in, size_in, stride_in, Internal::Slicing() ) {} 00067 00068 // constructors to allow return value optimisations 00069 // construction from 0-ary operator 00070 ///my_vector constructed from a TooN::Operator 00071 template <class Op> 00072 inline DiagonalMatrix(const Operator<Op>& op) 00073 : my_vector (op) 00074 { 00075 op.eval(my_vector); 00076 } 00077 00078 // constructor from arbitrary vector 00079 template<int Size2, typename Precision2, typename Base2> 00080 inline DiagonalMatrix(const Vector<Size2,Precision2,Base2>& from) 00081 : my_vector(from.size()) 00082 { 00083 my_vector=from; 00084 } 00085 ///@} 00086 00087 00088 00089 ///Index the leading elements on the diagonal 00090 Precision& operator[](int i){return my_vector[i];} 00091 ///Index the leading elements on the diagonal 00092 const Precision& operator[](int i) const {return my_vector[i];} 00093 00094 ///Return the leading diagonal as a vector. 00095 typename Vector<Size, Precision, Base>::as_slice_type diagonal_slice() { 00096 return my_vector.as_slice(); 00097 } 00098 00099 ///Return the leading diagonal as a vector. 00100 const typename Vector<Size, Precision, Base>::as_slice_type diagonal_slice() const { 00101 return my_vector.as_slice(); 00102 } 00103 00104 ///The vector used to hold the leading diagonal. 00105 Vector<Size,Precision,Base> my_vector; 00106 }; 00107 00108 00109 template<int S1, typename P1, typename B1, int S2, typename P2, typename B2> 00110 inline Vector<Internal::Sizer<S1,S2>::size, typename Internal::MultiplyType<P1,P2>::type> 00111 operator*(const DiagonalMatrix<S1,P1,B1>& d, const Vector<S2,P2,B2>& v){ 00112 return diagmult(d.my_vector,v); 00113 } 00114 00115 template<int S1, typename P1, typename B1, int S2, typename P2, typename B2> 00116 inline Vector<Internal::Sizer<S1,S2>::size, typename Internal::MultiplyType<P1,P2>::type> 00117 operator*( const Vector<S1,P1,B1>& v, const DiagonalMatrix<S2,P2,B2>& d){ 00118 return diagmult(v,d.my_vector); 00119 } 00120 00121 // perhaps not the safest way to do this as we're returning the same operator used to normally make vectors 00122 template<int S1, typename P1, typename B1, int S2, typename P2, typename B2> 00123 inline DiagonalMatrix<Internal::Sizer<S1,S2>::size, typename Internal::MultiplyType<P1,P2>::type> 00124 operator*( const DiagonalMatrix<S1,P1,B1>& d1, const DiagonalMatrix<S2,P2,B2>& d2){ 00125 SizeMismatch<S1,S2>::test(d1.my_vector.size(),d2.my_vector.size()); 00126 return Operator<Internal::VPairwise<Internal::Multiply,S1,P1,B1,S2,P2,B2> >(d1.my_vector,d2.my_vector); 00127 } 00128 00129 template<int R, int C, int Size, typename P1, typename P2, typename B1, typename B2> 00130 Matrix<R, C, typename Internal::MultiplyType<P1,P2>::type> 00131 operator* (const Matrix<R, C, P1, B1>& m, const DiagonalMatrix<Size, P2, B2>& d){ 00132 return diagmult(m,d.my_vector); 00133 } 00134 00135 template<int R, int C, typename P1, typename B1, int Size, typename P2, typename B2> 00136 Matrix<R, C, typename Internal::MultiplyType<P1,P2>::type> 00137 operator* (const DiagonalMatrix<Size,P1,B1>& d, const Matrix<R,C,P2,B2>& m) 00138 { 00139 return diagmult(d.my_vector, m); 00140 } 00141 00142 }