Choreonoid  1.8
TruncatedSVD.h
Go to the documentation of this file.
1 
6 #ifndef CNOID_UTIL_TRUNCATED_SVD_SOLVER_H_INCLUDED
7 #define CNOID_UTIL_TRUNCATED_SVD_SOLVER_H_INCLUDED
8 
9 #include <Eigen/Core>
10 
11 namespace cnoid {
12 
13 template <class MatrixType>
15 {
16  typedef typename MatrixType::Scalar Scalar;
17  Eigen::JacobiSVD<MatrixType> svd;
18  Eigen::DiagonalMatrix<Scalar, Eigen::Dynamic> sinv;
19  Scalar truncateRatio;
20  int numTruncated;
21 
22 public:
23 
24  static double defaultTruncateRatio() { return 2.0e2; }
25 
27  truncateRatio = defaultTruncateRatio();
28  numTruncated = 0;
29  }
30 
31  void setTruncateRatio(Scalar r){
32  if(r <= 0.0){
33  truncateRatio = std::numeric_limits<double>::infinity();
34  } else {
35  truncateRatio = r;
36  }
37  }
38 
39  TruncatedSVD& compute(const MatrixType& matrix){
40 
41  numTruncated = 0;
42 
43  svd.compute(matrix, Eigen::ComputeThinU | Eigen::ComputeThinV);
44  sinv.diagonal() = svd.singularValues();
45 
46  int lastNonZeroSingularValues = svd.nonzeroSingularValues() - 1;
47  if(lastNonZeroSingularValues > 0){
48  Scalar& s0 = sinv.diagonal()(0);
49  Scalar& s_last = sinv.diagonal()(lastNonZeroSingularValues);
50  if((s0 / s_last) > truncateRatio){
51  s_last = Scalar(0.0);
52  ++numTruncated;
53  int j;
54  for(j = lastNonZeroSingularValues - 1; j > 0; --j){
55  Scalar& s = sinv.diagonal()(j);
56  if((s0 / s) > truncateRatio){
57  s = Scalar(0.0);
58  ++numTruncated;
59  } else {
60  break;
61  }
62  }
63  while(j >= 0){
64  Scalar& s = sinv.diagonal()(j);
65  s = Scalar(1.0) / s;
66  --j;
67  }
68  }
69  }
70  return *this;
71  }
72 
74  return numTruncated;
75  }
76 
77  const typename Eigen::JacobiSVD<MatrixType>::SingularValuesType& singularValues() const {
78  return svd.singularValues();
79  }
80 
81  template <class VectorType1, class VectorType2>
82  void solve(const Eigen::MatrixBase<VectorType1>& b, Eigen::MatrixBase<VectorType2>& out_x) const {
83  if(numTruncated > 0){
84  out_x = svd.matrixV() * sinv * svd.matrixU().transpose() * b;
85  } else {
86  out_x = svd.solve(b);
87  }
88  }
89 };
90 }
91 
92 #endif
cnoid::TruncatedSVD::defaultTruncateRatio
static double defaultTruncateRatio()
Definition: TruncatedSVD.h:24
cnoid::TruncatedSVD::setTruncateRatio
void setTruncateRatio(Scalar r)
Definition: TruncatedSVD.h:31
cnoid::TruncatedSVD::solve
void solve(const Eigen::MatrixBase< VectorType1 > &b, Eigen::MatrixBase< VectorType2 > &out_x) const
Definition: TruncatedSVD.h:82
cnoid::TruncatedSVD::compute
TruncatedSVD & compute(const MatrixType &matrix)
Definition: TruncatedSVD.h:39
cnoid::TruncatedSVD::TruncatedSVD
TruncatedSVD()
Definition: TruncatedSVD.h:26
cnoid
Definition: AbstractSceneLoader.h:11
cnoid::TruncatedSVD::numTruncatedSingularValues
int numTruncatedSingularValues() const
Definition: TruncatedSVD.h:73
cnoid::TruncatedSVD::singularValues
const Eigen::JacobiSVD< MatrixType >::SingularValuesType & singularValues() const
Definition: TruncatedSVD.h:77
cnoid::TruncatedSVD
Definition: TruncatedSVD.h:14