eigen_pinv.hpp
Go to the documentation of this file.
00001 #include <Eigen/Geometry>
00002 #include <Eigen/Jacobi>
00003 #include <Eigen/SVD>
00004 //#include <limits>
00005 #ifndef EIGEN_PINV_HPP
00006 #define EIGEN_PINV_HPP
00007 namespace EIGEN_PINV
00008 {
00009 // Derived from code by Yohann Solaro ( http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2010/01/msg00187.html )
00010 // see : http://en.wikipedia.org/wiki/Moore-Penrose_pseudoinverse#The_general_case_and_the_SVD_method
00011 Eigen::MatrixXd pinv( const Eigen::MatrixXd &b, double rcond )
00012 {
00013   // TODO: Figure out why it wants fewer rows than columns
00014   // if ( a.rows()<a.cols() )
00015   // return false;
00016   bool flip = false;
00017   Eigen::MatrixXd a;
00018   if( a.rows() < a.cols() )
00019   {
00020     a = b.transpose();
00021     flip = true;
00022   }
00023   else
00024     a = b;
00025   // SVD
00026   Eigen::JacobiSVD<Eigen::MatrixXd> svdA;
00027   svdA.compute( a, Eigen::ComputeFullU | Eigen::ComputeThinV );
00028   Eigen::JacobiSVD<Eigen::MatrixXd>::SingularValuesType vSingular = svdA.singularValues();
00029   // Build a diagonal matrix with the Inverted Singular values
00030   // The pseudo inverted singular matrix is easy to compute :
00031   // is formed by replacing every nonzero entry by its reciprocal (inversing).
00032   Eigen::VectorXd vPseudoInvertedSingular( svdA.matrixV().cols() );
00033 
00034   for (int iRow=0; iRow<vSingular.rows(); iRow++)
00035   {
00036     if ( fabs(vSingular(iRow)) <= rcond )
00037     {
00038       vPseudoInvertedSingular(iRow)=0.;
00039     }
00040     else
00041       vPseudoInvertedSingular(iRow)=1./vSingular(iRow);
00042   }
00043   // A little optimization here
00044   Eigen::MatrixXd mAdjointU = svdA.matrixU().adjoint().block( 0, 0, vSingular.rows(), svdA.matrixU().adjoint().cols() );
00045   // Pseudo-Inversion : V * S * U'
00046   Eigen::MatrixXd a_pinv = (svdA.matrixV() * vPseudoInvertedSingular.asDiagonal()) * mAdjointU;
00047   if( flip )
00048   {
00049     a = a.transpose();
00050     a_pinv = a_pinv.transpose();
00051   }
00052   return a_pinv;
00053 }
00054 }
00055 #endif // EIGEN_PINV_HPP


carl_moveit
Author(s): David Kent
autogenerated on Thu Jun 6 2019 20:28:44