Changeset 2572 in Sophya for trunk/SophyaExt/LinAlg


Ignore:
Timestamp:
Jul 28, 2004, 4:21:21 PM (21 years ago)
Author:
cmv
Message:

implementation calcul lwork avec lwork=-1 cmv 28/07/04

Location:
trunk/SophyaExt/LinAlg
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaExt/LinAlg/intflapack.cc

    r2567 r2572  
    199199}
    200200
    201 // --- ATTENTION BUG POSSIBLE dans l'avenir (CMV) --- REZA A LIRE S.T.P.
    202 // -> Cette connerie de Fortran/C interface
    203 // Dans les routines fortran de lapack:
    204 // Appel depuis le C avec:
    205 //   int_4 lwork = -1;
    206 // SUBROUTINE SSYSV( UPLO,N,NRHS,A,LDA,IPIV,B,LDB,WORK,LWORK,INFO)
    207 //   INTEGER            INFO, LDA, LDB, LWORK, N, NRHS
    208 //   LOGICAL            LQUERY
    209 //   LQUERY = ( LWORK.EQ.-1 )
    210 //   ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN
    211 //    ==> le test est bien interprete sous Linux mais pas sous OSF
    212 //    ==> Sous OSF "LWORK.EQ.-1" est FALSE quand on passe lwork=-1 par argument
    213 //    ==> POUR REZA: confusion entier 4 / 8 bits ??? (bizarre on l'aurait vu avant?)
    214201////////////////////////////////////////////////////////////////////////////////////
    215202template <class T>
    216203int_4 LapackServer<T>::ilaenv_en_C(int_4 ispec,char *name,char *opts,int_4 n1,int_4 n2,int_4 n3,int_4 n4)
    217204{
    218  int_4 nc1 = strlen(name);
    219  int_4 nc2 = strlen(opts);
    220  int_4 rc=0;
     205 int_4 nc1 = strlen(name), nc2 = strlen(opts), rc=0;
    221206 rc = ilaenv_(&ispec,name,opts,&n1,&n2,&n3,&n4,nc1,nc2);
    222207 //cout<<"ilaenv_en_C("<<ispec<<","<<name<<"("<<nc1<<"),"<<opts<<"("<<nc2<<"),"
    223208 //    <<n1<<","<<n2<<","<<n3<<","<<n4<<") = "<<rc<<endl;
    224209 return rc;
     210}
     211
     212template <class T>
     213int_4 LapackServer<T>::type2i4(void *val,int nbytes)
     214// Retourne un entier contenant la valeur contenue dans val
     215// - nbytes = nombre de bytes dans le contenu de val
     216// ex: r_4 x = 3.4;              type2i4(&x,4) -> 3
     217// ex: r_8 x = 3.4;              type2i4(&x,8) -> 3
     218// ex: complex<r_4> x(3.4,7.8);  type2i4(&x,4) -> 3
     219// ex: complex<r_8> x(3.4,7.8);  type2i4(&x,8) -> 3
     220{
     221  r_4* x4; r_8* x8; int_4 lw=0;
     222  if(nbytes==4) {x4 = (r_4*)val; lw = (int_4)(*x4);}
     223    else        {x8 = (r_8*)val; lw = (int_4)(*x8);}
     224  return lw;
    225225}
    226226
     
    317317  int_4 lwork = -1;
    318318  T * work = NULL;
     319  T wkget[2];
    319320
    320321  char uplo = 'U'; // char uplo = 'L';
     
    322323
    323324  if (typeid(T) == typeid(r_4) ) {
    324     lwork = ilaenv_en_C(1,"SSYTRF",struplo,n,-1,-1,-1) * n;
    325     work = new T[lwork  +GARDMEM];
     325    ssysv_(&uplo, &n, &nrhs, (r_4 *)a.Data(), &lda, ipiv, (r_4 *)b.Data(), &ldb,
     326          (r_4 *)wkget, &lwork, &info);
     327    lwork = type2i4(&wkget[0],4); work = new T[lwork  +GARDMEM];
    326328    ssysv_(&uplo, &n, &nrhs, (r_4 *)a.Data(), &lda, ipiv, (r_4 *)b.Data(), &ldb,
    327329          (r_4 *)work, &lwork, &info);
    328330  } else if (typeid(T) == typeid(r_8) )  {
    329     lwork = ilaenv_en_C(1,"DSYTRF",struplo,n,-1,-1,-1) * n;
    330     work = new T[lwork  +GARDMEM];
     331    dsysv_(&uplo, &n, &nrhs, (r_8 *)a.Data(), &lda, ipiv, (r_8 *)b.Data(), &ldb,
     332          (r_8 *)wkget, &lwork, &info);
     333    lwork = type2i4(&wkget[0],8); work = new T[lwork  +GARDMEM];
    331334    dsysv_(&uplo, &n, &nrhs, (r_8 *)a.Data(), &lda, ipiv, (r_8 *)b.Data(), &ldb,
    332335          (r_8 *)work, &lwork, &info);
    333336  } else if (typeid(T) == typeid(complex<r_4>) )  {
    334     lwork = ilaenv_en_C(1,"CSYTRF",struplo,n,-1,-1,-1) * n;
    335     work = new T[lwork  +GARDMEM];
     337    csysv_(&uplo, &n, &nrhs, (complex<r_4> *)a.Data(), &lda, ipiv,
     338          (complex<r_4> *)b.Data(), &ldb,
     339          (complex<r_4> *)wkget, &lwork, &info);
     340    lwork = type2i4(&wkget[0],4); work = new T[lwork  +GARDMEM];
    336341    csysv_(&uplo, &n, &nrhs, (complex<r_4> *)a.Data(), &lda, ipiv,
    337342          (complex<r_4> *)b.Data(), &ldb,
    338343          (complex<r_4> *)work, &lwork, &info);
    339344  } else if (typeid(T) == typeid(complex<r_8>) )  {
    340     lwork = ilaenv_en_C(1,"ZSYTRF",struplo,n,-1,-1,-1) * n;
    341     work = new T[lwork  +GARDMEM];
     345    zsysv_(&uplo, &n, &nrhs, (complex<r_8> *)a.Data(), &lda, ipiv,
     346          (complex<r_8> *)b.Data(), &ldb,
     347          (complex<r_8> *)wkget, &lwork, &info);
     348    lwork = type2i4(&wkget[0],8); work = new T[lwork  +GARDMEM];
    342349    zsysv_(&uplo, &n, &nrhs, (complex<r_8> *)a.Data(), &lda, ipiv,
    343350          (complex<r_8> *)b.Data(), &ldb,
     
    410417  if (maxmnrhs < 1) maxmnrhs = 1;
    411418 
    412   int_4 lwork = minmn+maxmnrhs*5;
    413   T * work = new T[lwork];
     419  int_4 lwork = -1; //minmn+maxmnrhs*5;
     420  T * work = NULL;
     421  T wkget[2];
    414422
    415423  char trans = 'N';
    416424 
    417   if (typeid(T) == typeid(r_4) )
     425  if (typeid(T) == typeid(r_4) ) {
     426    sgels_(&trans, &m, &n, &nrhs, (r_4 *)a.Data(), &lda,
     427           (r_4 *)b.Data(), &ldb, (r_4 *)wkget, &lwork, &info);
     428    lwork = type2i4(&wkget[0],4); work = new T[lwork  +GARDMEM];
    418429    sgels_(&trans, &m, &n, &nrhs, (r_4 *)a.Data(), &lda,
    419430           (r_4 *)b.Data(), &ldb, (r_4 *)work, &lwork, &info);
    420   else if (typeid(T) == typeid(r_8) )
     431  } else if (typeid(T) == typeid(r_8) )  {
     432    dgels_(&trans, &m, &n, &nrhs, (r_8 *)a.Data(), &lda,
     433           (r_8 *)b.Data(), &ldb, (r_8 *)wkget, &lwork, &info);
     434    lwork = type2i4(&wkget[0],8); work = new T[lwork  +GARDMEM];
    421435    dgels_(&trans, &m, &n, &nrhs, (r_8 *)a.Data(), &lda,
    422436           (r_8 *)b.Data(), &ldb, (r_8 *)work, &lwork, &info);
    423   else if (typeid(T) == typeid(complex<r_4>) )
     437  } else if (typeid(T) == typeid(complex<r_4>) )  {
     438    cgels_(&trans, &m, &n, &nrhs, (complex<r_4> *)a.Data(), &lda,
     439           (complex<r_4> *)b.Data(), &ldb, (complex<r_4> *)wkget, &lwork, &info);
     440    lwork = type2i4(&wkget[0],4); work = new T[lwork  +GARDMEM];
    424441    cgels_(&trans, &m, &n, &nrhs, (complex<r_4> *)a.Data(), &lda,
    425442           (complex<r_4> *)b.Data(), &ldb, (complex<r_4> *)work, &lwork, &info);
    426   else if (typeid(T) == typeid(complex<r_8>) )
     443  } else if (typeid(T) == typeid(complex<r_8>) )  {
     444    zgels_(&trans, &m, &n, &nrhs, (complex<r_8> *)a.Data(), &lda,
     445           (complex<r_8> *)b.Data(), &ldb, (complex<r_8> *)wkget, &lwork, &info);
     446    lwork = type2i4(&wkget[0],8); work = new T[lwork  +GARDMEM];
    427447    zgels_(&trans, &m, &n, &nrhs, (complex<r_8> *)a.Data(), &lda,
    428448           (complex<r_8> *)b.Data(), &ldb, (complex<r_8> *)work, &lwork, &info);
    429   else {
    430     delete[] work;
     449  } else {
     450    if(work) delete [] work; work=NULL;
    431451    string tn = typeid(T).name();
    432452    cerr << " LapackServer::LeastSquareSolve(a,b) - Unsupported DataType T = " << tn << endl;
    433453    throw TypeMismatchExc("LapackServer::LeastSquareSolve(a,b) - Unsupported DataType (T)");
    434454  }
    435   delete[] work;
     455  if(work) delete [] work;
    436456  return(info);
    437457}
     
    447467  \param b : input vector b overwritten by solution on output (beware of size changing)
    448468  \param x : output matrix of solutions.
     469  \param rank : output the rank of the matrix.
    449470  \return : return code from lapack driver _gelsd()
    450471  \warning : b is not resized.
     
    462483  int_4 n = a.NCols();
    463484
    464   if(b.NRows() != n)
     485  if(b.NRows() != m)
    465486     throw(SzMismatchError("LapackServer::LeastSquareSolveSVD_DC(a,b) bad matching dim between a and b"));
    466487
     
    469490  int_4 maxmn = (m > n) ? m : n;
    470491
    471   if(b.NRows() != n)
    472      throw(SzMismatchError("LapackServer::LeastSquareSolveSVD_DC(a,b) bad matching dim between a and b"));
    473 
    474492  int_4 lda = m;
    475493  int_4 ldb = maxmn;
    476494  int_4 info;
    477495
    478   { // Use {} for automatic des-alloc bsave
    479   TMatrix<T> bsave(n,nrhs); bsave.SetMemoryMapping(BaseArray::FortranMemoryMapping);
     496  { // Use {} for automatic des-allocation of "bsave"
     497  TMatrix<T> bsave(m,nrhs); bsave.SetMemoryMapping(BaseArray::FortranMemoryMapping);
    480498  bsave = b;
    481499  b.ReSize(maxmn,nrhs); b = (T) 0;
    482   for(int i=0;i<n;i++) for(int j=0;j<nrhs;j++) b(i,j) = bsave(i,j);
    483   }
     500  for(int i=0;i<m;i++) for(int j=0;j<nrhs;j++) b(i,j) = bsave(i,j);
     501  } // Use {} for automatic des-allocation of "bsave"
    484502  s.ReSize(minmn);
    485503 
    486   int_4 smlsiz = 25;
     504  int_4 smlsiz = 25;  // Normallement ilaenv_en_C(9,...) renvoie toujours 25
    487505  if(typeid(T) == typeid(r_4) )               smlsiz = ilaenv_en_C(9,"SGELSD"," ",0,0,0,0);
    488506  else if(typeid(T) == typeid(r_8) )          smlsiz = ilaenv_en_C(9,"DGELSD"," ",0,0,0,0);
     
    490508  else if(typeid(T) == typeid(complex<r_8>) ) smlsiz = ilaenv_en_C(9,"ZGELSD"," ",0,0,0,0);
    491509  if(smlsiz<0) smlsiz = 0;
    492 
    493510  r_8 dum = log((r_8)minmn/(r_8)(smlsiz+1.)) / log(2.);
    494511  int_4 nlvl = int_4(dum) + 1; if(nlvl<0) nlvl = 0;
    495512
     513  T * work = NULL;
     514  int_4 * iwork = NULL;
     515  int_4 lwork=-1, lrwork;
     516  T wkget[2];
     517
    496518  if(typeid(T) == typeid(r_4) ) {
    497     int_4 lwork = 12*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + minmn*nrhs + (smlsiz+1)*(smlsiz+1);
    498     r_4* work = new r_4[lwork +GARDMEM];
    499     int_4* iwork = new int_4[3*minmn*nlvl+11*minmn  +GARDMEM];
    500519    r_4* sloc = new r_4[minmn];
    501520    r_4 srcond = rcond;
     521    iwork = new int_4[3*minmn*nlvl+11*minmn  +GARDMEM];
     522    sgelsd_(&m,&n,&nrhs,(r_4*)a.Data(),&lda,
     523           (r_4*)b.Data(),&ldb,(r_4*)sloc,&srcond,&rank,
     524           (r_4*)wkget,&lwork,(int_4*)iwork,&info);
     525    lwork = type2i4(&wkget[0],4); work = new T[lwork +GARDMEM];
    502526    sgelsd_(&m,&n,&nrhs,(r_4*)a.Data(),&lda,
    503527           (r_4*)b.Data(),&ldb,(r_4*)sloc,&srcond,&rank,
    504528           (r_4*)work,&lwork,(int_4*)iwork,&info);
    505529    for(int_4 i=0;i<minmn;i++) s(i) = sloc[i];
    506     delete [] sloc; delete [] work; delete [] iwork;
     530    delete [] sloc;
    507531  } else if(typeid(T) == typeid(r_8) )  {
    508     int_4 lwork = 12*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + minmn*nrhs + (smlsiz+1)*(smlsiz+1);
    509     r_8* work = new r_8[lwork +GARDMEM];
    510     int_4* iwork = new int_4[3*minmn*nlvl+11*minmn  +GARDMEM];
     532    iwork = new int_4[3*minmn*nlvl+11*minmn  +GARDMEM];
     533    dgelsd_(&m,&n,&nrhs,(r_8*)a.Data(),&lda,
     534           (r_8*)b.Data(),&ldb,(r_8*)s.Data(),&rcond,&rank,
     535           (r_8*)wkget,&lwork,(int_4*)iwork,&info);
     536    lwork = type2i4(&wkget[0],8); work = new T[lwork +GARDMEM];
    511537    dgelsd_(&m,&n,&nrhs,(r_8*)a.Data(),&lda,
    512538           (r_8*)b.Data(),&ldb,(r_8*)s.Data(),&rcond,&rank,
    513539           (r_8*)work,&lwork,(int_4*)iwork,&info);
    514     delete [] work; delete [] iwork;
    515540  } else if(typeid(T) == typeid(complex<r_4>) )  {
    516     int_4 lwork = 2*minmn + minmn*nrhs;
    517     complex<r_4>* work = new complex<r_4>[lwork +GARDMEM];
    518     int_4 lrwork = 10*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + 3*smlsiz*nrhs + (smlsiz+1)*(smlsiz+1);
     541    // Cf meme remarque que ci-dessous (complex<r_8)
     542    lrwork = 10*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + 3*smlsiz*nrhs + (smlsiz+1)*(smlsiz+1);
     543    int_4 lrwork_d = 12*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + minmn*nrhs + (smlsiz+1)*(smlsiz+1);
     544    if(lrwork_d > lrwork) lrwork = lrwork_d;
    519545    r_4* rwork = new r_4[lrwork +GARDMEM];
    520     int_4* iwork = new int_4[3*minmn*nlvl+11*minmn  +GARDMEM];
     546    iwork = new int_4[3*minmn*nlvl+11*minmn  +GARDMEM];
    521547    r_4* sloc = new r_4[minmn];
    522548    r_4 srcond = rcond;
    523549    cgelsd_(&m,&n,&nrhs,(complex<r_4>*)a.Data(),&lda,
    524550           (complex<r_4>*)b.Data(),&ldb,(r_4*)sloc,&srcond,&rank,
     551           (complex<r_4>*)wkget,&lwork,(r_4*)rwork,(int_4*)iwork,&info);
     552    lwork = type2i4(&wkget[0],4); work = new T[lwork +GARDMEM];
     553    cgelsd_(&m,&n,&nrhs,(complex<r_4>*)a.Data(),&lda,
     554           (complex<r_4>*)b.Data(),&ldb,(r_4*)sloc,&srcond,&rank,
    525555           (complex<r_4>*)work,&lwork,(r_4*)rwork,(int_4*)iwork,&info);
    526556    for(int_4 i=0;i<minmn;i++) s(i) = sloc[i];
    527     delete [] sloc; delete [] work; delete [] rwork; delete [] iwork;
     557    delete [] sloc; delete [] rwork;
    528558  } else if(typeid(T) == typeid(complex<r_8>) )  {
    529     int_4 lwork = 2*minmn + minmn*nrhs;
    530     complex<r_8>* work = new complex<r_8>[lwork +GARDMEM];
    531     int_4 lrwork = 10*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + 3*smlsiz*nrhs + (smlsiz+1)*(smlsiz+1);
     559    // CMV: Bizarrement, la formule donnee dans zgelsd() plante pour des N grands (500)
     560    // On prend (par analogie) la formule pour "lwork" de dgelsd()
     561    lrwork = 10*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + 3*smlsiz*nrhs + (smlsiz+1)*(smlsiz+1);
     562    int_4 lrwork_d = 12*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + minmn*nrhs + (smlsiz+1)*(smlsiz+1);
     563    if(lrwork_d > lrwork) lrwork = lrwork_d;
    532564    r_8* rwork = new r_8[lrwork +GARDMEM];
    533     int_4* iwork = new int_4[3*minmn*nlvl+11*minmn  +GARDMEM];
    534     r_8 srcond = rcond;
     565    iwork = new int_4[3*minmn*nlvl+11*minmn  +GARDMEM];
    535566    zgelsd_(&m,&n,&nrhs,(complex<r_8>*)a.Data(),&lda,
    536            (complex<r_8>*)b.Data(),&ldb,(r_8*)s.Data(),&srcond,&rank,
     567           (complex<r_8>*)b.Data(),&ldb,(r_8*)s.Data(),&rcond,&rank,
     568           (complex<r_8>*)wkget,&lwork,(r_8*)rwork,(int_4*)iwork,&info);
     569    lwork = type2i4(&wkget[0],8); work = new T[lwork +GARDMEM];
     570    zgelsd_(&m,&n,&nrhs,(complex<r_8>*)a.Data(),&lda,
     571           (complex<r_8>*)b.Data(),&ldb,(r_8*)s.Data(),&rcond,&rank,
    537572           (complex<r_8>*)work,&lwork,(r_8*)rwork,(int_4*)iwork,&info);
    538     delete [] work; delete [] rwork; delete [] iwork;
     573    delete [] rwork;
    539574  } else {
     575    if(work) delete [] work; work=NULL;
     576    if(iwork) delete [] iwork; iwork=NULL;
    540577    string tn = typeid(T).name();
    541578    cerr << " LapackServer::LeastSquareSolveSVD_DC(a,b) - Unsupported DataType T = " << tn << endl;
     
    543580  }
    544581
     582  if(work) delete [] work; if(iwork) delete [] iwork;
    545583  return(info);
    546584}
     
    572610  \f]
    573611  U and V are orthogonal (unitary) matrices.
    574   \param a : input m-by-n matrix (in FotranMemoryMapping)
     612  \param a : input m-by-n matrix (in FortranMemoryMapping)
    575613  \param s : Vector of min(m,n) singular values (descending order)
    576   \param u : Matrix of left singular vectors
    577   \param vt : Transpose of right singular vectors.
     614  \param u : m-by-m Matrix of left singular vectors
     615  \param vt : Transpose of right singular vectors (n-by-n matrix).
    578616  \return : return code from lapack driver _gesvd()
    579617 */
     
    649687  int_4 info;
    650688
    651   int_4 lwork = maxmn*5*wspace_size_factor;
    652   T * work = new T[lwork];
     689  int_4 lwork = -1;   // maxmn*5  *wspace_size_factor;
     690  T * work = NULL;    // = new T[lwork];
     691  T wkget[2];
    653692
    654693  if (typeid(T) == typeid(r_4) ) {
     694    sgesvd_(&jobu, &jobvt, &m, &n, (r_4 *)a.Data(), &lda,
     695            (r_4 *)s.Data(), (r_4 *) up->Data(), &ldu, (r_4 *)vtp->Data(), &ldvt,
     696            (r_4 *)wkget, &lwork, &info);
     697    lwork = type2i4(&wkget[0],4); work = new T[lwork +GARDMEM];
    655698    sgesvd_(&jobu, &jobvt, &m, &n, (r_4 *)a.Data(), &lda,
    656699            (r_4 *)s.Data(), (r_4 *) up->Data(), &ldu, (r_4 *)vtp->Data(), &ldvt,
     
    659702    dgesvd_(&jobu, &jobvt, &m, &n, (r_8 *)a.Data(), &lda,
    660703            (r_8 *)s.Data(), (r_8 *) up->Data(), &ldu, (r_8 *)vtp->Data(), &ldvt,
     704            (r_8 *)wkget, &lwork, &info);
     705    lwork = type2i4(&wkget[0],8); work = new T[lwork +GARDMEM];
     706    dgesvd_(&jobu, &jobvt, &m, &n, (r_8 *)a.Data(), &lda,
     707            (r_8 *)s.Data(), (r_8 *) up->Data(), &ldu, (r_8 *)vtp->Data(), &ldvt,
    661708            (r_8 *)work, &lwork, &info);
    662709  } else if (typeid(T) == typeid(complex<r_4>) ) {
    663710    r_4 * rwork = new r_4[5*minmn +GARDMEM];
    664711    r_4 * sloc  = new r_4[minmn];
     712    cgesvd_(&jobu, &jobvt, &m, &n, (complex<r_4> *)a.Data(), &lda,
     713            (r_4 *)sloc, (complex<r_4> *) up->Data(), &ldu,
     714            (complex<r_4> *)vtp->Data(), &ldvt,
     715            (complex<r_4> *)wkget, &lwork, (r_4 *)rwork, &info);
     716    lwork = type2i4(&wkget[0],4); work = new T[lwork +GARDMEM];
    665717    cgesvd_(&jobu, &jobvt, &m, &n, (complex<r_4> *)a.Data(), &lda,
    666718            (r_4 *)sloc, (complex<r_4> *) up->Data(), &ldu,
     
    675727            (r_8 *)sloc, (complex<r_8> *) up->Data(), &ldu,
    676728            (complex<r_8> *)vtp->Data(), &ldvt,
     729            (complex<r_8> *)wkget, &lwork, (r_8 *)rwork, &info);
     730    lwork = type2i4(&wkget[0],8); work = new T[lwork +GARDMEM];
     731    zgesvd_(&jobu, &jobvt, &m, &n, (complex<r_8> *)a.Data(), &lda,
     732            (r_8 *)sloc, (complex<r_8> *) up->Data(), &ldu,
     733            (complex<r_8> *)vtp->Data(), &ldvt,
    677734            (complex<r_8> *)work, &lwork, (r_8 *)rwork, &info);
    678735    for(int_4 i=0;i<minmn;i++) s[i] = sloc[i];
    679736    delete [] rwork; delete [] sloc;
    680737  } else {
     738    if(work) delete [] work; work=NULL;
    681739    if (jobu == 'N') delete up;
    682740    if (jobvt == 'N') delete vtp;
     
    686744  }
    687745
     746  if(work) delete [] work;
    688747  if (jobu == 'N') delete up;
    689748  if (jobvt == 'N') delete vtp;
     
    712771  u.ReSize(m,m);
    713772  vt.ReSize(n,n);
    714  
    715   int_4 lda = n;
    716   int_4 ldu = u.NCols();
    717   int_4 ldvt = vt.NCols();
    718   int_4 info; 
     773
     774  int_4 lda = m;
     775  int_4 ldu = m;
     776  int_4 ldvt = n;
     777  int_4 info;
     778  int_4 lwork=-1;
     779  T * work = NULL;
     780  int_4 * iwork = NULL;
     781  T wkget[2];
    719782
    720783  if(typeid(T) == typeid(r_4) ) {
    721784    r_4* sloc = new r_4[minmn];
    722     int_4 lwork = 3*minmn*minmn + supermax;
    723     r_4* work = new r_4[lwork +GARDMEM];
    724     int_4* iwork = new int_4[8*minmn +GARDMEM];
     785    iwork = new int_4[8*minmn +GARDMEM];
     786    sgesdd_(&jobz,&m,&n,(r_4*)a.Data(),&lda,
     787           (r_4*)sloc,(r_4*)u.Data(),&ldu,(r_4*)vt.Data(),&ldvt,
     788           (r_4*)wkget,&lwork,(int_4*)iwork,&info);
     789    lwork = type2i4(&wkget[0],4); work = new T[lwork +GARDMEM];
    725790    sgesdd_(&jobz,&m,&n,(r_4*)a.Data(),&lda,
    726791           (r_4*)sloc,(r_4*)u.Data(),&ldu,(r_4*)vt.Data(),&ldvt,
    727792           (r_4*)work,&lwork,(int_4*)iwork,&info);
    728793    for(int_4 i=0;i<minmn;i++) s(i) = (r_8) sloc[i];
    729     delete [] sloc; delete [] work; delete [] iwork;
     794    delete [] sloc;
    730795  } else if(typeid(T) == typeid(r_8) ) {
    731     int_4 lwork = 3*minmn*minmn + supermax;
    732     r_8* work = new r_8[lwork +GARDMEM];
    733     int_4* iwork = new int_4[8*minmn +GARDMEM];
     796    iwork = new int_4[8*minmn +GARDMEM];
     797    dgesdd_(&jobz,&m,&n,(r_8*)a.Data(),&lda,
     798           (r_8*)s.Data(),(r_8*)u.Data(),&ldu,(r_8*)vt.Data(),&ldvt,
     799           (r_8*)wkget,&lwork,(int_4*)iwork,&info);
     800    lwork = type2i4(&wkget[0],8); work = new T[lwork +GARDMEM];
    734801    dgesdd_(&jobz,&m,&n,(r_8*)a.Data(),&lda,
    735802           (r_8*)s.Data(),(r_8*)u.Data(),&ldu,(r_8*)vt.Data(),&ldvt,
    736803           (r_8*)work,&lwork,(int_4*)iwork,&info);
    737     delete [] work; delete [] iwork;
    738804  } else if(typeid(T) == typeid(complex<r_4>) ) {
    739805    r_4* sloc = new r_4[minmn];
    740     int_4 lwork = minmn*minmn+2*minmn+maxmn;
    741     complex<r_4>* work = new complex<r_4>[lwork +GARDMEM];
    742806    r_4* rwork = new r_4[5*minmn*minmn+5*minmn +GARDMEM];
    743     int_4* iwork = new int_4[8*minmn +GARDMEM];
     807    iwork = new int_4[8*minmn +GARDMEM];
     808    cgesdd_(&jobz,&m,&n,(complex<r_4>*)a.Data(),&lda,
     809           (r_4*)sloc,(complex<r_4>*)u.Data(),&ldu,(complex<r_4>*)vt.Data(),&ldvt,
     810           (complex<r_4>*)wkget,&lwork,(r_4*)rwork,(int_4*)iwork,&info);
     811    lwork = type2i4(&wkget[0],4); work = new T[lwork +GARDMEM];
    744812    cgesdd_(&jobz,&m,&n,(complex<r_4>*)a.Data(),&lda,
    745813           (r_4*)sloc,(complex<r_4>*)u.Data(),&ldu,(complex<r_4>*)vt.Data(),&ldvt,
    746814           (complex<r_4>*)work,&lwork,(r_4*)rwork,(int_4*)iwork,&info);
    747815    for(int_4 i=0;i<minmn;i++) s(i) = (r_8) sloc[i];
    748     delete [] sloc; delete [] work; delete [] rwork; delete [] iwork;
     816    delete [] sloc; delete [] rwork;
    749817  } else if(typeid(T) == typeid(complex<r_8>) )  {
    750     int_4 lwork = minmn*minmn+2*minmn+maxmn;
    751     complex<r_8>* work = new complex<r_8>[lwork +GARDMEM];
    752818    r_8* rwork = new r_8[5*minmn*minmn+5*minmn +GARDMEM];
    753     int_4* iwork = new int_4[8*minmn +GARDMEM];
     819    iwork = new int_4[8*minmn +GARDMEM];
     820    zgesdd_(&jobz,&m,&n,(complex<r_8>*)a.Data(),&lda,
     821           (r_8*)s.Data(),(complex<r_8>*)u.Data(),&ldu,(complex<r_8>*)vt.Data(),&ldvt,
     822           (complex<r_8>*)wkget,&lwork,(r_8*)rwork,(int_4*)iwork,&info);
     823    lwork = type2i4(&wkget[0],8); work = new T[lwork +GARDMEM];
    754824    zgesdd_(&jobz,&m,&n,(complex<r_8>*)a.Data(),&lda,
    755825           (r_8*)s.Data(),(complex<r_8>*)u.Data(),&ldu,(complex<r_8>*)vt.Data(),&ldvt,
    756826           (complex<r_8>*)work,&lwork,(r_8*)rwork,(int_4*)iwork,&info);
    757     delete [] work; delete [] rwork; delete [] iwork;
     827    delete [] rwork;
    758828  } else {
     829    if(work) delete [] work; work=NULL;
     830    if(iwork) delete [] iwork; iwork=NULL;
    759831    string tn = typeid(T).name();
    760832    cerr << " LapackServer::SVD_DC(...) - Unsupported DataType T = " << tn << endl;
     
    762834  }
    763835
     836  if(work) delete [] work; if(iwork) delete [] iwork;
    764837  return(info);
    765838}
     
    794867  int_4 lda = a.Step(cola);
    795868  int_4 info = 0;
     869  int_4 lwork = -1;
     870  T * work = NULL;
     871  T wkget[2];
    796872
    797873  b.ReSize(n); b = 0.;
    798874
    799875  if (typeid(T) == typeid(r_4) ) {
    800     int_4 lwork = 3*n-1; r_4* work = new r_4[lwork  +GARDMEM];
    801876    r_4* w = new r_4[n];
     877    ssyev_(&jobz,&uplo,&n,(r_4 *)a.Data(),&lda,(r_4 *)w,(r_4 *)wkget,&lwork,&info);
     878    lwork = type2i4(&wkget[0],4); /* 3*n-1;*/ work = new T[lwork  +GARDMEM];
    802879    ssyev_(&jobz,&uplo,&n,(r_4 *)a.Data(),&lda,(r_4 *)w,(r_4 *)work,&lwork,&info);
    803880    if(info==0) for(int i=0;i<n;i++) b(i) = w[i];
    804     delete [] work; delete [] w;
     881    delete [] w;
    805882  } else if (typeid(T) == typeid(r_8) )  {
    806     int_4 lwork = 3*n-1; r_8* work = new r_8[lwork  +GARDMEM];
    807883    r_8* w = new r_8[n];
     884    dsyev_(&jobz,&uplo,&n,(r_8 *)a.Data(),&lda,(r_8 *)w,(r_8 *)wkget,&lwork,&info);
     885    lwork = type2i4(&wkget[0],8); /* 3*n-1;*/ work = new T[lwork  +GARDMEM];
    808886    dsyev_(&jobz,&uplo,&n,(r_8 *)a.Data(),&lda,(r_8 *)w,(r_8 *)work,&lwork,&info);
    809887    if(info==0) for(int i=0;i<n;i++) b(i) = w[i];
    810     delete [] work; delete [] w;
     888    delete [] w;
    811889  } else if (typeid(T) == typeid(complex<r_4>) )  {
    812     int_4 lwork = 2*n-1; complex<r_4>* work = new complex<r_4>[lwork  +GARDMEM];
    813890    r_4* rwork = new r_4[3*n-2  +GARDMEM]; r_4* w = new r_4[n];
     891    cheev_(&jobz,&uplo,&n,(complex<r_4> *)a.Data(),&lda,(r_4 *)w
     892          ,(complex<r_4> *)wkget,&lwork,(r_4 *)rwork,&info);
     893    lwork = type2i4(&wkget[0],4); /* 2*n-1;*/ work = new T[lwork  +GARDMEM];
    814894    cheev_(&jobz,&uplo,&n,(complex<r_4> *)a.Data(),&lda,(r_4 *)w
    815895          ,(complex<r_4> *)work,&lwork,(r_4 *)rwork,&info);
    816896    if(info==0) for(int i=0;i<n;i++) b(i) = w[i];
    817     delete [] work; delete [] rwork; delete [] w;
     897    delete [] rwork; delete [] w;
    818898  } else if (typeid(T) == typeid(complex<r_8>) )  {
    819     int_4 lwork = 2*n-1; complex<r_8>* work = new complex<r_8>[lwork  +GARDMEM];
    820899    r_8* rwork = new r_8[3*n-2  +GARDMEM]; r_8* w = new r_8[n];
     900    zheev_(&jobz,&uplo,&n,(complex<r_8> *)a.Data(),&lda,(r_8 *)w
     901          ,(complex<r_8> *)wkget,&lwork,(r_8 *)rwork,&info);
     902    lwork = type2i4(&wkget[0],8); /* 2*n-1;*/ work = new T[lwork  +GARDMEM];
    821903    zheev_(&jobz,&uplo,&n,(complex<r_8> *)a.Data(),&lda,(r_8 *)w
    822904          ,(complex<r_8> *)work,&lwork,(r_8 *)rwork,&info);
    823905    if(info==0) for(int i=0;i<n;i++) b(i) = w[i];
    824     delete [] work; delete [] rwork; delete [] w;
     906    delete [] rwork; delete [] w;
    825907  } else {
     908    if(work) delete [] work; work=NULL;
    826909    string tn = typeid(T).name();
    827910    cerr << " LapackServer::LapackEigenSym(a,b) - Unsupported DataType T = " << tn << endl;
     
    829912  }
    830913
     914  if(work) delete [] work;
    831915  return(info);
    832916}
     
    880964  int_4 ldvr = n, ldvl = 1;
    881965
     966  int_4 lwork = -1;
     967  T * work = NULL;
     968  T wkget[2];
     969
    882970  if (typeid(T) == typeid(r_4) ) {
    883     int_4 lwork = 4*n; r_4* work = new r_4[lwork  +GARDMEM];
    884971    r_4* wr = new r_4[n]; r_4* wi = new r_4[n]; r_4* vl = NULL;
     972    sgeev_(&jobvl,&jobvr,&n,(r_4 *)a.Data(),&lda,(r_4 *)wr,(r_4 *)wi,
     973           (r_4 *)vl,&ldvl,(r_4 *)evec.Data(),&ldvr,
     974           (r_4 *)wkget,&lwork,&info);
     975    lwork = type2i4(&wkget[0],4); /* 4*n;*/ work = new T[lwork  +GARDMEM];
    885976    sgeev_(&jobvl,&jobvr,&n,(r_4 *)a.Data(),&lda,(r_4 *)wr,(r_4 *)wi,
    886977           (r_4 *)vl,&ldvl,(r_4 *)evec.Data(),&ldvr,
    887978           (r_4 *)work,&lwork,&info);
    888979    if(info==0) for(int i=0;i<n;i++) eval(i) = complex<r_8>(wr[i],wi[i]);
    889     delete [] work; delete [] wr; delete [] wi;
     980    delete [] wr; delete [] wi;
    890981  } else if (typeid(T) == typeid(r_8) )  {
    891     int_4 lwork = 4*n; r_8* work = new r_8[lwork  +GARDMEM];
    892982    r_8* wr = new r_8[n]; r_8* wi = new r_8[n]; r_8* vl = NULL;
     983    dgeev_(&jobvl,&jobvr,&n,(r_8 *)a.Data(),&lda,(r_8 *)wr,(r_8 *)wi,
     984           (r_8 *)vl,&ldvl,(r_8 *)evec.Data(),&ldvr,
     985           (r_8 *)wkget,&lwork,&info);
     986    lwork = type2i4(&wkget[0],8); /* 4*n;*/ work = new T[lwork  +GARDMEM];
    893987    dgeev_(&jobvl,&jobvr,&n,(r_8 *)a.Data(),&lda,(r_8 *)wr,(r_8 *)wi,
    894988           (r_8 *)vl,&ldvl,(r_8 *)evec.Data(),&ldvr,
    895989           (r_8 *)work,&lwork,&info);
    896990    if(info==0) for(int i=0;i<n;i++) eval(i) = complex<r_8>(wr[i],wi[i]);
    897     delete [] work; delete [] wr; delete [] wi;
     991    delete [] wr; delete [] wi;
    898992  } else if (typeid(T) == typeid(complex<r_4>) )  {
    899     int_4 lwork = 2*n; complex<r_4>* work = new complex<r_4>[lwork  +GARDMEM];
    900993    r_4* rwork = new r_4[2*n  +GARDMEM]; r_4* vl = NULL; TVector< complex<r_4> > w(n);
     994    cgeev_(&jobvl,&jobvr,&n,(complex<r_4> *)a.Data(),&lda,(complex<r_4> *)w.Data(),
     995           (complex<r_4> *)vl,&ldvl,(complex<r_4> *)evec.Data(),&ldvr,
     996           (complex<r_4> *)wkget,&lwork,(r_4 *)rwork,&info);
     997    lwork = type2i4(&wkget[0],4); /* 2*n;*/ work = new T[lwork  +GARDMEM];
    901998    cgeev_(&jobvl,&jobvr,&n,(complex<r_4> *)a.Data(),&lda,(complex<r_4> *)w.Data(),
    902999           (complex<r_4> *)vl,&ldvl,(complex<r_4> *)evec.Data(),&ldvr,
    9031000           (complex<r_4> *)work,&lwork,(r_4 *)rwork,&info);
    9041001    if(info==0) for(int i=0;i<n;i++) eval(i) = w(i);
    905     delete [] work; delete [] rwork;
     1002    delete [] rwork;
    9061003  } else if (typeid(T) == typeid(complex<r_8>) )  {
    907     int_4 lwork = 2*n; complex<r_8>* work = new complex<r_8>[lwork  +GARDMEM];
    9081004    r_8* rwork = new r_8[2*n  +GARDMEM]; r_8* vl = NULL;
    9091005    zgeev_(&jobvl,&jobvr,&n,(complex<r_8> *)a.Data(),&lda,(complex<r_8> *)eval.Data(),
    9101006           (complex<r_8> *)vl,&ldvl,(complex<r_8> *)evec.Data(),&ldvr,
     1007           (complex<r_8> *)wkget,&lwork,(r_8 *)rwork,&info);
     1008    lwork = type2i4(&wkget[0],8); /* 2*n;*/ work = new T[lwork  +GARDMEM];
     1009    zgeev_(&jobvl,&jobvr,&n,(complex<r_8> *)a.Data(),&lda,(complex<r_8> *)eval.Data(),
     1010           (complex<r_8> *)vl,&ldvl,(complex<r_8> *)evec.Data(),&ldvr,
    9111011           (complex<r_8> *)work,&lwork,(r_8 *)rwork,&info);
    912     delete [] work; delete [] rwork;
     1012    delete [] rwork;
    9131013  } else {
     1014    if(work) delete [] work; work=NULL;
    9141015    string tn = typeid(T).name();
    9151016    cerr << " LapackServer::LapackEigen(a,b) - Unsupported DataType T = " << tn << endl;
     
    9171018  }
    9181019
     1020  if(work) delete [] work;
    9191021  return(info);
    9201022}
  • trunk/SophyaExt/LinAlg/intflapack.h

    r2567 r2572  
    3838                TArray<T>* up=NULL, TArray<T> * vtp=NULL);
    3939  int_4 ilaenv_en_C(int_4 ispec,char *name,char *opts,int_4 n1,int_4 n2,int_4 n3,int_4 n4);
     40  int_4 type2i4(void *val,int nbytes);
    4041
    4142  int wspace_size_factor;
Note: See TracChangeset for help on using the changeset viewer.