31 #include <TooN/TooN.h> 32 #include <TooN/lapack.h> 38 static const double condition_no=1e9;
86 template<
int Rows=Dynamic,
int Cols=Rows,
typename Precision=DefaultPrecision>
90 static const int Min_Dim = Rows<Cols?Rows:Cols;
98 SVD(
int rows,
int cols)
100 my_diagonal(
std::min(rows,cols)),
101 my_square(
std::min(rows,cols),
std::min(rows,cols))
106 template <
int R2,
int C2,
typename P2,
typename B2>
109 my_diagonal(
std::min(m.num_rows(),m.num_cols())),
110 my_square(
std::min(m.num_rows(),m.num_cols()),
std::min(m.num_rows(),m.num_cols()))
116 template <
int R2,
int C2,
typename P2,
typename B2>
124 Precision*
const a = my_copy.my_data;
125 int lda = my_copy.num_cols();
126 int m = my_copy.num_cols();
127 int n = my_copy.num_rows();
128 Precision*
const uorvt = my_square.my_data;
129 Precision*
const s = my_diagonal.my_data;
144 ldu = my_square.num_cols();
154 gesvd_( &JOBVT, &JOBU, &m, &n, a, &lda, s, uorvt,
155 &ldvt, uorvt, &ldu, &size, &LWORK, &INFO);
157 LWORK = (
long int)(size);
158 wk =
new Precision[LWORK];
160 gesvd_( &JOBVT, &JOBU, &m, &n, a, &lda, s, uorvt,
161 &ldvt, uorvt, &ldu, wk, &LWORK, &INFO);
167 return (my_copy.num_rows() >= my_copy.num_cols());
170 int min_dim(){
return std::min(my_copy.num_rows(), my_copy.num_cols()); }
178 template <
int Rows2,
int Cols2,
typename P2,
typename B2>
184 return (
get_VT().T() * diagmult(inv_diag, (
get_U().T() * rhs)));
191 template <
int Size,
typename P2,
typename B2>
197 return (
get_VT().T() * diagmult(inv_diag, (
get_U().T() * rhs)));
207 return diagmult(
get_VT().T(),inv_diag) *
get_U().T();
213 Precision result = my_diagonal[0];
214 for(
int i=1; i<my_diagonal.size(); i++){
215 result *= my_diagonal[i];
222 int rank(
const Precision condition = condition_no) {
223 if (my_diagonal[0] == 0)
return 0;
225 for(
int i=0; i<min_dim(); i++){
226 if(my_diagonal[i] * condition <= my_diagonal[0]){
239 (my_copy.my_data,my_copy.num_rows(),my_copy.num_cols());
242 (my_square.my_data, my_square.num_rows(), my_square.num_cols());
255 (my_square.my_data, my_square.num_rows(), my_square.num_cols());
258 (my_copy.my_data,my_copy.num_rows(),my_copy.num_cols());
268 for(
int i=0; i<min_dim(); i++){
269 if(my_diagonal[i] * condition <= my_diagonal[0]){
272 inv_diag[i]=
static_cast<Precision
>(1)/my_diagonal[i];
291 template<
int Size,
typename Precision>
299 template <
int R2,
int C2,
typename P2,
typename B2>
int rank(const Precision condition=condition_no)
Calculate the rank of the matrix.
Definition: SVD.h:222
SVD(const Matrix< R2, C2, P2, B2 > &m)
Construct the SVD decomposition of a matrix.
Definition: SVD.h:107
void get_inv_diag(Vector< Min_Dim > &inv_diag, const Precision condition)
Return the pesudo-inverse diagonal.
Definition: SVD.h:267
Pretty generic SFINAE introspection generator.
Definition: vec_test.cc:21
A vector.
Definition: vector.hh:126
Matrix< Rows, Min_Dim, Precision, Reference::RowMajor > get_U()
Return the U matrix from the decomposition The size of this depends on the shape of the original matr...
Definition: SVD.h:236
void compute(const Matrix< R2, C2, P2, B2 > &m)
Compute the SVD decomposition of M, typically used after the default constructor. ...
Definition: SVD.h:117
SVD(int rows, int cols)
constructor for Rows=-1 or Cols=-1 (or both)
Definition: SVD.h:98
Matrix< Cols, Rows > get_pinv(const Precision condition=condition_no)
Calculate (pseudo-)inverse of the matrix.
Definition: SVD.h:204
Precision determinant()
Calculate the product of the singular values for square matrices this is the determinant.
Definition: SVD.h:212
Vector< Min_Dim, Precision > & get_diagonal()
Return the singular values as a vector.
Definition: SVD.h:247
Vector< Cols, typename Internal::MultiplyType< Precision, P2 >::type > backsub(const Vector< Size, P2, B2 > &rhs, const Precision condition=condition_no)
Calculate result of multiplying the (pseudo-)inverse of M by a vector.
Definition: SVD.h:193
Matrix< Min_Dim, Cols, Precision, Reference::RowMajor > get_VT()
Return the VT matrix from the decomposition The size of this depends on the shape of the original mat...
Definition: SVD.h:252
Matrix< Cols, Cols2, typename Internal::MultiplyType< Precision, P2 >::type > backsub(const Matrix< Rows2, Cols2, P2, B2 > &rhs, const Precision condition=condition_no)
Calculate result of multiplying the (pseudo-)inverse of M by another matrix.
Definition: SVD.h:180
Performs SVD and back substitute to solve equations.
Definition: SVD.h:87
SVD()
default constructor for Rows>0 and Cols>0
Definition: SVD.h:95
version of SVD forced to be square princiapally here to allow use in WLS
Definition: SVD.h:292