From 2ae4f93ef84530a7f862a45ac57a5120865073ed Mon Sep 17 00:00:00 2001 From: Mansard <nmansard@laas.fr> Date: Tue, 23 Aug 2011 09:54:58 +0200 Subject: [PATCH] IVIGIT. --- unitTesting/CMakeLists.txt | 18 +--- unitTesting/qrt.cpp | 186 +++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+), 13 deletions(-) create mode 100644 unitTesting/qrt.cpp diff --git a/unitTesting/CMakeLists.txt b/unitTesting/CMakeLists.txt index dec17e2..8516db1 100644 --- a/unitTesting/CMakeLists.txt +++ b/unitTesting/CMakeLists.txt @@ -16,16 +16,17 @@ ADD_DEFINITIONS(-DDEBUG=2) SET(tests - dummy) + dummy + qrt) FOREACH(test ${tests}) SET(EXECUTABLE_NAME "${test}_exe") ADD_EXECUTABLE(${EXECUTABLE_NAME} ${test}.cpp) - TARGET_LINK_LIBRARIES(${EXECUTABLE_NAME} - controller-pd - ) + #TARGET_LINK_LIBRARIES(${EXECUTABLE_NAME} + #controller-pd + # ) PKG_CONFIG_USE_DEPENDENCY(${EXECUTABLE_NAME} sot-core) PKG_CONFIG_USE_DEPENDENCY(${EXECUTABLE_NAME} soth) @@ -35,13 +36,4 @@ FOREACH(test ${tests}) TARGET_LINK_LIBRARIES(${EXECUTABLE_NAME} "${${test}_plugins_dependencies}") ENDIF(${test}_plugins_dependencies) - - ADD_TEST(${test} ${EXECUTABLE_NAME} - ${samplemodelpath} sample.wrl ${samplespec} ${sampleljr} ) - - IF (UNIX) - SET_PROPERTY(TEST ${test} PROPERTY - ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_INSTALL_PREFIX}/lib:${CMAKE_BINARY_DIR}/src:${BOOST_ROOT}/lib") - ENDIF(UNIX) - ENDFOREACH(test) diff --git a/unitTesting/qrt.cpp b/unitTesting/qrt.cpp new file mode 100644 index 0000000..136864d --- /dev/null +++ b/unitTesting/qrt.cpp @@ -0,0 +1,186 @@ +/* + * Copyright 2011, Nicolas Mansard, LAAS-CNRS + * + * This file is part of sot-dyninv. + * sot-dyninv is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * sot-dyninv is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. You should + * have received a copy of the GNU Lesser General Public License along + * with sot-dyninvc. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <Eigen/QR> +#include <soth/Algebra.hpp> +#include <iostream> + +std::ostream& p( const char * n ) { return std::cout << n << " = "; } + + +namespace Eigen +{ + class FullRowRankColPivQR + : private ColPivHouseholderQR< MatrixXd > + { + public: + + void compute(const MatrixType& matrix) + { + assert( matrix.rows()<=matrix.cols() ); + ColPivHouseholderQR< MatrixXd >::compute( matrix.transpose() ); + assert( rank() == matrix.rows() ); + } + + void solveInPlace( MatrixXd& Gp ) + { + /* r is the rank, nxm the size of the original matrix (ie whose transpose has + * been decomposed. */ + const int r = rank(), n=cols(), m=rows(); + assert( r==n ); + assert( Gp.rows() == m ); + + /* G'E = Q R + * => G^+ = Q R^+T E' */ + + /* Compute E'*X. */ + Gp.applyOnTheLeft( colsPermutation().transpose() ); + + /* Compute R^+T E'*X. */ + matrixQR() + .topLeftCorner(r,r).transpose().triangularView<Lower>() + .solveInPlace(Gp.topRows(r)); + + /* Compute Q R^+T E'*X. */ + /* Q = P1*P2* ... *Pn */ + VectorXd workspace( n ); + for (int k = r-1; k >= 0 ; --k) + { + int remainingSize = m-k; + Gp.bottomRows( Gp.rows()-k ) + .applyHouseholderOnTheLeft(matrixQR().col(k).tail(remainingSize-1), + hCoeffs().coeff(k), &workspace.coeffRef(0)); + } + } + }; +} + +int main (void) +{ + using namespace Eigen; + using std::endl; using std::cout; using soth::MATLAB; + + { /* Compute the pseudo inverse of a full-col rank matrix: G = V [ R; 0 ]. */ + + const unsigned int n=6, m=3, r=3; + + MatrixXd G = MatrixXd::Random(n,m); + p("G") << (MATLAB)G << endl; + + Eigen::ColPivHouseholderQR<Eigen::MatrixXd> G_qr; + G_qr.compute(G); + p("QR") << (MATLAB)G_qr.matrixQR() << endl; + + { + /* Q1 = ... */ + MatrixXd Q1 = MatrixXd::Identity( n,r ); + VectorXd workspace( n ); + /* P0*P1*P2 ... */ + for (int k = r-1; k >= 0 ; --k) + { + int remainingSize = n-k; + Q1.bottomRows( Q1.rows()-k ) + .applyHouseholderOnTheLeft(G_qr.matrixQR().col(k).tail(remainingSize-1), + G_qr.hCoeffs().coeff(k), &workspace.coeffRef(0)); + } + p("Q1") << (MATLAB)Q1 << endl; + } + + { + /* Q1' = ... */ + MatrixXd Q1t = MatrixXd::Identity( r,n ); + VectorXd workspace( n ); + /* P2*P1*P0 ... */ + for (int k = r-1; k >= 0 ; --k) + { + int remainingSize = n-k; + Q1t.rightCols( Q1t.cols()-k ) + .applyHouseholderOnTheRight(G_qr.matrixQR().col(k).tail(remainingSize-1), + G_qr.hCoeffs().coeff(k), &workspace.coeffRef(0)); + } + p("Q1t") << (MATLAB)Q1t << endl; + } + + { + MatrixXd Gp = MatrixXd::Identity( r,n ); + VectorXd workspace( n ); + /* P2*P1*P0 ... */ + for (int k = r-1; k >= 0 ; --k) + { + int remainingSize = n-k; + Gp.rightCols( Gp.cols()-k ) + .applyHouseholderOnTheRight(G_qr.matrixQR().col(k).tail(remainingSize-1), + G_qr.hCoeffs().coeff(k), &workspace.coeffRef(0)); + } + + G_qr.matrixQR() + .topLeftCorner(r,r).triangularView<Upper>() + .solveInPlace(Gp); + p("EtGp") << (MATLAB)Gp << endl; + + Gp.applyOnTheLeft( G_qr.colsPermutation() ); + p("Gp") << (MATLAB)Gp << endl; + } + } + + { /* Compute the pseudo inverse of a full-row rank matrix: G = [ L; 0 ] V'. */ + const unsigned int n=3, m=6, r=3; + + MatrixXd G = MatrixXd::Random(n,m); + p("G") << (MATLAB)G << endl; + + Eigen::ColPivHouseholderQR< Eigen::MatrixXd > Gt_qr; + Gt_qr.compute(G.transpose()); + p("QR") << (MATLAB)Gt_qr.matrixQR() << endl; + p("Q") << (MATLAB)(MatrixXd)Gt_qr.householderQ() << endl; + p("R") << (MATLAB)(MatrixXd)Gt_qr.matrixQR().triangularView<Upper>() << endl; + p("E") << (MATLAB)Gt_qr.colsPermutation().toDenseMatrix() << endl; + + { + MatrixXd Gp = MatrixXd::Identity( m,r ); + Gp.applyOnTheLeft( Gt_qr.colsPermutation().transpose() ); + p("Et") << (MATLAB)Gp << endl; + + Gt_qr.matrixQR() + .topLeftCorner(r,r).transpose().triangularView<Lower>() + .solveInPlace(Gp.topRows(r)); + p("RptEt") << (MATLAB)Gp << endl; + + /* Q = P1*P2* ... *Pn */ + VectorXd workspace( n ); + for (int k = r-1; k >= 0 ; --k) + { + cout << k << endl; + int remainingSize = m-k; + Gp.bottomRows( Gp.rows()-k ) + .applyHouseholderOnTheLeft(Gt_qr.matrixQR().col(k).tail(remainingSize-1), + Gt_qr.hCoeffs().coeff(k), &workspace.coeffRef(0)); + } + p("Gp") << (MATLAB)Gp << endl; + + } + + { + FullRowRankColPivQR G_lq; G_lq.compute(G); + MatrixXd Gp = MatrixXd::Identity( m,r ); + G_lq.solveInPlace(Gp); + p("Gp") << (MATLAB)Gp << endl; + } + + } + + return 0; +} -- GitLab