38 #ifndef GMM_LAPACK_INTERFACE_H 39 #define GMM_LAPACK_INTERFACE_H 46 #if defined(GMM_USES_LAPACK) 88 void sgetrf_(...);
void dgetrf_(...);
void cgetrf_(...);
void zgetrf_(...);
89 void sgetrs_(...);
void dgetrs_(...);
void cgetrs_(...);
void zgetrs_(...);
90 void sgetri_(...);
void dgetri_(...);
void cgetri_(...);
void zgetri_(...);
91 void sgeqrf_(...);
void dgeqrf_(...);
void cgeqrf_(...);
void zgeqrf_(...);
92 void sorgqr_(...);
void dorgqr_(...);
void cungqr_(...);
void zungqr_(...);
93 void sormqr_(...);
void dormqr_(...);
void cunmqr_(...);
void zunmqr_(...);
94 void sgees_ (...);
void dgees_ (...);
void cgees_ (...);
void zgees_ (...);
95 void sgeev_ (...);
void dgeev_ (...);
void cgeev_ (...);
void zgeev_ (...);
96 void sgeesx_(...);
void dgeesx_(...);
void cgeesx_(...);
void zgeesx_(...);
97 void sgesvd_(...);
void dgesvd_(...);
void cgesvd_(...);
void zgesvd_(...);
104 # define getrf_interface(lapack_name, base_type) inline \ 105 size_type lu_factor(dense_matrix<base_type > &A, lapack_ipvt &ipvt){ \ 106 GMMLAPACK_TRACE("getrf_interface"); \ 107 long m = long(mat_nrows(A)), n = long(mat_ncols(A)), lda(m), info(-1L); \ 108 if (m && n) lapack_name(&m, &n, &A(0,0), &lda, ipvt.pfirst(), &info); \ 109 if ((info & 0xFFFFFFFF00000000L) && !(info & 0x00000000FFFFFFFFL)) \ 111 ipvt.set_to_int32(); \ 112 return size_type(int(info & 0x00000000FFFFFFFFL)); \ 115 getrf_interface(sgetrf_, BLAS_S)
116 getrf_interface(dgetrf_, BLAS_D)
117 getrf_interface(cgetrf_, BLAS_C)
118 getrf_interface(zgetrf_, BLAS_Z)
124 # define getrs_interface(f_name, trans1, lapack_name, base_type) inline \ 125 void f_name(const dense_matrix<base_type > &A, \ 126 const lapack_ipvt &ipvt, std::vector<base_type > &x, \ 127 const std::vector<base_type > &b) { \ 128 GMMLAPACK_TRACE("getrs_interface"); \ 129 long n = long(mat_nrows(A)), info(0), nrhs(1); \ 130 gmm::copy(b, x); trans1; \ 132 lapack_name(&t,&n,&nrhs,&(A(0,0)),&n,ipvt.pfirst(),&x[0],&n,&info); \ 135 # define getrs_trans_n const char t = 'N' 136 # define getrs_trans_t const char t = 'T' 138 getrs_interface(lu_solve, getrs_trans_n, sgetrs_, BLAS_S)
139 getrs_interface(lu_solve, getrs_trans_n, dgetrs_, BLAS_D)
140 getrs_interface(lu_solve, getrs_trans_n, cgetrs_, BLAS_C)
141 getrs_interface(lu_solve, getrs_trans_n, zgetrs_, BLAS_Z)
142 getrs_interface(lu_solve_transposed, getrs_trans_t, sgetrs_, BLAS_S)
143 getrs_interface(lu_solve_transposed, getrs_trans_t, dgetrs_, BLAS_D)
144 getrs_interface(lu_solve_transposed, getrs_trans_t, cgetrs_, BLAS_C)
145 getrs_interface(lu_solve_transposed, getrs_trans_t, zgetrs_, BLAS_Z)
151 # define getri_interface(lapack_name, base_type) inline \ 152 void lu_inverse(const dense_matrix<base_type > &LU, \ 153 const lapack_ipvt &ipvt, const dense_matrix<base_type > &A_) { \ 154 GMMLAPACK_TRACE("getri_interface"); \ 155 dense_matrix<base_type >& \ 156 A = const_cast<dense_matrix<base_type > &>(A_); \ 157 long n = int(mat_nrows(A)), info(0), lwork(-1); base_type work1; \ 160 lapack_name(&n, &A(0,0), &n, ipvt.pfirst(), &work1, &lwork, &info); \ 161 lwork = int(gmm::real(work1)); \ 162 std::vector<base_type > work(lwork); \ 163 lapack_name(&n, &A(0,0), &n, ipvt.pfirst(), &work[0], &lwork,&info); \ 167 getri_interface(sgetri_, BLAS_S)
168 getri_interface(dgetri_, BLAS_D)
169 getri_interface(cgetri_, BLAS_C)
170 getri_interface(zgetri_, BLAS_Z)
176 # define geqrf_interface(lapack_name1, base_type) inline \ 177 void qr_factor(dense_matrix<base_type > &A){ \ 178 GMMLAPACK_TRACE("geqrf_interface"); \ 179 long m = long(mat_nrows(A)), n=long(mat_ncols(A)), info(0), lwork(-1); \ 182 std::vector<base_type > tau(n); \ 183 lapack_name1(&m, &n, &A(0,0), &m, &tau[0], &work1 , &lwork, &info); \ 184 lwork = long(gmm::real(work1)); \ 185 std::vector<base_type > work(lwork); \ 186 lapack_name1(&m, &n, &A(0,0), &m, &tau[0], &work[0], &lwork, &info); \ 187 GMM_ASSERT1(!info, "QR factorization failed"); \ 191 geqrf_interface(sgeqrf_, BLAS_S)
192 geqrf_interface(dgeqrf_, BLAS_D)
198 # define geqrf_interface2(lapack_name1, lapack_name2, base_type) inline \ 199 void qr_factor(const dense_matrix<base_type > &A, \ 200 dense_matrix<base_type > &Q, dense_matrix<base_type > &R) { \ 201 GMMLAPACK_TRACE("geqrf_interface2"); \ 202 long m = long(mat_nrows(A)), n=long(mat_ncols(A)), info(0), lwork(-1); \ 205 std::copy(A.begin(), A.end(), Q.begin()); \ 206 std::vector<base_type > tau(n); \ 207 lapack_name1(&m, &n, &Q(0,0), &m, &tau[0], &work1 , &lwork, &info); \ 208 lwork = long(gmm::real(work1)); \ 209 std::vector<base_type > work(lwork); \ 210 lapack_name1(&m, &n, &Q(0,0), &m, &tau[0], &work[0], &lwork, &info); \ 211 GMM_ASSERT1(!info, "QR factorization failed"); \ 212 base_type *p = &R(0,0), *q = &Q(0,0); \ 213 for (long j = 0; j < n; ++j, q += m-n) \ 214 for (long i = 0; i < n; ++i, ++p, ++q) \ 215 *p = (j < i) ? base_type(0) : *q; \ 216 lapack_name2(&m, &n, &n, &Q(0,0), &m,&tau[0],&work[0],&lwork,&info); \ 218 else gmm::clear(Q); \ 221 geqrf_interface2(sgeqrf_, sorgqr_, BLAS_S)
222 geqrf_interface2(dgeqrf_, dorgqr_, BLAS_D)
223 geqrf_interface2(cgeqrf_, cungqr_, BLAS_C)
224 geqrf_interface2(zgeqrf_, zungqr_, BLAS_Z)
230 # define gees_interface(lapack_name, base_type) \ 231 template <typename VECT> inline void implicit_qr_algorithm( \ 232 const dense_matrix<base_type > &A, const VECT &eigval_, \ 233 dense_matrix<base_type > &Q, \ 234 double tol=gmm::default_tol(base_type()), bool compvect = true) { \ 235 GMMLAPACK_TRACE("gees_interface"); \ 236 typedef bool (*L_fp)(...); L_fp p = 0; \ 237 long n=long(mat_nrows(A)), info(0), lwork(-1), sdim; base_type work1; \ 239 dense_matrix<base_type > H(n,n); gmm::copy(A, H); \ 240 char jobvs = (compvect ? 'V' : 'N'), sort = 'N'; \ 241 std::vector<double> rwork(n), eigv1(n), eigv2(n); \ 242 lapack_name(&jobvs, &sort, p, &n, &H(0,0), &n, &sdim, &eigv1[0], \ 243 &eigv2[0], &Q(0,0), &n, &work1, &lwork, &rwork[0], &info); \ 244 lwork = long(gmm::real(work1)); \ 245 std::vector<base_type > work(lwork); \ 246 lapack_name(&jobvs, &sort, p, &n, &H(0,0), &n, &sdim, &eigv1[0], \ 247 &eigv2[0], &Q(0,0), &n, &work[0], &lwork, &rwork[0],&info);\ 248 GMM_ASSERT1(!info, "QR algorithm failed"); \ 249 extract_eig(H, const_cast<VECT &>(eigval_), tol); \ 252 # define gees_interface2(lapack_name, base_type) \ 253 template <typename VECT> inline void implicit_qr_algorithm( \ 254 const dense_matrix<base_type > &A, const VECT &eigval_, \ 255 dense_matrix<base_type > &Q, \ 256 double tol=gmm::default_tol(base_type()), bool compvect = true) { \ 257 GMMLAPACK_TRACE("gees_interface2"); \ 258 typedef bool (*L_fp)(...); L_fp p = 0; \ 259 long n=long(mat_nrows(A)), info(0), lwork(-1), sdim; base_type work1; \ 261 dense_matrix<base_type > H(n,n); gmm::copy(A, H); \ 262 char jobvs = (compvect ? 'V' : 'N'), sort = 'N'; \ 263 std::vector<double> rwork(n), eigvv(n*2); \ 264 lapack_name(&jobvs, &sort, p, &n, &H(0,0), &n, &sdim, &eigvv[0], \ 265 &Q(0,0), &n, &work1, &lwork, &rwork[0], &rwork[0], &info); \ 266 lwork = long(gmm::real(work1)); \ 267 std::vector<base_type > work(lwork); \ 268 lapack_name(&jobvs, &sort, p, &n, &H(0,0), &n, &sdim, &eigvv[0], \ 269 &Q(0,0), &n, &work[0], &lwork, &rwork[0], &rwork[0],&info);\ 270 GMM_ASSERT1(!info, "QR algorithm failed"); \ 271 extract_eig(H, const_cast<VECT &>(eigval_), tol); \ 274 gees_interface(sgees_, BLAS_S)
275 gees_interface(dgees_, BLAS_D)
276 gees_interface2(cgees_, BLAS_C)
277 gees_interface2(zgees_, BLAS_Z)
280 # define jobv_right char jobvl = 'N', jobvr = 'V'; 281 # define jobv_left char jobvl = 'V', jobvr = 'N'; 283 # define geev_interface(lapack_name, base_type, side) \ 284 template <typename VECT> inline void geev_interface_ ## side( \ 285 const dense_matrix<base_type > &A, const VECT &eigval_, \ 286 dense_matrix<base_type > &Q) { \ 287 GMMLAPACK_TRACE("geev_interface"); \ 288 long n = long(mat_nrows(A)), info(0), lwork(-1); base_type work1; \ 290 dense_matrix<base_type > H(n,n); gmm::copy(A, H); \ 292 std::vector<base_type > eigvr(n), eigvi(n); \ 293 lapack_name(&jobvl, &jobvr, &n, &H(0,0), &n, &eigvr[0], &eigvi[0], \ 294 &Q(0,0), &n, &Q(0,0), &n, &work1, &lwork, &info); \ 295 lwork = long(gmm::real(work1)); \ 296 std::vector<base_type > work(lwork); \ 297 lapack_name(&jobvl, &jobvr, &n, &H(0,0), &n, &eigvr[0], &eigvi[0], \ 298 &Q(0,0), &n, &Q(0,0), &n, &work[0], &lwork, &info); \ 299 GMM_ASSERT1(!info, "QR algorithm failed"); \ 300 gmm::copy(eigvr, gmm::real_part(const_cast<VECT &>(eigval_))); \ 301 gmm::copy(eigvi, gmm::imag_part(const_cast<VECT &>(eigval_))); \ 304 # define geev_interface2(lapack_name, base_type, side) \ 305 template <typename VECT> inline void geev_interface_ ## side( \ 306 const dense_matrix<base_type > &A, const VECT &eigval_, \ 307 dense_matrix<base_type > &Q) { \ 308 GMMLAPACK_TRACE("geev_interface"); \ 309 long n = long(mat_nrows(A)), info(0), lwork(-1); base_type work1; \ 311 dense_matrix<base_type > H(n,n); gmm::copy(A, H); \ 313 std::vector<base_type::value_type> rwork(2*n); \ 314 std::vector<base_type> eigv(n); \ 315 lapack_name(&jobvl, &jobvr, &n, &H(0,0), &n, &eigv[0], &Q(0,0), &n, \ 316 &Q(0,0), &n, &work1, &lwork, &rwork[0], &info); \ 317 lwork = long(gmm::real(work1)); \ 318 std::vector<base_type > work(lwork); \ 319 lapack_name(&jobvl, &jobvr, &n, &H(0,0), &n, &eigv[0], &Q(0,0), &n, \ 320 &Q(0,0), &n, &work[0], &lwork, &rwork[0], &info); \ 321 GMM_ASSERT1(!info, "QR algorithm failed"); \ 322 gmm::copy(eigv, const_cast<VECT &>(eigval_)); \ 325 geev_interface(sgeev_, BLAS_S, right)
326 geev_interface(dgeev_, BLAS_D, right)
327 geev_interface2(cgeev_, BLAS_C, right)
328 geev_interface2(zgeev_, BLAS_Z, right)
330 geev_interface(sgeev_, BLAS_S, left)
331 geev_interface(dgeev_, BLAS_D, left)
332 geev_interface2(cgeev_, BLAS_C, left)
333 geev_interface2(zgeev_, BLAS_Z, left)
341 # define geesx_interface(lapack_name, base_type) inline \ 342 void schur(dense_matrix<base_type> &A, \ 343 dense_matrix<base_type> &S, \ 344 dense_matrix<base_type> &Q) { \ 345 GMMLAPACK_TRACE("geesx_interface"); \ 346 long m = long(mat_nrows(A)), n = long(mat_ncols(A)); \ 347 GMM_ASSERT1(m == n, "Schur decomposition requires square matrix"); \ 348 char jobvs = 'V', sort = 'N', sense = 'N'; \ 349 bool select = false; \ 350 long lwork = 8*n, sdim = 0, liwork = 1; \ 351 std::vector<base_type> work(lwork), wr(n), wi(n); \ 352 std::vector<long> iwork(liwork); \ 353 std::vector<long> bwork(1); \ 354 resize(S, n, n); copy(A, S); \ 356 base_type rconde(0), rcondv(0); \ 358 lapack_name(&jobvs, &sort, &select, &sense, &n, &S(0,0), &n, \ 359 &sdim, &wr[0], &wi[0], &Q(0,0), &n, &rconde, &rcondv, \ 360 &work[0], &lwork, &iwork[0], &liwork, &bwork[0], &info);\ 361 GMM_ASSERT1(!info, "SCHUR algorithm failed"); \ 364 # define geesx_interface2(lapack_name, base_type) inline \ 365 void schur(dense_matrix<base_type> &A, \ 366 dense_matrix<base_type> &S, \ 367 dense_matrix<base_type> &Q) { \ 368 GMMLAPACK_TRACE("geesx_interface"); \ 369 long m = long(mat_nrows(A)), n = long(mat_ncols(A)); \ 370 GMM_ASSERT1(m == n, "Schur decomposition requires square matrix"); \ 371 char jobvs = 'V', sort = 'N', sense = 'N'; \ 372 bool select = false; \ 373 long lwork = 8*n, sdim = 0; \ 374 std::vector<base_type::value_type> rwork(lwork); \ 375 std::vector<base_type> work(lwork), w(n); \ 376 std::vector<long> bwork(1); \ 377 resize(S, n, n); copy(A, S); \ 379 base_type rconde(0), rcondv(0); \ 381 lapack_name(&jobvs, &sort, &select, &sense, &n, &S(0,0), &n, \ 382 &sdim, &w[0], &Q(0,0), &n, &rconde, &rcondv, \ 383 &work[0], &lwork, &rwork[0], &bwork[0], &info); \ 384 GMM_ASSERT1(!info, "SCHUR algorithm failed"); \ 387 geesx_interface(sgeesx_, BLAS_S)
388 geesx_interface(dgeesx_, BLAS_D)
389 geesx_interface2(cgeesx_, BLAS_C)
390 geesx_interface2(zgeesx_, BLAS_Z)
392 template <typename MAT>
393 void schur(const MAT &A_, MAT &S, MAT &Q) {
404 # define gesvd_interface(lapack_name, base_type) inline \ 405 void svd(dense_matrix<base_type> &X, \ 406 dense_matrix<base_type> &U, \ 407 dense_matrix<base_type> &Vtransposed, \ 408 std::vector<base_type> &sigma) { \ 409 GMMLAPACK_TRACE("gesvd_interface"); \ 410 long m = long(mat_nrows(X)), n = long(mat_ncols(X)); \ 411 long mn_min = m < n ? m : n; \ 412 sigma.resize(mn_min); \ 413 std::vector<base_type> work(15 * mn_min); \ 414 long lwork = long(work.size()); \ 416 resize(Vtransposed, n, n); \ 419 lapack_name(&job, &job, &m, &n, &X(0,0), &m, &sigma[0], &U(0,0), \ 420 &m, &Vtransposed(0,0), &n, &work[0], &lwork, &info); \ 423 # define cgesvd_interface(lapack_name, base_type, base_type2) inline \ 424 void svd(dense_matrix<base_type> &X, \ 425 dense_matrix<base_type> &U, \ 426 dense_matrix<base_type> &Vtransposed, \ 427 std::vector<base_type2> &sigma) { \ 428 GMMLAPACK_TRACE("gesvd_interface"); \ 429 long m = long(mat_nrows(X)), n = long(mat_ncols(X)); \ 430 long mn_min = m < n ? m : n; \ 431 sigma.resize(mn_min); \ 432 std::vector<base_type> work(15 * mn_min); \ 433 std::vector<base_type2> rwork(5 * mn_min); \ 434 long lwork = long(work.size()); \ 436 resize(Vtransposed, n, n); \ 439 lapack_name(&job, &job, &m, &n, &X(0,0), &m, &sigma[0], &U(0,0), \ 440 &m, &Vtransposed(0,0), &n, &work[0], &lwork, \ 444 gesvd_interface(sgesvd_, BLAS_S)
445 gesvd_interface(dgesvd_, BLAS_D)
446 cgesvd_interface(cgesvd_, BLAS_C, BLAS_S)
447 cgesvd_interface(zgesvd_, BLAS_Z, BLAS_D)
449 template <typename MAT, typename VEC>
450 void svd(const MAT &X_, MAT &U, MAT &Vtransposed, VEC &sigma) {
452 svd(X, U, Vtransposed, sigma);
464 template <
typename MAT>
465 void schur(
const MAT &A_, MAT &S, MAT &Q)
467 GMM_ASSERT1(
false,
"Use of function schur(A,S,Q) requires GetFEM++ " 468 "to be built with Lapack");
473 #endif // GMM_USES_LAPACK 475 #endif // GMM_LAPACK_INTERFACE_H
LU factorizations and determinant computation for dense matrices.
gmm interface for fortran BLAS.