// Copyright (C) 2007 Ruben Smits // Version: 1.0 // Author: Ruben Smits // Maintainer: Ruben Smits // URL: http://www.orocos.org/kdl // This library 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 2.1 of the License, or (at your option) any later version. // This library 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 this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA //Based on the svd of the KDL-0.2 library by Erwin Aertbelien #ifndef SVD_EIGEN_HH_HPP #define SVD_EIGEN_HH_HPP #include #include namespace KDL { template inline Scalar PYTHAG(Scalar a,Scalar b) { double at,bt,ct; at = fabs(a); bt = fabs(b); if (at > bt ) { ct=bt/at; return Scalar(at*sqrt(1.0+ct*ct)); } else { if (bt==0) return Scalar(0.0); else { ct=at/bt; return Scalar(bt*sqrt(1.0+ct*ct)); } } } template inline Scalar SIGN(Scalar a,Scalar b) { return ((b) >= Scalar(0.0) ? fabs(a) : -fabs(a)); } /** * svd calculation of boost ublas matrices * * @param A matrix(mxn) * @param U matrix(mxn) * @param S vector n * @param V matrix(nxn) * @param tmp vector n * @param maxiter defaults to 150 * * @return -2 if maxiter exceeded, 0 otherwise */ template int svd_eigen_HH( const Eigen::MatrixBase& A, Eigen::MatrixBase& U, Eigen::MatrixBase& S, Eigen::MatrixBase& V, Eigen::MatrixBase& tmp, int maxiter=150) { //get the rows/columns of the matrix const int rows = A.rows(); const int cols = A.cols(); U = A; int i(-1),its(-1),j(-1),jj(-1),k(-1),nm=0; int ppi(0); bool flag; e_scalar maxarg1,maxarg2,anorm(0),c(0),f(0),h(0),s(0),scale(0),x(0),y(0),z(0),g(0); g=scale=anorm=e_scalar(0.0); /* Householder reduction to bidiagonal form. */ for (i=0;i maxarg2 ? maxarg1 : maxarg2; } /* Accumulation of right-hand transformations. */ for (i=cols-1;i>=0;i--) { if (i=0;i--) { ppi=i+1; g=S(i); for (j=ppi;j=0;k--) { /* Loop over singular values. */ for (its=1;its<=maxiter;its++) { /* Loop over allowed iterations. */ flag=true; for (ppi=k;ppi>=0;ppi--) { /* Test for splitting. */ nm=ppi-1; /* Note that tmp(1) is always zero. */ if ((fabs(tmp(ppi))+anorm) == anorm) { flag=false; break; } if ((fabs(S(nm)+anorm) == anorm)) break; } if (flag) { c=e_scalar(0.0); /* Cancellation of tmp(l), if l>1: */ s=e_scalar(1.); for (i=ppi;i<=k;i++) { f=s*tmp(i); tmp(i)=c*tmp(i); if ((fabs(f)+anorm) == anorm) break; g=S(i); h=PYTHAG(f,g); S(i)=h; h=e_scalar(1.0)/h; c=g*h; s=(-f*h); for (j=0;j S_max){ S_max = Sj; i_max = j; } } if (i_max != i){ /* swap eigenvalues */ e_scalar tmp = S(i); S(i)=S(i_max); S(i_max)=tmp; /* swap eigenvectors */ U.col(i).swap(U.col(i_max)); V.col(i).swap(V.col(i_max)); } } if (its == maxiter) return (-2); else return (0); } } #endif