/* * NICE-Core - efficient algebra and computer vision methods * - libbasicvector - A simple vector library * See file License for license information. */ #ifndef BASICVECTOR_SVD_H #define BASICVECTOR_SVD_H #include "core/vector/VectorT.h" #include "core/vector/MatrixT.h" #include "core/vector/RowMatrixT.h" #ifdef NICE_USELIB_LINAL #include #endif namespace NICE { #ifdef NICE_USELIB_LINAL template class SVD { public: /** * Constructor * @param matrix Input matrix */ inline SVD(const MatrixT& matrix) { LinAl::MatrixCF _u; LinAl::MatrixCF _vt; LinAl::VectorCC _s; LinAl::svdfull(matrix.linal(), _u, _s, _vt); u = _u; vt = _vt; s = _s; } /** * Get the first factor U. * @return */ inline MatrixT getU() { return u; } /** * Get the third factor V. * @return */ inline MatrixT getV() { return vt.transpose(); } /** * Get the transposed third factor V^T. * @return */ inline MatrixT getVt() { return vt; } /** * Get the singular values as a vector. * @return */ inline VectorT getSingularValues() { return s; } /** * Get the singular values as a diagonal matrix. * @return */ inline MatrixT getS() { MatrixT result(s.size(), s.size()); result = 0.0; for (uint i = 0; i < s.size(); ++i) { result(i,i) = s[i]; } return result; } // double norm2 () // double cond () // int rank () private: MatrixT u; VectorT s; MatrixT vt; }; /** enforce predefined singular values of a square matrix */ template inline void enforceSingularValues(MatrixT& m, const VectorT& sNew) { SVD svd(m); MatrixT u = svd.getU(); MatrixT s = svd.getS(); MatrixT vt = svd.getVt(); for (unsigned int i = 0; i < sNew.size(); i++) { s(i, i) = sNew[i]; } MatrixT us; us.multiply(u, s); m.multiply(us, vt); } template inline void enforceRankDefect(MatrixT& m, const uint defect) { SVD svd(m); MatrixT u = svd.getU(); MatrixT s = svd.getS(); MatrixT vt = svd.getVt(); for (unsigned int i = 0; i < s.rows(); i++) { s(i, i) = ((int)i < (int)s.rows() - (int)defect ? s(i,i) : 0.0); } MatrixT us; us.multiply(u, s); m.multiply(us, vt); } #else // no LinAl #ifndef SVDLINAL_WARNING #pragma message NICE_WARNING("SVD requires LinAl.") #define SVDLINAL_WARNING #endif #endif } // namespace #endif