Added QR factorization algorithms to Cantera's fortran interface
within the numerics directory.
This commit is contained in:
parent
3994bb9438
commit
fa30f63056
3 changed files with 153 additions and 15 deletions
|
|
@ -32,7 +32,7 @@ namespace Cantera {
|
|||
//====================================================================================================================
|
||||
SquareMatrix::SquareMatrix() :
|
||||
DenseMatrix(),
|
||||
m_factored(false)
|
||||
m_factored(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ namespace Cantera {
|
|||
*/
|
||||
SquareMatrix::SquareMatrix(int n, doublereal v) :
|
||||
DenseMatrix(n, n, v),
|
||||
m_factored(false)
|
||||
m_factored(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ namespace Cantera {
|
|||
int SquareMatrix::factor() {
|
||||
integer n = static_cast<int>(nRows());
|
||||
int info=0;
|
||||
m_factored = true;
|
||||
m_factored = 1;
|
||||
ct_dgetrf(n, n, &(*(begin())), static_cast<int>(nRows()),
|
||||
DATA_PTR(ipiv()), info);
|
||||
if (info != 0) {
|
||||
|
|
@ -141,17 +141,47 @@ namespace Cantera {
|
|||
}
|
||||
return info;
|
||||
}
|
||||
//=====================================================================================================================
|
||||
/*
|
||||
* clear the factored flag
|
||||
*/
|
||||
void SquareMatrix::clearFactorFlag() {
|
||||
m_factored = false;
|
||||
m_factored = 0;
|
||||
}
|
||||
/**
|
||||
//=====================================================================================================================
|
||||
/*
|
||||
* set the factored flag
|
||||
*/
|
||||
void SquareMatrix::setFactorFlag() {
|
||||
m_factored = true;
|
||||
m_factored = 1;
|
||||
}
|
||||
//=====================================================================================================================
|
||||
int SquareMatrix::factorQR() {
|
||||
if ((int) tau.size() < m_nrows) {
|
||||
tau.resize(m_nrows, 0.0);
|
||||
work.resize(9 * m_nrows, 0.0);
|
||||
}
|
||||
int info;
|
||||
int lwork = work.size();
|
||||
ct_dgeqrf(m_nrows, m_nrows, &(*(begin())), m_nrows, DATA_PTR(tau), DATA_PTR(work), lwork, info);
|
||||
if (info != 0) {
|
||||
if (m_printLevel) {
|
||||
writelogf("SquareMatrix::factorQR(): DGEQRF returned INFO = %d\n", info);
|
||||
}
|
||||
if (! m_useReturnErrorCode) {
|
||||
throw CELapackError("SquareMatrix::factorQR()", "DGEQRF returned INFO = " + int2str(info));
|
||||
}
|
||||
}
|
||||
int lworkOpt = work[0];
|
||||
if (lworkOpt != lwork) {
|
||||
work.resize(lworkOpt);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
//=====================================================================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,15 @@ namespace Cantera {
|
|||
* boolean to indicate that the matrix is now A-1.
|
||||
*/
|
||||
int factor();
|
||||
|
||||
//! Factors the A matrix using the QR algorithm, overwriting A
|
||||
/*!
|
||||
* we set m_factored to 2 to indicate the matrix is now QR factored
|
||||
*
|
||||
* @return Returns the info variable from lapack
|
||||
*/
|
||||
int factorQR();
|
||||
|
||||
/**
|
||||
* clear the factored flag
|
||||
*/
|
||||
|
|
@ -89,7 +98,10 @@ namespace Cantera {
|
|||
/*
|
||||
* the factor flag
|
||||
*/
|
||||
bool m_factored;
|
||||
int m_factored;
|
||||
|
||||
vector_fp tau;
|
||||
vector_fp work;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@
|
|||
|
||||
#define _DSCAL_ dscal
|
||||
|
||||
#define _DGEQRF_ dgeqrf
|
||||
#define _DORMQR_ dormqr
|
||||
|
||||
#else
|
||||
|
||||
#define _DGEMV_ dgemv_
|
||||
|
|
@ -48,14 +51,21 @@
|
|||
|
||||
#define _DSCAL_ dscal_
|
||||
|
||||
#define _DGEQRF_ dgreqrf_
|
||||
#define _DORMQR_ dormqr_
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
namespace ctlapack {
|
||||
typedef enum {Transpose = 1, NoTranspose = 0} transpose_t;
|
||||
typedef enum {ColMajor = 1, RowMajor = 0} storage_t;
|
||||
typedef enum {UpperTriangular = 0, LowerTriangular = 1} upperlower_t;
|
||||
typedef enum {Left = 0, Right = 1} side_t;
|
||||
}
|
||||
const char no_yes[2] = {'N', 'T'};
|
||||
const char upper_lower[2] = {'U', 'L'};
|
||||
const char left_right[2] = {'L', 'R'};
|
||||
|
||||
#ifdef USE_CBLAS
|
||||
#include <Accelerate.h>
|
||||
|
|
@ -129,7 +139,36 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
int _DSCAL_(integer *n, doublereal *da, doublereal *dx, integer *incx);
|
||||
void cblas_dscal(const int N, const double alpha, double *X, const int incX);
|
||||
void cblas_dscal(const int N, const double alpha, double *X, const int incX);
|
||||
|
||||
|
||||
int _DGEQRF_(const integer* m, const integer* n, doublereal* a, const integer* lda,
|
||||
doublereal* tau, doublereal* work, const integer *lwork, integer *info);
|
||||
|
||||
#ifdef LAPACK_FTN_STRING_LEN_AT_END
|
||||
int _DORMQR_(const char* side, const char* trans, const integer* m, const integer* n,
|
||||
const integer * k, doublereal* a, const integer* lda,
|
||||
doublereal* tau, doublereal* c, const integer* ldc,
|
||||
doublereal* work, const integer *lwork, integer *info, ftnlen sisize, ftnlen trsize);
|
||||
#else
|
||||
int _DORMQR_(const char* side, ftnlen sisize, const char* trans, ftnlen trsize, const integer* m,
|
||||
const integer* n, const integer * k, doublereal* a, const integer* lda,
|
||||
doublereal* tau,doublereal* c, const integer* ldc,
|
||||
doublereal* work, const integer *lwork, integer *info);
|
||||
#endif
|
||||
|
||||
#ifdef LAPACK_FTN_STRING_LEN_AT_END
|
||||
int _DTRTRS_(const char* uplo, const char* trans, const char *diag, const integer* n,
|
||||
const integer * nrhs, doublereal* a, const integer* lda,
|
||||
doublereal* b, const integer* ldb, integer *info,
|
||||
ftnlen upsize, ftnlen trsize, ftnlen disize);
|
||||
#else
|
||||
int _DTRTRS_(const char* uplo, ftnlen upsize, const char* trans, ftnlen trsize, const char *diag,
|
||||
ftnlen disize, const integer* n, const integer * nrhs, doublereal* a, const integer* lda,
|
||||
doublereal* b, const integer* ldb, integer *info);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
}
|
||||
//#endif
|
||||
|
|
@ -230,11 +269,9 @@ namespace Cantera {
|
|||
#else
|
||||
ftnlen trsize = 1;
|
||||
#ifdef LAPACK_FTN_STRING_LEN_AT_END
|
||||
_DGETRS_(&tr, &f_n, &f_nrhs, a, &f_lda, ipiv, b, &f_ldb,
|
||||
&f_info, trsize);
|
||||
_DGETRS_(&tr, &f_n, &f_nrhs, a, &f_lda, ipiv, b, &f_ldb, &f_info, trsize);
|
||||
#else
|
||||
_DGETRS_(&tr, trsize, &f_n, &f_nrhs, a, &f_lda, ipiv, b, &f_ldb,
|
||||
&f_info);
|
||||
_DGETRS_(&tr, trsize, &f_n, &f_nrhs, a, &f_lda, ipiv, b, &f_ldb, &f_info);
|
||||
#endif
|
||||
#endif
|
||||
info = f_info;
|
||||
|
|
@ -260,13 +297,72 @@ namespace Cantera {
|
|||
rank = f_rank;
|
||||
}
|
||||
|
||||
inline void ct_dscal(int n, doublereal da, doublereal* dx, int incx) {
|
||||
inline void ct_dscal(int n, doublereal da, doublereal* dx, int incx) {
|
||||
//integer f_n = n, f_incx = incx;
|
||||
//_DSCAL_(&f_n, &da, dx, &f_incx);
|
||||
cblas_dscal(n, da, dx, incx);
|
||||
cblas_dscal(n, da, dx, incx);
|
||||
}
|
||||
|
||||
inline void ct_dgeqrf(int m, int n, doublereal* a, int lda, doublereal *tau,
|
||||
doublereal* work, int lwork, int &info) {
|
||||
integer f_m = m;
|
||||
integer f_n = n;
|
||||
integer f_lda = lda;
|
||||
integer f_lwork = lwork;
|
||||
integer f_info = info;
|
||||
_DGEQRF_(&f_m, &f_n, a, &f_lda, tau, work, &f_lwork, &f_info);
|
||||
info = f_info;
|
||||
}
|
||||
|
||||
inline void ct_dormqr(ctlapack::side_t rlside, ctlapack::transpose_t trans, int m,
|
||||
int n, int k, doublereal* a, int lda, doublereal *tau, doublereal *c, int ldc,
|
||||
doublereal *work, const integer *lwork, int &info) {
|
||||
char side = left_right[rlside];
|
||||
char tr = no_yes[trans];
|
||||
integer f_m = m;
|
||||
integer f_n = n;
|
||||
integer f_k = k;
|
||||
integer f_lda = lda;
|
||||
integer f_ldc = ldc;
|
||||
integer f_info = info;
|
||||
#ifdef NO_FTN_STRING_LEN_AT_END
|
||||
_DORMQR_(&side, &tr, &f_m, &f_n, &f_k, a, &f_lda, tau, c, &f_ldc, work, lwork, &f_info);
|
||||
#else
|
||||
ftnlen trsize = 1;
|
||||
#ifdef LAPACK_FTN_STRING_LEN_AT_END
|
||||
_DORMQR_(&side, &tr, &f_m, &f_n, &f_k, a, &f_lda, tau, c, &f_ldc, work, lwork, &f_info, trsize, trsize);
|
||||
#else
|
||||
_DORMQR_(&side, trsize, &tr, trsize, &f_m, &f_n, &f_k, a, &f_lda, tau, c, &f_ldc, work, lwork, &f_info);
|
||||
#endif
|
||||
#endif
|
||||
info = f_info;
|
||||
}
|
||||
|
||||
inline void ct_dtrtrs(ctlapack::upperlower_t uplot, ctlapack::transpose_t trans, const char *diag,
|
||||
int n, int nrhs, doublereal* a, int lda, doublereal *b, int ldb, int &info) {
|
||||
char uplo = upper_lower[uplot];
|
||||
char tr = no_yes[trans];
|
||||
char dd = 'N';
|
||||
if (diag) {
|
||||
dd = diag[0];
|
||||
}
|
||||
|
||||
integer f_n = n;
|
||||
integer f_nrhs = nrhs;
|
||||
integer f_lda = lda;
|
||||
integer f_ldb = ldb;
|
||||
integer f_info = info;
|
||||
#ifdef NO_FTN_STRING_LEN_AT_END
|
||||
_DTRTRS_(&uplo, &tr, &dd, &f_n, &f_nrhs, a, &f_lda, b, &f_ldb, &f_info);
|
||||
#else
|
||||
ftnlen trsize = 1;
|
||||
#ifdef LAPACK_FTN_STRING_LEN_AT_END
|
||||
_DTRTRS_(&uplo, &tr, &dd, &f_n, &f_nrhs, a, &f_lda, b, &f_ldb, &f_info, trsize, trsize, trsize);
|
||||
#else
|
||||
_DTRTRS_(&uplo, trsize, &tr, trsize, &dd, trsize, &f_n, &f_nrhs, a, &f_lda, b, &f_ldb, &f_info);
|
||||
#endif
|
||||
#endif
|
||||
info = f_info;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue