CPPLapack
 All Classes Files Functions Variables Friends
zgematrix-lapack.hpp
Go to the documentation of this file.
00001 //=============================================================================
00002 /*! solve A*X=Y using zgesv\n
00003   The argument is zgematrix Y. Y is overwritten and become the solution X.
00004   A is also overwritten and become P*l*U. */
00005 inline long zgematrix::zgesv(zgematrix& mat)
00006 {VERBOSE_REPORT;
00007 #ifdef  CPPL_DEBUG
00008   if(m!=n || m!=mat.m){
00009     ERROR_REPORT;
00010     std::cerr << "These two matrices cannot be solved." << std::endl
00011               << "Your input was (" << m << "x" << n << ") and (" << mat.m << "x" << mat.n << ")." << std::endl;
00012     exit(1);
00013   }
00014 #endif//CPPL_DEBUG 
00015   
00016   long NRHS(mat.n), LDA(n), *IPIV(new long[n]), LDB(mat.m), INFO(1);
00017   zgesv_(n, NRHS, array, LDA, IPIV, mat.array, LDB, INFO);
00018   delete [] IPIV;
00019   
00020   if(INFO!=0){
00021     WARNING_REPORT;
00022     std::cerr << "Serious trouble happend. INFO = " << INFO << "." << std::endl;
00023   }
00024   return INFO;
00025 }
00026 
00027 //=============================================================================
00028 /*! solve A*x=y using zgesv\n
00029   The argument is zcovector y. y is overwritten and become the solution x.
00030   A is also overwritten and become P*l*U. */
00031 inline long zgematrix::zgesv(zcovector& vec)
00032 {VERBOSE_REPORT;
00033 #ifdef  CPPL_DEBUG
00034   if(m!=n || m!=vec.l){
00035     ERROR_REPORT;
00036     std::cerr << "These matrix and vector cannot be solved." << std::endl
00037               << "Your input was (" << m << "x" << n << ") and (" << vec.l << ")." << std::endl;
00038     exit(1);
00039   }
00040 #endif//CPPL_DEBUG 
00041   long NRHS(1), LDA(n), *IPIV(new long[n]), LDB(vec.l), INFO(1);
00042   zgesv_(n, NRHS, array, LDA, IPIV, vec.array, LDB, INFO);
00043   delete [] IPIV;
00044   
00045   if(INFO!=0){
00046     WARNING_REPORT;
00047     std::cerr << "Serious trouble happend. INFO = " << INFO << "." << std::endl;
00048   }
00049   return INFO;
00050 }
00051 
00052 ///////////////////////////////////////////////////////////////////////////////
00053 ///////////////////////////////////////////////////////////////////////////////
00054 ///////////////////////////////////////////////////////////////////////////////
00055 
00056 //=============================================================================
00057 /*! solve overdetermined or underdetermined A*X=Y using zgels\n*/
00058 inline long zgematrix::zgels(zgematrix& mat)
00059 {VERBOSE_REPORT;
00060 #ifdef  CPPL_DEBUG
00061   if(m!=mat.m){
00062     ERROR_REPORT;
00063     std::cerr << "These two matrices cannot be solved." << std::endl
00064               << "Your input was (" << m << "x" << n << ") and (" << mat.m << "x" << mat.n << ")." << std::endl;
00065     exit(1);
00066   }
00067 #endif//CPPL_DEBUG    
00068   
00069   if(m<n){ //underdetermined
00070     zgematrix tmp(n,mat.n);
00071     for(long i=0; i<mat.m; i++){ for(long j=0; j<mat.n; j++){
00072       tmp(i,j) =mat(i,j);
00073     }}
00074     mat.clear();
00075     swap(mat,tmp);
00076   }
00077   
00078   char TRANS('n');
00079   long NRHS(mat.n), LDA(m), LDB(mat.m),
00080     LWORK(std::min(m,n)+std::max(std::min(m,n),NRHS)), INFO(1);
00081   comple *WORK(new comple[LWORK]);
00082   zgels_(TRANS, m, n, NRHS, array, LDA, mat.array, LDB, WORK, LWORK, INFO);
00083   delete [] WORK;
00084   
00085   if(m>n){ //overdetermined
00086     zgematrix tmp(n,mat.n);
00087     for(long i=0; i<tmp.m; i++){ for(long j=0; j<tmp.n; j++){
00088       tmp(i,j) =mat(i,j);
00089     }}
00090     mat.clear();
00091     swap(mat,tmp);
00092   }
00093   
00094   if(INFO!=0){
00095     WARNING_REPORT;
00096     std::cerr << "Serious trouble happend. INFO = " << INFO << "." << std::endl;
00097   }
00098   return INFO;
00099 }
00100 
00101 //=============================================================================
00102 /*! solve overdetermined or underdetermined A*x=y using zgels\n*/
00103 inline long zgematrix::zgels(zcovector& vec)
00104 {VERBOSE_REPORT;
00105 #ifdef  CPPL_DEBUG
00106   if(m!=vec.l){
00107     ERROR_REPORT;
00108     std::cerr << "These matrix and vector cannot be solved." << std::endl
00109               << "Your input was (" << m << "x" << n << ") and (" << vec.l << ")." << std::endl;
00110     exit(1);
00111   }
00112 #endif//CPPL_DEBUG    
00113   
00114   if(m<n){ //underdetermined
00115     zcovector tmp(n);
00116     for(long i=0; i<vec.l; i++){ tmp(i)=vec(i); }
00117     vec.clear();
00118     swap(vec,tmp);
00119   }
00120   
00121   char TRANS('n');
00122   long NRHS(1), LDA(m), LDB(vec.l),
00123     LWORK(std::min(m,n)+std::max(std::min(m,n),NRHS)), INFO(1);
00124   comple *WORK(new comple[LWORK]);
00125   zgels_(TRANS, m, n, NRHS, array, LDA, vec.array, LDB, WORK, LWORK, INFO);
00126   delete [] WORK;
00127   
00128   if(m>n){ //overdetermined
00129     zcovector tmp(n);
00130     for(long i=0; i<tmp.l; i++){ tmp(i)=vec(i); }
00131     vec.clear();
00132     swap(vec,tmp);
00133   }
00134   
00135   if(INFO!=0){
00136     WARNING_REPORT;
00137     std::cerr << "Serious trouble happend. INFO = " << INFO << "." << std::endl;
00138   }
00139   return INFO;
00140 }
00141 
00142 //=============================================================================
00143 /*! solve overdetermined or underdetermined A*X=Y using zgels
00144   with the sum of residual squares output\n
00145   The residual is set as the columnwise sum of residual squares 
00146   for overdetermined problems 
00147   while it is always zero for underdetermined problems.
00148 */
00149 inline long zgematrix::zgels(zgematrix& mat, drovector& residual)
00150 {VERBOSE_REPORT;
00151 #ifdef  CPPL_DEBUG
00152   if(m!=mat.m){
00153     ERROR_REPORT;
00154     std::cerr << "These two matrices cannot be solved." << std::endl
00155               << "Your input was (" << m << "x" << n << ") and (" << mat.m << "x" << mat.n << ")." << std::endl;
00156     exit(1);
00157   }
00158 #endif//CPPL_DEBUG
00159   
00160   residual.resize(mat.n); residual.zero();
00161   
00162   if(m<n){ //underdetermined
00163     zgematrix tmp(n,mat.n);
00164     for(long i=0; i<mat.m; i++){ for(long j=0; j<mat.n; j++){
00165       tmp(i,j) =mat(i,j);
00166     }}
00167     mat.clear();
00168     swap(mat,tmp);
00169   }
00170   
00171   char TRANS('n');
00172   long NRHS(mat.n), LDA(m), LDB(mat.m),
00173     LWORK(std::min(m,n)+std::max(std::min(m,n),NRHS)), INFO(1);
00174   comple *WORK(new comple[LWORK]);
00175   zgels_(TRANS, m, n, NRHS, array, LDA, mat.array, LDB, WORK, LWORK, INFO);
00176   delete [] WORK;
00177   
00178   if(m>n){ //overdetermined
00179     for(long i=0; i<residual.l; i++){ for(long j=0; j<m-n; j++){
00180       residual(i) += std::norm(mat(n+j,i));
00181     }}
00182     
00183     zgematrix tmp(n,mat.n);
00184     for(long i=0; i<tmp.m; i++){ for(long j=0; j<tmp.n; j++){
00185       tmp(i,j) =mat(i,j);
00186     }}
00187     mat.clear();
00188     swap(mat,tmp);
00189   }
00190   
00191   if(INFO!=0){
00192     WARNING_REPORT;
00193     std::cerr << "Serious trouble happend. INFO = " << INFO << "." << std::endl;
00194   }
00195   return INFO;
00196 }
00197 
00198 //=============================================================================
00199 /*! solve overdetermined or underdetermined A*x=y using zgels
00200   with the sum of residual squares output\n
00201   The residual is set as the sum of residual squares for overdetermined problems
00202   while it is always zero for underdetermined problems.
00203 */
00204 inline long zgematrix::zgels(zcovector& vec, double& residual)
00205 {VERBOSE_REPORT;
00206 #ifdef  CPPL_DEBUG
00207   if(m!=vec.l){
00208     ERROR_REPORT;
00209     std::cerr << "These matrix and vector cannot be solved." << std::endl
00210               << "Your input was (" << m << "x" << n << ") and (" << vec.l << ")." << std::endl;
00211     exit(1);
00212   }
00213 #endif//CPPL_DEBUG    
00214   
00215   residual=0.0;
00216   
00217   if(m<n){ //underdetermined
00218     zcovector tmp(n);
00219     for(long i=0; i<vec.l; i++){ tmp(i)=vec(i); }
00220     vec.clear();
00221     swap(vec,tmp);
00222   }
00223   
00224   char TRANS('n');
00225   long NRHS(1), LDA(m), LDB(vec.l),
00226     LWORK(std::min(m,n)+std::max(std::min(m,n),NRHS)), INFO(1);
00227   comple *WORK(new comple[LWORK]);
00228   zgels_(TRANS, m, n, NRHS, array, LDA, vec.array, LDB, WORK, LWORK, INFO);
00229   delete [] WORK;
00230   
00231   if(m>n){ //overdetermined
00232     for(long i=0; i<m-n; i++){ residual+=std::norm(vec(n+i)); }
00233     
00234     zcovector tmp(n);
00235     for(long i=0; i<tmp.l; i++){ tmp(i)=vec(i); }
00236     vec.clear();
00237     swap(vec,tmp);
00238   }
00239   
00240   if(INFO!=0){
00241     WARNING_REPORT;
00242     std::cerr << "Serious trouble happend. INFO = " << INFO << "." << std::endl;
00243   }
00244   return INFO;
00245 }
00246 
00247 ///////////////////////////////////////////////////////////////////////////////
00248 ///////////////////////////////////////////////////////////////////////////////
00249 ///////////////////////////////////////////////////////////////////////////////
00250 
00251 //=============================================================================
00252 /*! calculate the least-squares-least-norm solution 
00253   for overdetermined or underdetermined A*x=y using zgelss\n */
00254 inline long zgematrix::zgelss(zcovector& B, dcovector& S, long& RANK,
00255                               const double RCOND =-1. )
00256 {VERBOSE_REPORT;
00257 #ifdef  CPPL_DEBUG
00258   if(m!=B.l){
00259     ERROR_REPORT;
00260     std::cerr << "These matrix and vector cannot be solved." << std::endl
00261               << "Your input was (" << m << "x" << n << ") and (" << B.l << ")." << std::endl;
00262     exit(1);
00263   }
00264 #endif//CPPL_DEBUG    
00265   
00266   if(m<n){ //underdetermined
00267     zcovector tmp(n);
00268     for(long i=0; i<B.l; i++){ tmp(i)=B(i); }
00269     B.clear();
00270     swap(B,tmp);
00271   }
00272   
00273   S.resize(std::min(m,n));
00274   
00275   long NRHS(1), LDA(m), LDB(B.l),
00276     LWORK(2*std::min(m,n) +std::max(std::max(m,n),NRHS)), INFO(1);
00277   double *RWORK(new double[5*std::min(m,n)]);
00278   comple *WORK(new comple[LWORK]);
00279   zgelss_(m, n, NRHS, array, LDA, B.array, LDB, S.array, RCOND, RANK, 
00280           WORK, LWORK, RWORK, INFO);
00281   delete [] RWORK; delete [] WORK;
00282   
00283   if(INFO!=0){
00284     WARNING_REPORT;
00285     std::cerr << "Serious trouble happend. INFO = " << INFO << "." << std::endl;
00286   }
00287   return INFO;
00288 }
00289 
00290 //=============================================================================
00291 /*! calculate the least-squares-least-norm solution 
00292   for overdetermined or underdetermined A*x=y using zgelss\n */
00293 inline long zgematrix::zgelss(zgematrix& B, dcovector& S, long& RANK,
00294                               const double RCOND =-1. )
00295 {VERBOSE_REPORT;
00296 #ifdef  CPPL_DEBUG
00297   if(m!=B.m){
00298     ERROR_REPORT;
00299     std::cerr << "These matrix and vector cannot be solved." << std::endl
00300               << "Your input was (" << m << "x" << n << ") and (" << B.m << "x" << B.n << ")." << std::endl;
00301     exit(1);
00302   }
00303 #endif//CPPL_DEBUG    
00304   
00305   if(m<n){ //underdetermined
00306     zgematrix tmp(n,B.n);
00307     for(long i=0; i<B.m; i++){
00308       for(long j=0; j<B.n; j++){
00309         tmp(i,j)=B(i,j);
00310       }
00311     }
00312     B.clear();
00313     swap(B,tmp);
00314   }
00315   
00316   S.resize(std::min(m,n));
00317   
00318   long NRHS(B.n), LDA(m), LDB(B.m),
00319     LWORK(2*std::min(m,n) +std::max(std::max(m,n),NRHS)), INFO(1);
00320   double *RWORK(new double[5*std::min(m,n)]);
00321   comple *WORK(new comple[LWORK]);
00322   zgelss_(m, n, NRHS, array, LDA, B.array, LDB, S.array, RCOND, RANK, 
00323           WORK, LWORK, RWORK, INFO);
00324   delete [] RWORK; delete [] WORK;
00325   
00326   if(INFO!=0){
00327     WARNING_REPORT;
00328     std::cerr << "Serious trouble happend. INFO = " << INFO << "." << std::endl;
00329   }
00330   return INFO;
00331 }
00332 
00333 ///////////////////////////////////////////////////////////////////////////////
00334 ///////////////////////////////////////////////////////////////////////////////
00335 ///////////////////////////////////////////////////////////////////////////////
00336 
00337 //=============================================================================
00338 /*! calculate eigenvalues\n
00339   The argument need not to be initialized.
00340   w is overwitten and become eigenvalues.
00341   This matrix is also overwritten. */
00342 inline long zgematrix::zgeev(std::vector< comple >& w)
00343 {VERBOSE_REPORT;
00344 #ifdef  CPPL_DEBUG
00345   if(m!=n){
00346     ERROR_REPORT;
00347     std::cerr << "This matrix cannot have eigenvalues." << std::endl
00348               << "Your input was (" << m << "x" << n << ")." << std::endl;
00349     exit(1);
00350   }
00351 #endif//CPPL_DEBUG
00352   
00353   w.resize(n);
00354   char JOBVL('n'), JOBVR('n');
00355   long LDA(n), LDVL(1), LDVR(1), LWORK(4*n), INFO(1);
00356   double *RWORK(new double[2*n]);
00357   comple *VL(NULL), *VR(NULL), 
00358     *WORK(new comple[LWORK]);
00359   zgeev_(JOBVL, JOBVR, n, array, LDA, &w[0], 
00360          VL, LDVL, VR, LDVR, WORK, LWORK, RWORK, INFO);
00361   delete [] RWORK; delete [] WORK; delete [] VL; delete [] VR;
00362   
00363   if(INFO!=0){
00364     WARNING_REPORT;
00365     std::cerr << "Serious trouble happend. INFO = " << INFO << "." << std::endl;
00366   }
00367   return INFO;
00368 }
00369 
00370 //=============================================================================
00371 /*! calculate eigenvalues and right eigenvectors\n
00372   All of the arguments need not to be initialized.
00373   w, vr are overwitten and become eigenvalues and right eigenvectors, 
00374   respectively. 
00375   This matrix is also overwritten. */
00376 inline long zgematrix::zgeev(std::vector< comple >& w,
00377                              std::vector<zcovector>& vr)
00378 {VERBOSE_REPORT;
00379 #ifdef  CPPL_DEBUG
00380   if(m!=n){
00381     ERROR_REPORT;
00382     std::cerr << "This matrix cannot have eigenvalues." << std::endl
00383               << "Your input was (" << m << "x" << n << ")." << std::endl;
00384     exit(1);
00385   }
00386 #endif//CPPL_DEBUG
00387   
00388   w.resize(n);  vr.resize(n);
00389   for(long i=0; i<n; i++){ vr[i].resize(n); }
00390   zgematrix VR(n,n);
00391   char JOBVL('n'), JOBVR('V');
00392   long LDA(n), LDVL(1), LDVR(n), LWORK(4*n), INFO(1);
00393   double *RWORK(new double[2*n]);
00394   comple *VL(NULL), *WORK(new comple[LWORK]);
00395   zgeev_(JOBVL, JOBVR, n, array, LDA, &w[0], 
00396          VL, LDVL, VR.array, LDVR, WORK, LWORK, RWORK, INFO);
00397   delete [] RWORK; delete [] WORK; delete [] VL;
00398   
00399   //// forming ////
00400   for(long j=0; j<n; j++){  for(long i=0; i<n; i++){
00401     vr[j](i) = VR(i,j);
00402   }}
00403   
00404   if(INFO!=0){
00405     WARNING_REPORT;
00406     std::cerr << "Serious trouble happend. INFO = " << INFO << "." << std::endl;
00407   }
00408   return INFO;
00409 }
00410 
00411 //=============================================================================
00412 /*! calculate eigenvalues and left eigenvectors\n
00413   All of the arguments need not to be initialized.
00414   w, vr are overwitten and become eigenvalues and left eigenvectors, 
00415   respectively. 
00416   This matrix is also overwritten. */
00417 inline long zgematrix::zgeev(std::vector< comple >& w,
00418                              std::vector<zrovector>& vl)
00419 {VERBOSE_REPORT;
00420 #ifdef  CPPL_DEBUG
00421   if(m!=n){
00422     ERROR_REPORT;
00423     std::cerr << "This matrix cannot have eigenvalues." << std::endl
00424               << "Your input was (" << m << "x" << n << ")." << std::endl;
00425     exit(1);
00426   }
00427 #endif//CPPL_DEBUG
00428   
00429   w.resize(n);  vl.resize(n);
00430   for(long i=0; i<n; i++){ vl[i].resize(n); }
00431   zgematrix VL(n,n);
00432   char JOBVL('V'), JOBVR('n');
00433   long LDA(n), LDVL(n), LDVR(1), LWORK(4*n), INFO(1);
00434   double *RWORK(new double[2*n]);
00435   comple *VR(NULL), *WORK(new comple[LWORK]);
00436   zgeev_(JOBVL, JOBVR, n, array, LDA, &w[0], 
00437          VL.array, LDVL, VR, LDVR, WORK, LWORK, RWORK, INFO);
00438   delete [] RWORK; delete [] WORK; delete [] VR;
00439   
00440   //// forming ////
00441   for(long j=0; j<n; j++){ for(long i=0; i<n; i++){
00442     vl[j](i) = std::conj(VL(i,j));
00443   }}
00444   
00445   if(INFO!=0){
00446     WARNING_REPORT;
00447     std::cerr << "Serious trouble happend. INFO = " << INFO << "." << std::endl;
00448   }
00449   return INFO;
00450 }
00451 
00452 
00453 ///////////////////////////////////////////////////////////////////////////////
00454 ///////////////////////////////////////////////////////////////////////////////
00455 ///////////////////////////////////////////////////////////////////////////////
00456 
00457 //=============================================================================
00458 //inline long zgematrix::zgegv()
00459 
00460 
00461 ///////////////////////////////////////////////////////////////////////////////
00462 ///////////////////////////////////////////////////////////////////////////////
00463 ///////////////////////////////////////////////////////////////////////////////
00464 
00465 //=============================================================================
00466 /*! compute the singular value decomposition (SVD)\n
00467   The arguments are zcocector S, zgematrix U and VT.
00468   All of them need not to be initialized.
00469   S, U and VT are overwitten and become singular values, left singular vectors,
00470   and right singular vectors respectively.
00471   This matrix also overwritten.
00472 */
00473 inline long zgematrix::zgesvd(dcovector& S, zgematrix& U, zgematrix& VT)
00474 {VERBOSE_REPORT;
00475   char JOBU('A'), JOBVT('A');
00476   long LDA(m), LDU(m), LDVT(n),
00477     LWORK(std::max(3*std::min(m,n)+std::max(m,n),5*std::min(m,n))), INFO(1);
00478   double *RWORK(new double[5*std::min(m,n)]);
00479   comple *WORK(new comple[LWORK]);
00480   S.resize(std::min(m,n)); U.resize(LDU,m); VT.resize(LDVT,n);
00481   
00482   zgesvd_(JOBU, JOBVT, m, n, array, LDA, S.array, U.array, 
00483           LDU, VT.array, LDVT, WORK, LWORK, RWORK, INFO);
00484   delete [] RWORK; delete [] WORK;
00485   
00486   if(INFO!=0){
00487     WARNING_REPORT;
00488     std::cerr << "Serious trouble happend. INFO = " << INFO << "." << std::endl;
00489   }
00490   return INFO;
00491 }
 All Classes Files Functions Variables Friends