TooN: internal/diagmatrix.h Source File

TooN 2.0.0-beta8

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

- File List

internal/diagmatrix.h

    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 }