hpp-constraints  4.9.1
Definition of basic geometric constraints for motion planning
svd.hh
Go to the documentation of this file.
1 // Copyright (c) 2015 CNRS
2 // Author: Joseph Mirabel
3 //
4 //
5 // This file is part of hpp-constraints
6 // hpp-constraints is free software: you can redistribute it
7 // and/or modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation, either version
9 // 3 of the License, or (at your option) any later version.
10 //
11 // hpp-constraints is distributed in the hope that it will be
12 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Lesser Public License for more details. You should have
15 // received a copy of the GNU Lesser General Public License along with
16 // hpp-constraints If not, see
17 // <http://www.gnu.org/licenses/>.
18 
19 #ifndef HPP_CONSTRAINTS_SVD_HH
20 # define HPP_CONSTRAINTS_SVD_HH
21 
22 # include <hpp/constraints/fwd.hh>
23 # include <Eigen/SVD>
24 
25 namespace hpp {
26  namespace constraints {
27  template <typename SVD>
28  static Eigen::Ref<const typename SVD::MatrixUType>
29  getU1 (const SVD& svd, const size_type& rank)
30  {
31  return svd.matrixU().leftCols (rank);
32  }
33 
34  template <typename SVD>
35  static Eigen::Ref<const typename SVD::MatrixUType>
36  getU2 (const SVD& svd, const size_type& rank)
37  {
38  return svd.matrixU().rightCols (svd.matrixU().cols() - rank);
39  }
40 
41  template <typename SVD>
42  static Eigen::Ref<const typename SVD::MatrixUType>
43  getV1 (const SVD& svd, const size_type& rank)
44  {
45  return svd.matrixV().leftCols (rank);
46  }
47 
48  template <typename SVD>
49  static Eigen::Ref<const typename SVD::MatrixUType>
50  getV2 (const SVD& svd, const size_type& rank)
51  {
52  return svd.matrixV().rightCols (svd.matrixV().cols() - rank);
53  }
54 
55  template < typename SVD>
56  static void pseudoInverse(const SVD& svd,
57  Eigen::Ref <typename SVD::MatrixType> pinvmat)
58  {
59  eigen_assert(svd.computeU() && svd.computeV() && "Eigen::JacobiSVD "
60  "computation flags must be at least: ComputeThinU | ComputeThinV");
61 
62  size_type rank = svd.rank();
63  typename SVD::SingularValuesType singularValues_inv =
64  svd.singularValues().segment (0,rank).cwiseInverse ();
65 
66  pinvmat.noalias() =
67  getV1<SVD> (svd, rank) * singularValues_inv.asDiagonal() *
68  getU1<SVD> (svd, rank).adjoint();
69  }
70 
71  template < typename SVD >
72  void projectorOnSpan (const SVD& svd,
73  Eigen::Ref <typename SVD::MatrixType> projector)
74  {
75  eigen_assert(svd.computeU() && svd.computeV() && "Eigen::JacobiSVD "
76  "computation flags must be at least: ComputeThinU | ComputeThinV");
77 
78  size_type rank = svd.rank();
79  projector.noalias() = getV1<SVD> (svd, rank) * getV1<SVD>(svd, rank).adjoint();
80  }
81 
82  template < typename SVD >
83  void projectorOnSpanOfInv (const SVD& svd,
84  Eigen::Ref <typename SVD::MatrixType> projector)
85  {
86  eigen_assert(svd.computeU() && svd.computeV() && "Eigen::JacobiSVD "
87  "computation flags must be at least: ComputeThinU | ComputeThinV");
88 
89  size_type rank = svd.rank();
90  projector.noalias() = getU1<SVD>(svd, rank) * getU1<SVD>(svd, rank).adjoint();
91  }
92 
93  template < typename SVD >
94  void projectorOnKernel (const SVD& svd,
95  Eigen::Ref <typename SVD::MatrixType> projector,
96  const bool& computeFullV = false)
97  {
98  eigen_assert(svd.computeV() && "Eigen::JacobiSVD "
99  "computation flags must be at least: ComputeThinV");
100 
101  size_type rank = svd.rank();
102  if (computeFullV)
103  projector.noalias() = getV2<SVD> (svd, rank) * getV2<SVD>(svd, rank).adjoint();
104  else {
105  projector.noalias() = - getV1<SVD> (svd, rank) * getV1<SVD>(svd, rank).adjoint();
106  projector.diagonal().noalias () += vector_t::Ones(svd.matrixV().rows());
107  }
108  }
109 
110  template < typename SVD >
111  void projectorOnKernelOfInv (const SVD& svd,
112  Eigen::Ref <typename SVD::MatrixType> projector,
113  const bool& computeFullU = false)
114  {
115  eigen_assert(svd.computeU() && "Eigen::JacobiSVD "
116  "computation flags must be at least: ComputeThinU");
117 
118  size_type rank = svd.rank();
119  if (computeFullU) {
120  // U2 * U2*
121  projector.noalias() = getU2<SVD>(svd, rank) * getU2<SVD>(svd, rank).adjoint();
122  } else {
123  // I - U1 * U1*
124  projector.noalias() = - getU1<SVD>(svd, rank) * getU1<SVD>(svd, rank).adjoint();
125  projector.diagonal().noalias () += vector_t::Ones(svd.matrixU().rows());
126  }
127  }
128  } // namespace constraints
129 } // namespace hpp
130 
131 #endif // HPP_CONSTRAINTS_SVD_HH
matrix_t::Index size_type
void projectorOnKernel(const SVD &svd, Eigen::Ref< typename SVD::MatrixType > projector, const bool &computeFullV=false)
Definition: svd.hh:94
void projectorOnSpanOfInv(const SVD &svd, Eigen::Ref< typename SVD::MatrixType > projector)
Definition: svd.hh:83
void projectorOnKernelOfInv(const SVD &svd, Eigen::Ref< typename SVD::MatrixType > projector, const bool &computeFullU=false)
Definition: svd.hh:111
pinocchio::size_type size_type
Definition: fwd.hh:35
void projectorOnSpan(const SVD &svd, Eigen::Ref< typename SVD::MatrixType > projector)
Definition: svd.hh:72