/*! solve overdetermined or underdetermined A*x=y using dgels with the sum of residual squares output\n The residual is set as the sum of residual squares for overdetermined problems while it is always zero for underdetermined problems. */ inline long dgematrix::dgels(dcovector& vec, double& residual) { #ifdef CPPL_VERBOSE std::cerr << "# [MARK] dgematrix::dgels(dcovector&, double&)" << std::endl; #endif//CPPL_VERBOSE #ifdef CPPL_DEBUG if(M!=vec.L){ std::cerr << "[ERROR] dgematrix::dgels(dcovector&, double&) " << std::endl << "These matrix and vector cannot be solved." << std::endl << "Your input was (" << M << "x" << N << ") and (" << vec.L << ")." << std::endl; exit(1); } #endif//CPPL_DEBUG residual=0.0; if(M<N){ //underdetermined dcovector tmp(N); for(long i=0; i<vec.L; i++){ tmp(i)=vec(i); } vec.clear(); swap(vec,tmp); } char TRANS('N'); long NRHS(1), LDA(M), LDB(vec.L), LWORK(min(M,N)+max(min(M,N),NRHS)), INFO(1); double *WORK(new double[LWORK]); dgels_(TRANS, M, N, NRHS, Array, LDA, vec.Array, LDB, WORK, LWORK, INFO); delete [] WORK; if(M>N){ //overdetermined for(long i=0; i<M-N; i++){ residual+=std::pow(vec(N+i),2.0); } dcovector tmp(N); for(long i=0; i<tmp.L; i++){ tmp(i)=vec(i); } vec.clear(); swap(vec,tmp); } if(INFO!=0){ std::cerr << "[WARNING] dgematrix::dgels(dcovector&, double&) " << "Serious trouble happend. INFO = " << INFO << "." << std::endl; } return INFO; }
/*! calculate the least-squares-least-norm solution for overdetermined or underdetermined A*x=y using dgelss\n */ inline long dgematrix::dgelss(dcovector& B, dcovector& S, long& RANK, const double RCOND =-1. ) { #ifdef CPPL_VERBOSE std::cerr << "# [MARK] dgematrix::dgelss(dcovector&, dcovector&, long&, const double)" << std::endl; #endif//CPPL_VERBOSE #ifdef CPPL_DEBUG if(M!=B.L){ std::cerr << "[ERROR] dgematrix::dgelss" << "(dcovector&, dcovector&, long, double) " << std::endl << "These matrix and vector cannot be solved." << std::endl << "Your input was (" << M << "x" << N << ") and (" << B.L << ")." << std::endl; exit(1); } #endif//CPPL_DEBUG if(M<N){ //underdetermined dcovector tmp(N); for(long i=0; i<B.L; i++){ tmp(i)=B(i); } B.clear(); swap(B,tmp); } S.resize(min(M,N)); long NRHS(1), LDA(M), LDB(B.L), LWORK(3*min(M,N)+max(max(2*min(M,N),max(M,N)), NRHS)), INFO(1); double *WORK(new double[LWORK]); dgelss_(M, N, NRHS, Array, LDA, B.Array, LDB, S.Array, RCOND, RANK, WORK, LWORK, INFO); delete [] WORK; if(INFO!=0){ std::cerr << "[WARNING] dgematrix::dgelss" << "(dcovector&, docvector&, long, const double) " << "Serious trouble happend. INFO = " << INFO << "." << std::endl; } return INFO; }