TooN
sl.h
1 // -*- c++ -*-
2 
3 // Copyright (C) 2005,2009 Tom Drummond (twd20@cam.ac.uk),
4 // Gerhard Reitmayr (gr281@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 #ifndef TOON_INCLUDE_SL_H
30 #define TOON_INCLUDE_SL_H
31 
32 #include <TooN/TooN.h>
33 #include <TooN/helpers.h>
34 #include <TooN/gaussian_elimination.h>
35 #include <TooN/determinant.h>
36 #include <cassert>
37 
38 namespace TooN {
39 
40 template <int N, typename P> class SL;
41 template <int N, typename P> std::istream & operator>>(std::istream &, SL<N, P> &);
42 
56 template <int N, typename Precision = DefaultPrecision>
57 class SL {
58  friend std::istream & operator>> <N,Precision>(std::istream &, SL &);
59 public:
60  static const int size = N;
61  static const int dim = N*N - 1;
62 
64  SL() : my_matrix(Identity) {}
65 
67  template <int S, typename P, typename B>
68  SL( const Vector<S,P,B> & v ) { *this = exp(v); }
69 
71  template <int R, int C, typename P, typename A>
72  SL(const Matrix<R,C,P,A>& M) : my_matrix(M) { coerce(); }
73 
75  const Matrix<N,N,Precision> & get_matrix() const { return my_matrix; }
77  SL inverse() const { return SL(*this, Invert()); }
78 
80  template <typename P>
82 
84  template <typename P>
85  SL operator*=( const SL<N,P> & rhs) { *this = *this*rhs; return *this; }
86 
89  template <int S, typename P, typename B>
90  static inline SL exp( const Vector<S,P,B> &);
91 
92  inline Vector<N*N-1, Precision> ln() const ;
93 
97  static inline Matrix<N,N,Precision> generator(int);
98 
99 private:
100  struct Invert {};
101  SL( const SL & from, struct Invert ) {
102  const Matrix<N> id = Identity;
103  my_matrix = gaussian_elimination(from.my_matrix, id);
104  }
105  SL( const SL & a, const SL & b) : my_matrix(a.get_matrix() * b.get_matrix()) {}
106 
107  void coerce(){
108  using std::abs;
109  Precision det = determinant(my_matrix);
110  assert(abs(det) > 0);
111  using std::pow;
112  my_matrix /= pow(det, 1.0/N);
113  }
114 
118  static const int COUNT_DIAG = N - 1;
119  static const int COUNT_SYMM = (dim - COUNT_DIAG)/2;
120  static const int COUNT_ASYMM = COUNT_SYMM;
121  static const int DIAG_LIMIT = COUNT_DIAG;
122  static const int SYMM_LIMIT = COUNT_SYMM + DIAG_LIMIT;
124 
125  Matrix<N,N,Precision> my_matrix;
126 };
127 
128 template <int N, typename Precision>
129 template <int S, typename P, typename B>
131  SizeMismatch<S,dim>::test(v.size(), dim);
132  Matrix<N,N,Precision> t(Zeros);
133  for(int i = 0; i < dim; ++i)
134  t += generator(i) * v[i];
135  SL<N, Precision> result;
136  result.my_matrix = TooN::exp(t);
137  return result;
138 }
139 
140 template <int N, typename Precision>
141 inline Vector<N*N-1, Precision> SL<N, Precision>::ln() const {
142  const Matrix<N> l = TooN::log(my_matrix);
143  Vector<SL<N,Precision>::dim, Precision> v;
144  Precision last = 0;
145  for(int i = 0; i < DIAG_LIMIT; ++i){ // diagonal elements
146  v[i] = l(i,i) + last;
147  last = l(i,i);
148  }
149  for(int i = DIAG_LIMIT, row = 0, col = 1; i < SYMM_LIMIT; ++i) { // calculate symmetric and antisymmetric in one go
150  // do the right thing here to calculate the correct indices !
151  v[i] = (l(row, col) + l(col, row))*0.5;
152  v[i+COUNT_SYMM] = (-l(row, col) + l(col, row))*0.5;
153  ++col;
154  if( col == N ){
155  ++row;
156  col = row+1;
157  }
158  }
159  return v;
160 }
161 
162 template <int N, typename Precision>
164  assert( i > -1 && i < dim );
165  Matrix<N,N,Precision> result(Zeros);
166  if(i < DIAG_LIMIT) { // first ones are the diagonal ones
167  result(i,i) = 1;
168  result(i+1,i+1) = -1;
169  } else if(i < SYMM_LIMIT){ // then the symmetric ones
170  int row = 0, col = i - DIAG_LIMIT + 1;
171  while(col > (N - row - 1)){
172  col -= (N - row - 1);
173  ++row;
174  }
175  col += row;
176  result(row, col) = result(col, row) = 1;
177  } else { // finally the antisymmetric ones
178  int row = 0, col = i - SYMM_LIMIT + 1;
179  while(col > N - row - 1){
180  col -= N - row - 1;
181  ++row;
182  }
183  col += row;
184  result(row, col) = -1;
185  result(col, row) = 1;
186  }
187  return result;
188 }
189 
190 template <int S, typename PV, typename B, int N, typename P>
192  return lhs.get_matrix() * rhs;
193 }
194 
195 template <int S, typename PV, typename B, int N, typename P>
197  return lhs * rhs.get_matrix();
198 }
199 
200 template<int R, int C, typename PM, typename A, int N, typename P> inline
202  return lhs.get_matrix() * rhs;
203 }
204 
205 template<int R, int C, typename PM, typename A, int N, typename P> inline
207  return lhs * rhs.get_matrix();
208 }
209 
210 template <int N, typename P>
211 std::ostream & operator<<(std::ostream & out, const SL<N, P> & h){
212  out << h.get_matrix();
213  return out;
214 }
215 
216 template <int N, typename P>
217 std::istream & operator>>(std::istream & in, SL<N, P> & h){
218  in >> h.my_matrix;
219  h.coerce();
220  return in;
221 }
222 
223 };
224 
225 #endif
Matrix< R, C, P > exp(const Matrix< R, C, P, B > &m)
computes the matrix exponential of a matrix m by scaling m by 1/(powers of 2), using Taylor series an...
Definition: helpers.h:330
Matrix< R, C, P > log(const Matrix< R, C, P, B > &m)
computes the matrix logarithm of a matrix m using the inverse scaling and squaring method...
Definition: helpers.h:373
const Matrix< N, N, Precision > & get_matrix() const
returns the represented matrix
Definition: sl.h:75
SL operator*=(const SL< N, P > &rhs)
right multiplies this SL with another one
Definition: sl.h:85
Pretty generic SFINAE introspection generator.
Definition: vec_test.cc:21
SL< N, typename Internal::MultiplyType< Precision, P >::type > operator*(const SL< N, P > &rhs) const
multiplies to SLs together by multiplying the underlying matrices
Definition: sl.h:81
SL inverse() const
returns the inverse using LU
Definition: sl.h:77
static const int dim
dimension of the vector space represented by SL<N>
Definition: sl.h:61
static Matrix< N, N, Precision > generator(int)
returns one generator of the group.
Definition: sl.h:163
represents an element from the group SL(n), the NxN matrices M with det(M) = 1.
Definition: sl.h:40
P determinant(const Matrix< R, C, P, B > &A)
Compute the determinant of a matrix using an appropriate method.
Definition: determinant.h:174
Definition: size_mismatch.hh:103
static SL exp(const Vector< S, P, B > &)
exponentiates a vector in the Lie algebra to compute the corresponding element
Vector< N, Precision > gaussian_elimination(Matrix< N, N, Precision > A, Vector< N, Precision > b)
Return the solution for , given and .
Definition: gaussian_elimination.h:43
SL(const Matrix< R, C, P, A > &M)
copy constructor from a matrix, coerces matrix to be of determinant = 1
Definition: sl.h:72
static const int size
size of the matrices represented by SL<N>
Definition: sl.h:60
SL(const Vector< S, P, B > &v)
exp constructor, creates element through exponentiation of Lie algebra vector. see SL::exp...
Definition: sl.h:68
SL()
default constructor, creates identity element
Definition: sl.h:64