00001 // Copyright (C) 2009-2011 NICTA (www.nicta.com.au) 00002 // Copyright (C) 2009-2011 Conrad Sanderson 00003 // Copyright (C) 2009-2010 Dimitrios Bouzas 00004 // Copyright (C) 2011 Stanislav Funiak 00005 // 00006 // This file is part of the Armadillo C++ library. 00007 // It is provided without any warranty of fitness 00008 // for any purpose. You can redistribute this file 00009 // and/or modify it under the terms of the GNU 00010 // Lesser General Public License (LGPL) as published 00011 // by the Free Software Foundation, either version 3 00012 // of the License or (at your option) any later version. 00013 // (see http://www.opensource.org/licenses for more info) 00014 00015 00018 00019 00020 00021 template<typename T1> 00022 inline 00023 arma_warn_unused 00024 uword 00025 rank 00026 ( 00027 const Base<typename T1::elem_type,T1>& X, 00028 typename T1::pod_type tol = 0.0, 00029 const typename arma_blas_type_only<typename T1::elem_type>::result* junk = 0 00030 ) 00031 { 00032 arma_extra_debug_sigprint(); 00033 arma_ignore(junk); 00034 00035 typedef typename T1::elem_type eT; 00036 typedef typename T1::pod_type T; 00037 00038 uword X_n_rows; 00039 uword X_n_cols; 00040 Col<T> s; 00041 00042 const bool status = auxlib::svd(s, X, X_n_rows, X_n_cols); 00043 const uword n_elem = s.n_elem; 00044 00045 if(status == true) 00046 { 00047 if( (tol == T(0)) && (n_elem > 0) ) 00048 { 00049 tol = (std::max)(X_n_rows, X_n_cols) * eop_aux::direct_eps(max(s)); 00050 } 00051 00052 // count non zero valued elements in s 00053 00054 const T* s_mem = s.memptr(); 00055 uword count = 0; 00056 00057 for(uword i=0; i<n_elem; ++i) 00058 { 00059 if(s_mem[i] > tol) 00060 { 00061 ++count; 00062 } 00063 } 00064 00065 return count; 00066 } 00067 else 00068 { 00069 arma_bad("rank(): failed to converge"); 00070 00071 return uword(0); 00072 } 00073 } 00074 00075 00076