EigenOpt 1.0.0
Loading...
Searching...
No Matches
kernel_projection.hxx
Go to the documentation of this file.
1#pragma once
2
4
5namespace EigenOpt {
6
7template<class Scalar, class D1, class D2>
9 const Eigen::MatrixBase<D1>& A,
10 const Eigen::MatrixBase<D2>& b,
11 Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>& Z,
12 Eigen::Matrix<Scalar,Eigen::Dynamic,1>& xeq
13)
14{
15 EigenOptTypedefs(Scalar);
16
17 // Perform a SVD on A, making sure to compute the full V to extract ker(A).
18 Eigen::JacobiSVD<MatrixXs> svd(A, Eigen::ComputeThinU|Eigen::ComputeFullV);
19
20 // Find the minimum-norm, least square solution to A*x=b.
21 xeq = svd.solve(b);
22
23 // SVD is a rank-revealing decomposition, and we can use it to check if we
24 // actually have some degrees of freedom left in x.
25 if(A.cols() > svd.rank()) {
26 // Yes, we have some additional degrees of freedom: extract the kernel of A.
27 Z = svd.matrixV().rightCols(svd.cols()-svd.rank());
28 }
29 else {
30 // No, we do not have any degrees of freedom (the system fully determines a
31 // value for xeq) and therefore the kernel is "empty".
32 Z.resize(A.cols(), 0);
33 }
34}
35
36
37template<class Scalar, class D1, class D2>
39 const Eigen::MatrixBase<D1>& A,
40 const Eigen::MatrixBase<D2>& b,
41 Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>& Z,
42 Eigen::Matrix<Scalar,Eigen::Dynamic,1>& xeq
43)
44{
45 EigenOptTypedefs(Scalar);
46
47 // Solve A*x = b in least squares sense (in the sense that it minimizes
48 // A*x-b, but it is not necessarily the minimum-norm solution) using a QR
49 // decomposition.
50 xeq = Eigen::ColPivHouseholderQR<MatrixXs>(A).solve(b);
51
52 // Do a QR decomposition of A^T to extract the orthogonal matrix Q.
53 Eigen::ColPivHouseholderQR<MatrixXs> QR(A.transpose());
54
55 // QR is a rank-revealing decomposition, and we can use it to check if we
56 // actually have some degrees of freedom left in x.
57 if(A.cols() > QR.rank()) {
58 // Yes, we have some additional degrees of freedom: extract the kernel of A
59 Z = MatrixXs(QR.householderQ()).rightCols(A.cols()-QR.rank());
60 }
61 else {
62 // No, we do not have any degrees of freedom (the system fully determines a
63 // value for xeq) and therefore the kernel is "empty".
64 Z.resize(A.cols(), 0);
65 }
66}
67
68} // namespace EigenOpt
Main namespace of this project, containing all utilities.
void svd_projection(const Eigen::MatrixBase< D1 > &A, const Eigen::MatrixBase< D2 > &b, Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &Z, Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > &xeq)
Return all solutions to a linear system, using a kernel-based parameterization.
void qr_projection(const Eigen::MatrixBase< D1 > &A, const Eigen::MatrixBase< D2 > &b, Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &Z, Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > &xeq)
Return all solutions to a linear system, using a kernel-based parameterization.
#define EigenOptTypedefs(ScalarType)
Definition typedefs.hpp:6