YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
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
19using namespace yarp::sig;
20using namespace yarp::eigen;
21
22void yarp::math::SVD(const Matrix &in, Matrix &U, Vector &S, Matrix &V)
23{
24 SVDJacobi(in,U,S,V);
25}
26
27void yarp::math::SVDMod(const Matrix &in, Matrix &U, Vector &S, Matrix &V)
28{
29 SVDJacobi(in,U,S,V);
30}
31
32void 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
46Matrix 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
63void 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
80Matrix 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
100void 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
120Matrix 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
127Matrix 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
136void 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
143void 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
169void 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
194void 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:39
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:94
size_t rows() const
Return number of rows.
Definition Matrix.h:88
void resize(size_t size) override
Resize the vector.
Definition Vector.h:221
size_t size() const
Definition Vector.h:341
Eigen::Map< Eigen::VectorXd > toEigen(yarp::sig::Vector &yarpVector)
Convert a yarp::sig::Vector to a Eigen::Map<Eigen::VectorXd> object.
Definition Eigen.h:21
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