YARP
Yet Another Robot Platform
SVD.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
11 #include <yarp/math/SVD.h>
12 #include <yarp/math/Math.h>
13 
14 #include <yarp/eigen/Eigen.h>
15 
16 #include <Eigen/SVD>
17 
18 
19 using namespace yarp::sig;
20 using namespace yarp::eigen;
21 
22 void yarp::math::SVD(const Matrix &in, Matrix &U, Vector &S, Matrix &V)
23 {
24  SVDJacobi(in,U,S,V);
25 }
26 
27 void yarp::math::SVDMod(const Matrix &in, Matrix &U, Vector &S, Matrix &V)
28 {
29  SVDJacobi(in,U,S,V);
30 }
31 
32 void yarp::math::SVDJacobi(const Matrix &in, Matrix &U, Vector &S, Matrix &V)
33 {
34  Eigen::JacobiSVD< Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> > svd(toEigen(in), Eigen::ComputeThinU | Eigen::ComputeThinV);
35 
36  U.resize(svd.matrixU().rows(),svd.matrixU().cols());
37  toEigen(U) = svd.matrixU();
38 
39  S.resize(svd.singularValues().size());
40  toEigen(S) = svd.singularValues();
41 
42  V.resize(svd.matrixV().rows(),svd.matrixV().cols());
43  toEigen(V) = svd.matrixV();
44 }
45 
46 Matrix yarp::math::pinv(const Matrix &in, double tol)
47 {
48  int m = in.rows(), n = in.cols(), k = m<n?m:n;
49  Matrix U(m,k), V(n,k);
50  Vector Sdiag(k);
51 
52  yarp::math::SVD(in, U, Sdiag, V);
53 
54  Matrix Spinv = zeros(k,k);
55  for (int c = 0; c < k; c++) {
56  if (Sdiag(c) > tol) {
57  Spinv(c, c) = 1 / Sdiag(c);
58  }
59  }
60  return V*Spinv*U.transposed();
61 }
62 
63 void yarp::math::pinv(const Matrix &in, Matrix &out, double tol)
64 {
65  int m = in.rows(), n = in.cols(), k = m<n?m:n;
66  Matrix U(m,k), V(n,k);
67  Vector Sdiag(k);
68 
69  yarp::math::SVD(in, U, Sdiag, V);
70 
71  Matrix Spinv = zeros(k,k);
72  for (int c = 0; c < k; c++) {
73  if (Sdiag(c) > tol) {
74  Spinv(c, c) = 1 / Sdiag(c);
75  }
76  }
77  out = V*Spinv*U.transposed();
78 }
79 
80 Matrix yarp::math::pinv(const Matrix &in, Vector &sv, double tol)
81 {
82  int m = in.rows(), n = in.cols(), k = m<n?m:n;
83  Matrix U(m,k), V(n,k);
84  if ((int)sv.size() != k) {
85  sv.resize(k);
86  }
87 
88  yarp::math::SVD(in, U, sv, V);
89 
90  Matrix Spinv = zeros(k,k);
91  for (int c = 0; c < k; c++) {
92  if (sv(c) > tol) {
93  Spinv(c, c) = 1 / sv(c);
94  }
95  }
96 
97  return V*Spinv*U.transposed();
98 }
99 
100 void yarp::math::pinv(const Matrix &in, Matrix &out, Vector &sv, double tol)
101 {
102  int m = in.rows(), n = in.cols(), k = m<n?m:n;
103  Matrix U(m,k), V(n,k);
104  if ((int)sv.size() != k) {
105  sv.resize(k);
106  }
107 
108  yarp::math::SVD(in, U, sv, V);
109 
110  Matrix Spinv = zeros(k,k);
111  for (int c = 0; c < k; c++) {
112  if (sv(c) > tol) {
113  Spinv(c, c) = 1 / sv(c);
114  }
115  }
116 
117  out = V*Spinv*U.transposed();
118 }
119 
120 Matrix yarp::math::pinvDamped(const Matrix &in, Vector &sv, double damp)
121 {
122  Matrix out(in.cols(), in.rows());
123  pinvDamped(in, out, sv, damp);
124  return out;
125 }
126 
127 Matrix yarp::math::pinvDamped(const Matrix &in, double damp)
128 {
129  int k = in.rows()<in.cols() ? in.rows() : in.cols();
130  Vector sv(k);
131  Matrix out(in.cols(), in.rows());
132  pinvDamped(in, out, sv, damp);
133  return out;
134 }
135 
136 void yarp::math::pinvDamped(const Matrix &in, Matrix &out, double damp)
137 {
138  int k = in.rows()<in.cols() ? in.rows() : in.cols();
139  Vector sv(k);
140  pinvDamped(in, out, sv, damp);
141 }
142 
143 void yarp::math::pinvDamped(const Matrix &in, Matrix &out, Vector &sv, double damp)
144 {
145  int m = in.rows(), n = in.cols(), k = m<n?m:n;
146  Matrix U(m,k), V(n,k);
147  if ((int)sv.size() != k) {
148  sv.resize(k);
149  }
150 
151  yarp::math::SVD(in, U, sv, V);
152 
153  Matrix Spinv = zeros(k,k);
154  double damp2 = damp*damp;
155  for (int c = 0; c < k; c++) {
156  Spinv(c, c) = sv(c) / (sv(c) * sv(c) + damp2);
157  }
158 
159  out = V*Spinv*U.transposed();
160 }
161 
163 {
164  Matrix out(A.rows(),A.rows());
165  projectionMatrix(A, out, tol);
166  return out;
167 }
168 
169 void yarp::math::projectionMatrix(const Matrix &A, Matrix &out, double tol)
170 {
171  int m = A.rows();
172  int n = A.cols();
173  int k = std::min(m, n);
174  Matrix U(m, k);
175  Matrix V(n, k);
176  Vector Sdiag(k);
177  yarp::math::SVD(A, U, Sdiag, V);
178  Matrix UT = U.transposed();
179  for(int c = 0; c < k; c++) {
180  if(Sdiag(c) <= tol) {
181  UT.setRow(c, zeros(m));
182  }
183  }
184  out = U*UT;
185 }
186 
188 {
189  Matrix out(A.cols(),A.cols());
190  nullspaceProjection(A, out, tol);
191  return out;
192 }
193 
194 void yarp::math::nullspaceProjection(const Matrix &A, Matrix &out, double tol)
195 {
196  int m = A.rows();
197  int n = A.cols();
198  int k = std::min(m, n);
199  Matrix U(m,k);
200  Matrix V(n,k);
201  Vector Sdiag(k);
202  yarp::math::SVD(A, U, Sdiag, V);
203  Matrix VT = V.transposed();
204  for (int c = 0; c < k; c++) {
205  if (Sdiag(c) <= tol) {
206  VT.setRow(c, zeros(n));
207  }
208  }
209  out = eye(n) - V*VT;
210 }
A class for a Matrix.
Definition: Matrix.h:43
void resize(size_t r, size_t c)
Resize the matrix, if matrix is not empty preserve old content.
Definition: Matrix.cpp:265
Matrix transposed() const
Return the transposed of the matrix.
Definition: Matrix.cpp:388
bool setRow(size_t row, const Vector &r)
Set a row of the matrix copying the values from a vector: the vector length must be equal to the numb...
Definition: Matrix.cpp:513
size_t cols() const
Return number of columns.
Definition: Matrix.h:98
size_t rows() const
Return number of rows.
Definition: Matrix.h:92
void resize(size_t size) override
Resize the vector.
Definition: Vector.h:222
size_t size() const
Definition: Vector.h:323
Eigen::Map< Eigen::VectorXd > toEigen(yarp::sig::Vector &yarpVector)
Convert a yarp::sig::Vector to a Eigen::Map<Eigen::VectorXd> object.
Definition: Eigen.h:22
yarp::sig::Matrix eye(int r, int c)
Build an identity matrix (defined in Math.h).
Definition: math.cpp:586
yarp::sig::Matrix projectionMatrix(const yarp::sig::Matrix &A, double tol=0.0)
Compute the projection matrix of A, that is defined as A times its pseudoinverse: A*pinv(A) (defined ...
Definition: SVD.cpp:162
void SVD(const yarp::sig::Matrix &in, yarp::sig::Matrix &U, yarp::sig::Vector &S, yarp::sig::Matrix &V)
Factorize the M-by-N matrix 'in' into the singular value decomposition in = U S V^T (defined in SVD....
Definition: SVD.cpp:22
void SVDMod(const yarp::sig::Matrix &in, yarp::sig::Matrix &U, yarp::sig::Vector &S, yarp::sig::Matrix &V)
Perform SVD decomposition on a MxN matrix (for M >= N) (defined in SVD.h).
Definition: SVD.cpp:27
yarp::sig::Matrix pinv(const yarp::sig::Matrix &in, double tol=0.0)
Perform the moore-penrose pseudo-inverse of a matrix (defined in SVD.h).
Definition: SVD.cpp:46
yarp::sig::Matrix pinvDamped(const yarp::sig::Matrix &in, yarp::sig::Vector &sv, double damp)
Perform the damped pseudo-inverse of a matrix (defined in SVD.h).
Definition: SVD.cpp:120
yarp::sig::Vector zeros(int s)
Creates a vector of zeros (defined in Math.h).
Definition: math.cpp:576
yarp::sig::Matrix nullspaceProjection(const yarp::sig::Matrix &A, double tol=0.0)
Compute the nullspace projection matrix of A, that is defined as the difference between the identity ...
Definition: SVD.cpp:187
void SVDJacobi(const yarp::sig::Matrix &in, yarp::sig::Matrix &U, yarp::sig::Vector &S, yarp::sig::Matrix &V)
Perform SVD decomposition on a matrix using the Jacobi method (defined in SVD.h).
Definition: SVD.cpp:32
Signal processing.
Definition: Image.h:22