00001 /**************************************************************************** 00002 Copyright (C)2002 David Jung <opensim@pobox.com> 00003 00004 This program/file is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. (http://www.gnu.org) 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 $Id: SVD 1029 2004-02-11 20:45:54Z jungd $ 00019 $Revision: 1.10 $ 00020 $Date: 2004-02-11 15:45:54 -0500 (Wed, 11 Feb 2004) $ 00021 $Author: jungd $ 00022 00023 ****************************************************************************/ 00024 00025 #ifndef _BASE_SVD_ 00026 #define _BASE_SVD_ 00027 00028 #include <base/base> 00029 00030 #include <base/Matrix> 00031 00032 00033 namespace base { 00034 00035 00036 /// Singular Value Decomposition of a rectangluar Matrix 00037 /** 00038 * A = U * S * V' 00039 * 00040 * where matrices U and V are orthogonal and S is a digonal matrix. 00041 * 00042 * The singular value decomposition is performed by constructing an SVD 00043 * object from an M*N matrix A with M>=N (that is, at least as many rows 00044 * as columns). Note, in case M > N, matrix S has to be a M*N diagonal 00045 * matrix. However, it has only N diag elements, which we store in a 1:N 00046 * Vector sig. 00047 * 00048 * This code is based on the Numerical Recipies in C book. 00049 */ 00050 00051 class SVD 00052 { 00053 public: 00054 /// Decompose Matrix A, of M rows and N columns, M>=N 00055 SVD(const Matrix &A); 00056 00057 /// Return U 00058 const Matrix& U() const; 00059 /// Return V 00060 const Matrix& V() const; 00061 /// Return vector of singular values ( min(M,N)x1 ) 00062 const Vector diag() const; 00063 00064 /// Return S - diagonal matrix of singular values (diagonal elements are diag() ) 00065 Matrix S() const; 00066 00067 static const Real maxCondition; // maximum condition number to return 00068 static const Real minSingValue; // minimum singular value before set to 0 00069 00070 /// Return condition number (max singular value / min singular value) 00071 /** (S_max/S_min) */ 00072 Real condition(Real maxCond = maxCondition) const; 00073 00074 00075 /// pseudo-inverse of A 00076 Matrix inv(Real minSingVal = minSingValue) const; 00077 00078 00079 private: 00080 Int M,N; ///< Dimensions of the problem (M>=N) 00081 Matrix UMat; ///< M*M orthogonal matrix U 00082 Matrix VMat; ///< N*N orthogonal matrix V 00083 Vector s; ///< Vector of N unordered singular values 00084 00085 }; 00086 00087 00088 } // base 00089 00090 00091 #endif