Changeset 2554 in Sophya


Ignore:
Timestamp:
Jul 19, 2004, 6:09:30 PM (21 years ago)
Author:
cmv
Message:

intro inversion matrices symetriques + ilaenv (cmv 19/07/04)

Location:
trunk/SophyaExt/LinAlg
Files:
2 edited

Legend:

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

    r2322 r2554  
    5252
    5353extern "C" {
     54// Le calculateur de workingspace
     55  int_4 ilaenv_(int_4 *ispec,char *name,char *opts,int_4 *n1,int_4 *n2,int_4 *n3,int_4 *n4,
     56                int_4 nc1,int_4 nc2);
     57
    5458// Drivers pour resolution de systemes lineaires
    5559  void sgesv_(int_4* n, int_4* nrhs, r_4* a, int_4* lda,
     
    6266              int_4* ipiv, complex<r_8>* b, int_4* ldb, int_4* info);
    6367
    64   // Driver pour resolution de systemes au sens de Xi2
     68// Drivers pour resolution de systemes lineaires symetriques
     69  void ssysv_(char* uplo, int_4* n, int_4* nrhs, r_4* a, int_4* lda,
     70              int_4* ipiv, r_4* b, int_4* ldb,
     71              r_4* work, int_4* lwork, int_4* info);
     72  void dsysv_(char* uplo, int_4* n, int_4* nrhs, r_8* a, int_4* lda,
     73              int_4* ipiv, r_8* b, int_4* ldb,
     74              r_8* work, int_4* lwork, int_4* info);
     75  void csysv_(char* uplo, int_4* n, int_4* nrhs, complex<r_4>* a, int_4* lda,
     76              int_4* ipiv, complex<r_4>* b, int_4* ldb,
     77              complex<r_4>* work, int_4* lwork, int_4* info);
     78  void zsysv_(char* uplo, int_4* n, int_4* nrhs, complex<r_8>* a, int_4* lda,
     79              int_4* ipiv, complex<r_8>* b, int_4* ldb,
     80              complex<r_8>* work, int_4* lwork, int_4* info);
     81
     82// Driver pour resolution de systemes au sens de Xi2
    6583  void sgels_(char * trans, int_4* m, int_4* n, int_4* nrhs, r_4* a, int_4* lda,
    6684              r_4* b, int_4* ldb, r_4* work, int_4* lwork, int_4* info);
     
    100118LapackServer<T>::~LapackServer()
    101119{
     120}
     121
     122// --- ATTENTION BUG PREVISIBLE (CMV) --- REZA A LIRE S.T.P.
     123// -> Cette connerie de Fortran/C interface
     124// Dans les routines fortran de lapack:
     125// Appel depuis le C avec:
     126//   int_4 lwork = -1;
     127// SUBROUTINE SSYSV( UPLO,N,NRHS,A,LDA,IPIV,B,LDB,WORK,LWORK,INFO)
     128//   INTEGER            INFO, LDA, LDB, LWORK, N, NRHS
     129//   LOGICAL            LQUERY
     130//   LQUERY = ( LWORK.EQ.-1 )
     131//   ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THEN
     132//    ==> le test est bien interprete sous Linux mais pas sous OSF
     133//    ==> Sous OSF "LWORK.EQ.-1" est FALSE quand on passe lwork=-1 par argument
     134//    ==> POUR REZA: confusion entier 4 / 8 bits ??? (bizarre on l'aurait vu avant?)
     135template <class T>
     136int_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)
     137{
     138 int_4 nc1 = strlen(name);
     139 int_4 nc2 = strlen(opts);
     140 int_4 rc=0;
     141 rc = ilaenv_(&ispec,name,opts,&n1,&n2,&n3,&n4,nc1,nc2);
     142 //cout<<"ilaenv_en_C("<<ispec<<","<<name<<"("<<nc1<<"),"<<opts<<"("<<nc2<<"),"
     143 //    <<n1<<","<<n2<<","<<n3<<","<<n4<<") = "<<rc<<endl;
     144 return rc;
    102145}
    103146
     
    150193    throw TypeMismatchExc("LapackServer::LinSolve(a,b) - Unsupported DataType (T)");
    151194  }
     195  delete[] ipiv;
     196  return(info);
     197}
     198
     199//! Interface to Lapack linear system solver driver s/d/c/zsysvd().
     200/*! Solve the linear system a * x = b with a symetric. Input arrays
     201  should have FortranMemory mapping (column packed).
     202  \param a : input matrix symetric , overwritten on output
     203  \param b : input-output, input vector b, contains x on exit
     204  \return : return code from lapack driver _gesv()
     205 */
     206template <class T>
     207int LapackServer<T>::LinSolveSym(TArray<T>& a, TArray<T> & b)
     208// --- REMARQUES DE CMV ---
     209// 1./ contrairement a ce qui est dit dans la doc, il s'agit
     210//     de matrices SYMETRIQUES complexes et non HERMITIENNES !!!
     211// 2./ pourquoi les routines de LinSolve pour des matrices symetriques
     212//     sont plus de deux fois plus lentes que les LinSolve generales ???
     213{
     214  if ( ( a.NbDimensions() != 2 ) || ( b.NbDimensions() != 2 ) )
     215    throw(SzMismatchError("LapackServer::LinSolveSym(a,b) a Or b NbDimensions() != 2"));
     216  int_4 rowa = a.RowsKA();
     217  int_4 cola = a.ColsKA();
     218  int_4 rowb = b.RowsKA();
     219  int_4 colb = b.ColsKA();
     220  if ( a.Size(rowa) !=  a.Size(cola))
     221    throw(SzMismatchError("LapackServer::LinSolveSym(a,b) a Not a square Array"));
     222  if ( a.Size(rowa) !=  b.Size(rowb))
     223    throw(SzMismatchError("LapackServer::LinSolveSym(a,b) RowSize(a <> b) "));
     224
     225  if (!a.IsPacked(rowa) || !b.IsPacked(rowb))
     226     throw(SzMismatchError("LapackServer::LinSolveSym(a,b) a Or b Not Column Packed"));
     227
     228  int_4 n = a.Size(rowa);
     229  int_4 nrhs = b.Size(colb);
     230  int_4 lda = a.Step(cola);
     231  int_4 ldb = b.Step(colb);
     232  int_4 info = 0;
     233  int_4* ipiv = new int_4[n];
     234  int_4 lwork = -1;
     235  T * work = NULL;
     236
     237  char uplo = 'U'; // char uplo = 'L';
     238  char struplo[5]; struplo[0] = uplo; struplo[1] = '\0';
     239
     240  if (typeid(T) == typeid(r_4) ) {
     241    lwork = ilaenv_en_C(1,"SSYTRF",struplo,n,-1,-1,-1) * n;
     242    work = new T[lwork+5];
     243    ssysv_(&uplo, &n, &nrhs, (r_4 *)a.Data(), &lda, ipiv, (r_4 *)b.Data(), &ldb,
     244          (r_4 *)work, &lwork, &info);
     245  } else if (typeid(T) == typeid(r_8) )  {
     246    lwork = ilaenv_en_C(1,"DSYTRF",struplo,n,-1,-1,-1) * n;
     247    work = new T[lwork+5];
     248    dsysv_(&uplo, &n, &nrhs, (r_8 *)a.Data(), &lda, ipiv, (r_8 *)b.Data(), &ldb,
     249          (r_8 *)work, &lwork, &info);
     250  } else if (typeid(T) == typeid(complex<r_4>) )  {
     251    lwork = ilaenv_en_C(1,"CSYTRF",struplo,n,-1,-1,-1) * n;
     252    work = new T[lwork+5];
     253    csysv_(&uplo, &n, &nrhs, (complex<r_4> *)a.Data(), &lda, ipiv,
     254          (complex<r_4> *)b.Data(), &ldb,
     255          (complex<r_4> *)work, &lwork, &info);
     256  } else if (typeid(T) == typeid(complex<r_8>) )  {
     257    lwork = ilaenv_en_C(1,"ZSYTRF",struplo,n,-1,-1,-1) * n;
     258    work = new T[lwork+5];
     259    zsysv_(&uplo, &n, &nrhs, (complex<r_8> *)a.Data(), &lda, ipiv,
     260          (complex<r_8> *)b.Data(), &ldb,
     261          (complex<r_8> *)work, &lwork, &info);
     262  } else {
     263    delete[] work;
     264    delete[] ipiv;
     265    string tn = typeid(T).name();
     266    cerr << " LapackServer::LinSolveSym(a,b) - Unsupported DataType T = " << tn << endl;
     267    throw TypeMismatchExc("LapackServer::LinSolveSym(a,b) - Unsupported DataType (T)");
     268  }
     269  delete[] work;
    152270  delete[] ipiv;
    153271  return(info);
  • trunk/SophyaExt/LinAlg/intflapack.h

    r1566 r2554  
    1414
    1515  virtual int LinSolve(TArray<T>& a, TArray<T> & b);
     16  virtual int LinSolveSym(TArray<T>& a, TArray<T> & b);
    1617  virtual int LeastSquareSolve(TArray<T>& a, TArray<T> & b);
    1718
     
    3031  int SVDDriver(TArray<T>& a, TArray<T> & s,
    3132                TArray<T>* up=NULL, TArray<T> * vtp=NULL);
     33  int_4 ilaenv_en_C(int_4 ispec,char *name,char *opts,int_4 n1,int_4 n2,int_4 n3,int_4 n4);
    3234
    3335  int wspace_size_factor;
     
    4143inline int LapackLinSolve(TArray<T>& a, TArray<T> & b)
    4244{ LapackServer<T> lps; return( lps.LinSolve(a, b) );  }
     45
     46/*! \ingroup LinAlg
     47    \fn LapackLinSolveSym(TArray<T>&, TArray<T> &)
     48    \brief Solves the linear system A*X = B with A symetric using LapackServer.
     49*/
     50template <class T>
     51inline int LapackLinSolveSym(TArray<T>& a, TArray<T> & b)
     52{ LapackServer<T> lps; return( lps.LinSolveSym(a, b) );  }
    4353
    4454/*! \ingroup LinAlg
Note: See TracChangeset for help on using the changeset viewer.