Go to the documentation of this file.00001 #include <Eigen/Geometry>
00002 #include <Eigen/Jacobi>
00003 #include <Eigen/SVD>
00004
00005 #ifndef EIGEN_PINV_HPP
00006 #define EIGEN_PINV_HPP
00007 namespace EIGEN_PINV
00008 {
00009
00010
00011 Eigen::MatrixXd pinv( const Eigen::MatrixXd &b, double rcond )
00012 {
00013
00014
00015
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
00026 Eigen::JacobiSVD<Eigen::MatrixXd> svdA;
00027 svdA.compute( a, Eigen::ComputeFullU | Eigen::ComputeThinV );
00028 Eigen::JacobiSVD<Eigen::MatrixXd>::SingularValuesType vSingular = svdA.singularValues();
00029
00030
00031
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
00044 Eigen::MatrixXd mAdjointU = svdA.matrixU().adjoint().block( 0, 0, vSingular.rows(), svdA.matrixU().adjoint().cols() );
00045
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