Chris@49: // Copyright (C) 2009-2011 NICTA (www.nicta.com.au) Chris@49: // Copyright (C) 2009-2011 Conrad Sanderson Chris@49: // Chris@49: // This Source Code Form is subject to the terms of the Mozilla Public Chris@49: // License, v. 2.0. If a copy of the MPL was not distributed with this Chris@49: // file, You can obtain one at http://mozilla.org/MPL/2.0/. Chris@49: Chris@49: Chris@49: //! \addtogroup fn_svd Chris@49: //! @{ Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: bool Chris@49: svd Chris@49: ( Chris@49: Col& S, Chris@49: const Base& X, Chris@49: const typename arma_blas_type_only::result* junk = 0 Chris@49: ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: arma_ignore(junk); Chris@49: Chris@49: // it doesn't matter if X is an alias of S, as auxlib::svd() makes a copy of X Chris@49: Chris@49: const bool status = auxlib::svd(S, X); Chris@49: Chris@49: if(status == false) Chris@49: { Chris@49: S.reset(); Chris@49: arma_bad("svd(): failed to converge", false); Chris@49: } Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: Col Chris@49: svd Chris@49: ( Chris@49: const Base& X, Chris@49: const typename arma_blas_type_only::result* junk = 0 Chris@49: ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: arma_ignore(junk); Chris@49: Chris@49: Col out; Chris@49: Chris@49: const bool status = auxlib::svd(out, X); Chris@49: Chris@49: if(status == false) Chris@49: { Chris@49: out.reset(); Chris@49: arma_bad("svd(): failed to converge"); Chris@49: } Chris@49: Chris@49: return out; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: bool Chris@49: svd Chris@49: ( Chris@49: Mat& U, Chris@49: Col& S, Chris@49: Mat& V, Chris@49: const Base& X, Chris@49: const char* method = "", Chris@49: const typename arma_blas_type_only::result* junk = 0 Chris@49: ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: arma_ignore(junk); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: ( ((void*)(&U) == (void*)(&S)) || (&U == &V) || ((void*)(&S) == (void*)(&V)) ), Chris@49: "svd(): two or more output objects are the same object" Chris@49: ); Chris@49: Chris@49: bool use_divide_and_conquer = false; Chris@49: Chris@49: const char sig = method[0]; Chris@49: Chris@49: switch(sig) Chris@49: { Chris@49: case '\0': Chris@49: case 's': Chris@49: break; Chris@49: Chris@49: case 'd': Chris@49: use_divide_and_conquer = true; Chris@49: break; Chris@49: Chris@49: default: Chris@49: { Chris@49: arma_stop("svd(): unknown method specified"); Chris@49: return false; Chris@49: } Chris@49: } Chris@49: Chris@49: // auxlib::svd() makes an internal copy of X Chris@49: const bool status = (use_divide_and_conquer == false) ? auxlib::svd(U, S, V, X) : auxlib::svd_dc(U, S, V, X); Chris@49: Chris@49: if(status == false) Chris@49: { Chris@49: U.reset(); Chris@49: S.reset(); Chris@49: V.reset(); Chris@49: arma_bad("svd(): failed to converge", false); Chris@49: } Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: bool Chris@49: svd_econ Chris@49: ( Chris@49: Mat& U, Chris@49: Col& S, Chris@49: Mat& V, Chris@49: const Base& X, Chris@49: const char mode = 'b', Chris@49: const typename arma_blas_type_only::result* junk = 0 Chris@49: ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: arma_ignore(junk); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: ( ((void*)(&U) == (void*)(&S)) || (&U == &V) || ((void*)(&S) == (void*)(&V)) ), Chris@49: "svd_econ(): two or more output objects are the same object" Chris@49: ); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: ( (mode != 'l') && (mode != 'r') && (mode != 'b') ), Chris@49: "svd_econ(): parameter 'mode' is incorrect" Chris@49: ); Chris@49: Chris@49: Chris@49: // auxlib::svd_econ() makes an internal copy of X Chris@49: const bool status = auxlib::svd_econ(U, S, V, X, mode); Chris@49: Chris@49: if(status == false) Chris@49: { Chris@49: U.reset(); Chris@49: S.reset(); Chris@49: V.reset(); Chris@49: arma_bad("svd_econ(): failed to converge", false); Chris@49: } Chris@49: Chris@49: return status; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_deprecated Chris@49: inline Chris@49: bool Chris@49: svd_thin Chris@49: ( Chris@49: Mat& U, Chris@49: Col& S, Chris@49: Mat& V, Chris@49: const Base& X, Chris@49: const char mode = 'b', Chris@49: const typename arma_blas_type_only::result* junk = 0 Chris@49: ) Chris@49: { Chris@49: arma_ignore(junk); Chris@49: Chris@49: return svd_econ(U,S,V,X,mode); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! @}