TooN
diagmatrix.h
1 //-*- c++ -*-
2 //
3 // Copyright (C) 2009 Tom Drummond (twd20@cam.ac.uk),
4 // Ed Rosten (er258@cam.ac.uk)
5 
6 //All rights reserved.
7 //
8 //Redistribution and use in source and binary forms, with or without
9 //modification, are permitted provided that the following conditions
10 //are met:
11 //1. Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //2. Redistributions in binary form must reproduce the above copyright
14 // notice, this list of conditions and the following disclaimer in the
15 // documentation and/or other materials provided with the distribution.
16 //
17 //THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
18 //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 //IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 //ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
21 //LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 //CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 //SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 //INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 //CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 //POSSIBILITY OF SUCH DAMAGE.
28 
29 
30 
31 namespace TooN {
32 
33  namespace Internal
34  {
35  //Dummy struct for Diagonal operator
36  template<int Size, typename Precision, typename Base>
37  struct DiagMatrixOp;
38  }
39 
40  template<int Size, typename Precision, typename Base>
41  struct Operator<Internal::DiagMatrixOp<Size, Precision, Base> >
42  {
43  public:
46 
47 
48  inline Operator() {}
49  inline Operator(int size_in) : my_vector(size_in) {}
50  inline Operator(Precision* data) : my_vector(data) {}
51  inline Operator(Precision* data, int size_in) : my_vector(data,size_in) {}
52  inline Operator(Precision* data_in, int size_in, int stride_in, Internal::Slicing)
53  : my_vector(data_in, size_in, stride_in, Internal::Slicing() ) {}
54 
55  // constructors to allow return value optimisations
56  // construction from 0-ary operator
58  template <class Op>
59  inline Operator(const Operator<Op>& op)
60  : my_vector (op)
61  {
62  op.eval(my_vector);
63  }
64 
65  // constructor from arbitrary vector
66  template<int Size2, typename Precision2, typename Base2>
67  inline Operator(const Vector<Size2,Precision2,Base2>& from)
68  : my_vector(from.size())
69  {
70  my_vector=from;
71  }
73 
74 
77  template<int R, int C, class P, class B>
78  void eval(Matrix<R,C,P,B>& m) const {
79  SizeMismatch<Size, Size>::test(m.num_rows(), m.num_cols());
80  m = Zeros;
81  m.diagonal_slice() = my_vector;
82  }
83 
86  };
87 
107 template<int Size=Dynamic, typename Precision=DefaultPrecision, typename Base=Internal::VBase>
108 struct DiagonalMatrix: public Operator<Internal::DiagMatrixOp<Size, Precision, Base> > {
109 public:
112 
113  inline DiagonalMatrix() {}
116  inline DiagonalMatrix(Precision* data, int size_in) : Operator<Internal::DiagMatrixOp<Size, Precision, Base> >(data,size_in) {}
117  inline DiagonalMatrix(Precision* data_in, int size_in, int stride_in, Internal::Slicing)
118  : Operator<Internal::DiagMatrixOp<Size, Precision, Base> >(data_in, size_in, stride_in, Internal::Slicing() ) {}
119 
120  // constructors to allow return value optimisations
121  // construction from 0-ary operator
123  template <class Op>
124  inline DiagonalMatrix(const Operator<Op>& op)
125  : Operator<Internal::DiagMatrixOp<Size, Precision, Base> > (op)
126  {
127  op.eval(this->my_vector);
128  }
129 
130  // constructor from arbitrary vector
131  template<int Size2, typename Precision2, typename Base2>
134  {
135  this->my_vector=from;
136  }
138 
139 
140 
142  Precision& operator[](int i){return this->my_vector[i];}
144  const Precision& operator[](int i) const {return this->my_vector[i];}
145 
148  return this->my_vector.as_slice();
149  }
150 
153  return this->my_vector.as_slice();
154  }
155 
156  DiagonalMatrix<Size, Precision> operator-() const
157  {
158  return -this->my_vector;
159  }
160 
161  DiagonalMatrix<Size, Precision> inverse() const
162  {
163  Vector<Size, Precision> inv(this->my_vector.size());
164  for(int i=0; i < inv.size(); i++)
165  inv[i] = 1 / this->my_vector[i];
166  return inv;
167  }
168 };
169 
170 
171 template<int S1, typename P1, typename B1, int S2, typename P2, typename B2>
173 operator*(const DiagonalMatrix<S1,P1,B1>& d, const Vector<S2,P2,B2>& v){
174  return diagmult(d.my_vector,v);
175 }
176 
177 template<int S1, typename P1, typename B1, int S2, typename P2, typename B2>
178 inline Vector<Internal::Sizer<S1,S2>::size, typename Internal::MultiplyType<P1,P2>::type>
179 operator*( const Vector<S1,P1,B1>& v, const DiagonalMatrix<S2,P2,B2>& d){
180  return diagmult(v,d.my_vector);
181 }
182 
183 // perhaps not the safest way to do this as we're returning the same operator used to normally make vectors
184 template<int S1, typename P1, typename B1, int S2, typename P2, typename B2>
186 operator*( const DiagonalMatrix<S1,P1,B1>& d1, const DiagonalMatrix<S2,P2,B2>& d2){
187  SizeMismatch<S1,S2>::test(d1.my_vector.size(),d2.my_vector.size());
189 }
190 
191 template<int R, int C, int Size, typename P1, typename P2, typename B1, typename B2>
193 operator* (const Matrix<R, C, P1, B1>& m, const DiagonalMatrix<Size, P2, B2>& d){
194  return diagmult(m,d.my_vector);
195 }
196 
197 template<int R, int C, typename P1, typename B1, int Size, typename P2, typename B2>
199 operator* (const DiagonalMatrix<Size,P1,B1>& d, const Matrix<R,C,P2,B2>& m)
200 {
201  return diagmult(d.my_vector, m);
202 }
203 
204 }
Operator(const Operator< Op > &op)
my_vector constructed from a TooN::Operator
Definition: diagmatrix.h:59
Pretty generic SFINAE introspection generator.
Definition: vec_test.cc:21
A vector.
Definition: vector.hh:126
const Vector< Size, Precision, Base >::as_slice_type diagonal_slice() const
Return the leading diagonal as a vector.
Definition: diagmatrix.h:152
Matrix< 2 > inv(const Matrix< 2 > &m)
Invert a matrix.
Definition: helpers.h:65
A diagonal matrix.
Definition: diagmatrix.h:108
Definition: operators.hh:119
Definition: operators.hh:86
Definition: diagmatrix.h:37
Vector< Size, Precision, Base >::as_slice_type diagonal_slice()
Return the leading diagonal as a vector.
Definition: diagmatrix.h:147
DiagonalMatrix(const Operator< Op > &op)
my_vector constructed from a TooN::Operator
Definition: diagmatrix.h:124
const Precision & operator[](int i) const
Index the leading elements on the diagonal.
Definition: diagmatrix.h:144
Precision & operator[](int i)
Index the leading elements on the diagonal.
Definition: diagmatrix.h:142
Definition: size_mismatch.hh:103
Vector< Size, Precision, Base > my_vector
The vector used to hold the leading diagonal.
Definition: diagmatrix.h:85
Definition: TooN.h:145