Changeset 2554 in Sophya for trunk/SophyaExt/LinAlg/intflapack.cc
- Timestamp:
- Jul 19, 2004, 6:09:30 PM (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaExt/LinAlg/intflapack.cc
r2322 r2554 52 52 53 53 extern "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 54 58 // Drivers pour resolution de systemes lineaires 55 59 void sgesv_(int_4* n, int_4* nrhs, r_4* a, int_4* lda, … … 62 66 int_4* ipiv, complex<r_8>* b, int_4* ldb, int_4* info); 63 67 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 65 83 void sgels_(char * trans, int_4* m, int_4* n, int_4* nrhs, r_4* a, int_4* lda, 66 84 r_4* b, int_4* ldb, r_4* work, int_4* lwork, int_4* info); … … 100 118 LapackServer<T>::~LapackServer() 101 119 { 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?) 135 template <class T> 136 int_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; 102 145 } 103 146 … … 150 193 throw TypeMismatchExc("LapackServer::LinSolve(a,b) - Unsupported DataType (T)"); 151 194 } 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 */ 206 template <class T> 207 int 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; 152 270 delete[] ipiv; 153 271 return(info);
Note:
See TracChangeset
for help on using the changeset viewer.