2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-08 13:04:56 +00:00

Windows fixes

This commit is contained in:
Jack Andersen
2018-10-14 10:16:21 -10:00
parent 1559163f98
commit 1851308021
68 changed files with 1343 additions and 968 deletions

7
gmm/gmm_arch_config.h Normal file
View File

@@ -0,0 +1,7 @@
# ifndef _SRC_GMM_GMM_ARCH_CONFIG_H
#define _SRC_GMM_GMM_ARCH_CONFIG_H 1
// enable the following line for OpenMP support
// #define GMM_HAVE_OPENMP
//
/* once: _SRC_GMM_GMM_ARCH_CONFIG_H */
#endif

View File

@@ -651,6 +651,38 @@ namespace gmm {
return res;
}
/** 1-distance between two vectors */
template <typename V1, typename V2> inline
typename number_traits<typename linalg_traits<V1>::value_type>
::magnitude_type
vect_dist1(const V1 &v1, const V2 &v2) { // not fully optimized
typedef typename linalg_traits<V1>::value_type T;
typedef typename number_traits<T>::magnitude_type R;
auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
size_type k1(0), k2(0);
R res(0);
while (it1 != ite1 && it2 != ite2) {
size_type i1 = index_of_it(it1, k1,
typename linalg_traits<V1>::storage_type());
size_type i2 = index_of_it(it2, k2,
typename linalg_traits<V2>::storage_type());
if (i1 == i2) {
res += gmm::abs(*it2 - *it1); ++it1; ++k1; ++it2; ++k2;
}
else if (i1 < i2) {
res += gmm::abs(*it1); ++it1; ++k1;
}
else {
res += gmm::abs(*it2); ++it2; ++k2;
}
}
while (it1 != ite1) { res += gmm::abs(*it1); ++it1; }
while (it2 != ite2) { res += gmm::abs(*it2); ++it2; }
return res;
}
/* ******************************************************************** */
/* vector Infinity norm */
/* ******************************************************************** */
@@ -666,6 +698,38 @@ namespace gmm {
return res;
}
/** Infinity distance between two vectors */
template <typename V1, typename V2> inline
typename number_traits<typename linalg_traits<V1>::value_type>
::magnitude_type
vect_distinf(const V1 &v1, const V2 &v2) { // not fully optimized
typedef typename linalg_traits<V1>::value_type T;
typedef typename number_traits<T>::magnitude_type R;
auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1);
auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2);
size_type k1(0), k2(0);
R res(0);
while (it1 != ite1 && it2 != ite2) {
size_type i1 = index_of_it(it1, k1,
typename linalg_traits<V1>::storage_type());
size_type i2 = index_of_it(it2, k2,
typename linalg_traits<V2>::storage_type());
if (i1 == i2) {
res = std::max(res, gmm::abs(*it2 - *it1)); ++it1; ++k1; ++it2; ++k2;
}
else if (i1 < i2) {
res = std::max(res, gmm::abs(*it1)); ++it1; ++k1;
}
else {
res = std::max(res, gmm::abs(*it2)); ++it2; ++k2;
}
}
while (it1 != ite1) { res = std::max(res, gmm::abs(*it1)); ++it1; }
while (it2 != ite2) { res = std::max(res, gmm::abs(*it2)); ++it2; }
return res;
}
/* ******************************************************************** */
/* matrix norm1 */
/* ******************************************************************** */

View File

@@ -151,13 +151,13 @@ namespace gmm {
/* BLAS functions used. */
/* ********************************************************************* */
extern "C" {
void daxpy_(const int *n, const double *alpha, const double *x,
const int *incx, double *y, const int *incy);
void dgemm_(const char *tA, const char *tB, const int *m,
const int *n, const int *k, const double *alpha,
const double *A, const int *ldA, const double *B,
const int *ldB, const double *beta, double *C,
const int *ldC);
void daxpy_(const long *n, const double *alpha, const double *x,
const long *incx, double *y, const long *incy);
void dgemm_(const char *tA, const char *tB, const long *m,
const long *n, const long *k, const double *alpha,
const double *A, const long *ldA, const double *B,
const long *ldB, const double *beta, double *C,
const long *ldC);
void sgemm_(...); void cgemm_(...); void zgemm_(...);
void sgemv_(...); void dgemv_(...); void cgemv_(...); void zgemv_(...);
void strsv_(...); void dtrsv_(...); void ctrsv_(...); void ztrsv_(...);
@@ -180,7 +180,7 @@ namespace gmm {
inline number_traits<base_type >::magnitude_type \
vect_norm2(param1(base_type)) { \
GMMLAPACK_TRACE("nrm2_interface"); \
int inc(1), n(int(vect_size(x))); trans1(base_type); \
long inc(1), n(long(vect_size(x))); trans1(base_type); \
return blas_name(&n, &x[0], &inc); \
}
@@ -200,7 +200,7 @@ namespace gmm {
blas_name, base_type) \
inline base_type vect_sp(param1(base_type), param2(base_type)) { \
GMMLAPACK_TRACE("dot_interface"); \
trans1(base_type); trans2(base_type); int inc(1), n(int(vect_size(y)));\
trans1(base_type); trans2(base_type); long inc(1), n(long(vect_size(y)));\
return mult1 mult2 blas_name(&n, &x[0], &inc, &y[0], &inc); \
}
@@ -267,7 +267,7 @@ namespace gmm {
blas_name, base_type) \
inline base_type vect_hp(param1(base_type), param2(base_type)) { \
GMMLAPACK_TRACE("dotc_interface"); \
trans1(base_type); trans2(base_type); int inc(1), n(int(vect_size(y)));\
trans1(base_type); trans2(base_type); long inc(1), n(long(vect_size(y)));\
return mult1 mult2 blas_name(&n, &x[0], &inc, &y[0], &inc); \
}
@@ -332,7 +332,7 @@ namespace gmm {
# define axpy_interface(param1, trans1, blas_name, base_type) \
inline void add(param1(base_type), std::vector<base_type > &y) { \
GMMLAPACK_TRACE("axpy_interface"); \
int inc(1), n(int(vect_size(y))); trans1(base_type); \
long inc(1), n(long(vect_size(y))); trans1(base_type); \
if (n == 0) return; \
blas_name(&n, &a, &x[0], &inc, &y[0], &inc); \
}
@@ -367,7 +367,7 @@ namespace gmm {
std::vector<base_type > &z, orien) { \
GMMLAPACK_TRACE("gemv_interface"); \
trans1(base_type); trans2(base_type); base_type beta(1); \
int m(int(mat_nrows(A))), lda(m), n(int(mat_ncols(A))), inc(1); \
long m(long(mat_nrows(A))), lda(m), n(long(mat_ncols(A))), inc(1); \
if (m && n) blas_name(&t, &m, &n, &alpha, &A(0,0), &lda, &x[0], &inc, \
&beta, &z[0], &inc); \
else gmm::clear(z); \
@@ -489,7 +489,7 @@ namespace gmm {
std::vector<base_type > &z, orien) { \
GMMLAPACK_TRACE("gemv_interface2"); \
trans1(base_type); trans2(base_type); base_type beta(0); \
int m(int(mat_nrows(A))), lda(m), n(int(mat_ncols(A))), inc(1); \
long m(long(mat_nrows(A))), lda(m), n(long(mat_ncols(A))), inc(1); \
if (m && n) \
blas_name(&t, &m, &n, &alpha, &A(0,0), &lda, &x[0], &inc, &beta, \
&z[0], &inc); \
@@ -586,8 +586,8 @@ namespace gmm {
const std::vector<base_type > &V, \
const std::vector<base_type > &W) { \
GMMLAPACK_TRACE("ger_interface"); \
int m(int(mat_nrows(A))), lda = m, n(int(mat_ncols(A))); \
int incx = 1, incy = 1; \
long m(long(mat_nrows(A))), lda = m, n(long(mat_ncols(A))); \
long incx = 1, incy = 1; \
base_type alpha(1); \
if (m && n) \
blas_name(&m, &n, &alpha, &V[0], &incx, &W[0], &incy, &A(0,0), &lda);\
@@ -604,8 +604,8 @@ namespace gmm {
const std::vector<base_type > &W) { \
GMMLAPACK_TRACE("ger_interface"); \
gemv_trans2_s(base_type); \
int m(int(mat_nrows(A))), lda = m, n(int(mat_ncols(A))); \
int incx = 1, incy = 1; \
long m(long(mat_nrows(A))), lda = m, n(long(mat_ncols(A))); \
long incx = 1, incy = 1; \
if (m && n) \
blas_name(&m, &n, &alpha, &x[0], &incx, &W[0], &incy, &A(0,0), &lda);\
}
@@ -621,8 +621,8 @@ namespace gmm {
gemv_p2_s(base_type)) { \
GMMLAPACK_TRACE("ger_interface"); \
gemv_trans2_s(base_type); \
int m(int(mat_nrows(A))), lda = m, n(int(mat_ncols(A))); \
int incx = 1, incy = 1; \
long m(long(mat_nrows(A))), lda = m, n(long(mat_ncols(A))); \
long incx = 1, incy = 1; \
base_type al2 = gmm::conj(alpha); \
if (m && n) \
blas_name(&m, &n, &al2, &V[0], &incx, &x[0], &incy, &A(0,0), &lda); \
@@ -643,9 +643,9 @@ namespace gmm {
dense_matrix<base_type > &C, c_mult) { \
GMMLAPACK_TRACE("gemm_interface_nn"); \
const char t = 'N'; \
int m(int(mat_nrows(A))), lda = m, k(int(mat_ncols(A))); \
int n(int(mat_ncols(B))); \
int ldb = k, ldc = m; \
long m(long(mat_nrows(A))), lda = m, k(long(mat_ncols(A))); \
long n(long(mat_ncols(B))); \
long ldb = k, ldc = m; \
base_type alpha(1), beta(0); \
if (m && k && n) \
blas_name(&t, &t, &m, &n, &k, &alpha, \
@@ -671,8 +671,8 @@ namespace gmm {
dense_matrix<base_type > &A \
= const_cast<dense_matrix<base_type > &>(*(linalg_origin(A_))); \
const char t = 'T', u = 'N'; \
int m(int(mat_ncols(A))), k(int(mat_nrows(A))), n(int(mat_ncols(B))); \
int lda = k, ldb = k, ldc = m; \
long m(long(mat_ncols(A))), k(long(mat_nrows(A))), n(long(mat_ncols(B))); \
long lda = k, ldb = k, ldc = m; \
base_type alpha(1), beta(0); \
if (m && k && n) \
blas_name(&t, &u, &m, &n, &k, &alpha, \
@@ -701,9 +701,9 @@ namespace gmm {
dense_matrix<base_type > &B \
= const_cast<dense_matrix<base_type > &>(*(linalg_origin(B_))); \
const char t = 'N', u = 'T'; \
int m(int(mat_nrows(A))), lda = m, k(int(mat_ncols(A))); \
int n(int(mat_nrows(B))); \
int ldb = n, ldc = m; \
long m(long(mat_nrows(A))), lda = m, k(long(mat_ncols(A))); \
long n(long(mat_nrows(B))); \
long ldb = n, ldc = m; \
base_type alpha(1), beta(0); \
if (m && k && n) \
blas_name(&t, &u, &m, &n, &k, &alpha, \
@@ -735,8 +735,8 @@ namespace gmm {
dense_matrix<base_type > &B \
= const_cast<dense_matrix<base_type > &>(*(linalg_origin(B_))); \
const char t = 'T', u = 'T'; \
int m(int(mat_ncols(A))), k(int(mat_nrows(A))), n(int(mat_nrows(B))); \
int lda = k, ldb = n, ldc = m; \
long m(long(mat_ncols(A))), k(long(mat_nrows(A))), n(long(mat_nrows(B))); \
long lda = k, ldb = n, ldc = m; \
base_type alpha(1), beta(0); \
if (m && k && n) \
blas_name(&t, &u, &m, &n, &k, &alpha, \
@@ -775,8 +775,8 @@ namespace gmm {
dense_matrix<base_type > &A \
= const_cast<dense_matrix<base_type > &>(*(linalg_origin(A_))); \
const char t = 'C', u = 'N'; \
int m(int(mat_ncols(A))), k(int(mat_nrows(A))), n(int(mat_ncols(B))); \
int lda = k, ldb = k, ldc = m; \
long m(long(mat_ncols(A))), k(long(mat_nrows(A))), n(long(mat_ncols(B))); \
long lda = k, ldb = k, ldc = m; \
base_type alpha(1), beta(0); \
if (m && k && n) \
blas_name(&t, &u, &m, &n, &k, &alpha, \
@@ -801,8 +801,8 @@ namespace gmm {
dense_matrix<base_type > &B \
= const_cast<dense_matrix<base_type > &>(*(linalg_origin(B_))); \
const char t = 'N', u = 'C'; \
int m(int(mat_nrows(A))), lda = m, k(int(mat_ncols(A))); \
int n(int(mat_nrows(B))), ldb = n, ldc = m; \
long m(long(mat_nrows(A))), lda = m, k(long(mat_ncols(A))); \
long n(long(mat_nrows(B))), ldb = n, ldc = m; \
base_type alpha(1), beta(0); \
if (m && k && n) \
blas_name(&t, &u, &m, &n, &k, &alpha, \
@@ -830,8 +830,8 @@ namespace gmm {
dense_matrix<base_type > &B \
= const_cast<dense_matrix<base_type > &>(*(linalg_origin(B_))); \
const char t = 'C', u = 'C'; \
int m(int(mat_ncols(A))), k(int(mat_nrows(A))), lda = k; \
int n(int(mat_nrows(B))), ldb = n, ldc = m; \
long m(long(mat_ncols(A))), k(long(mat_nrows(A))), lda = k; \
long n(long(mat_nrows(B))), ldb = n, ldc = m; \
base_type alpha(1), beta(0); \
if (m && k && n) \
blas_name(&t, &u, &m, &n, &k, &alpha, \
@@ -853,7 +853,7 @@ namespace gmm {
size_type k, bool is_unit) { \
GMMLAPACK_TRACE("trsv_interface"); \
loru; trans1(base_type); char d = is_unit ? 'U' : 'N'; \
int lda(int(mat_nrows(A))), inc(1), n = int(k); \
long lda(long(mat_nrows(A))), inc(1), n = long(k); \
if (lda) blas_name(&l, &t, &d, &n, &A(0,0), &lda, &x[0], &inc); \
}

View File

@@ -923,22 +923,21 @@ namespace gmm {
template <typename IT, typename ORG, typename VECT> inline
void set_to_end(IT &, ORG, const VECT *, linalg_const) { }
template <typename IT, typename ORG, typename VECT> inline
void set_to_begin(IT &, ORG, VECT *v, linalg_modifiable)
{ GMM_ASSERT3(!is_sparse(*v), "internal_error"); v = 0; }
{ GMM_ASSERT3(!is_sparse(*v), "internal_error"); (void)v; }
template <typename IT, typename ORG, typename VECT> inline
void set_to_begin(IT &, ORG, const VECT *v, linalg_modifiable)
{ GMM_ASSERT3(!is_sparse(*v), "internal_error"); v = 0; }
{ GMM_ASSERT3(!is_sparse(*v), "internal_error"); (void)v; }
template <typename IT, typename ORG, typename VECT> inline
void set_to_end(IT &, ORG, VECT *v, linalg_modifiable)
{ GMM_ASSERT3(!is_sparse(*v), "internal_error"); v = 0; }
{ GMM_ASSERT3(!is_sparse(*v), "internal_error"); (void)v; }
template <typename IT, typename ORG, typename VECT> inline
void set_to_end(IT &, ORG, const VECT *v, linalg_modifiable)
{ GMM_ASSERT3(!is_sparse(*v), "internal_error"); v = 0; }
{ GMM_ASSERT3(!is_sparse(*v), "internal_error"); (void)v; }
/* ******************************************************************** */
/* General index for certain algorithms. */
@@ -966,7 +965,7 @@ namespace gmm {
tol = numeric_limits<T>::epsilon();
else {
int i=int(sizeof(T)/4); while(i-- > 0) tol*=T(1E-8);
GMM_WARNING1("The numeric type " /*<< typeid(T).name()*/
GMM_WARNING1("The numeric type " /*<< typeid(T).name()*/
<< " has no numeric_limits defined !!\n"
<< "Taking " << tol << " as default tolerance");
}
@@ -984,7 +983,7 @@ namespace gmm {
mi = std::numeric_limits<T>::min();
else {
mi = T(0);
GMM_WARNING1("The numeric type " /*<< typeid(T).name()*/
GMM_WARNING1("The numeric type " /*<< typeid(T).name()*/
<< " has no numeric_limits defined !!\n"
<< "Taking 0 as default minimum");
}
@@ -1002,7 +1001,7 @@ namespace gmm {
mi = std::numeric_limits<T>::max();
else {
mi = T(1);
GMM_WARNING1("The numeric type " /*<< typeid(T).name()*/
GMM_WARNING1("The numeric type " /*<< typeid(T).name()*/
<< " has no numeric_limits defined !!\n"
<< "Taking 1 as default maximum !");
}

View File

@@ -70,10 +70,50 @@
#define GMM_DENSE_LU_H
#include "gmm_dense_Householder.h"
#include "gmm_opt.h"
namespace gmm {
/* ********************************************************************** */
/* IPVT structure. */
/* ********************************************************************** */
// For compatibility with lapack version with 64 or 32 bit integer.
// Should be replaced by std::vector<size_type> if 32 bit integer version
// of lapack is not used anymore (and lapack_ipvt_int set to size_type)
// Do not use iterators of this interface container
class lapack_ipvt : public std::vector<size_type> {
bool is_int64;
size_type &operator[](size_type i)
{ return std::vector<size_type>::operator[](i); }
size_type operator[] (size_type i) const
{ return std::vector<size_type>::operator[](i); }
void begin(void) const {}
void begin(void) {}
void end(void) const {}
void end(void) {}
public:
void set_to_int32() { is_int64 = false; }
const size_type *pfirst() const
{ return &(*(std::vector<size_type>::begin())); }
size_type *pfirst() { return &(*(std::vector<size_type>::begin())); }
lapack_ipvt(size_type n) : std::vector<size_type>(n), is_int64(true) {}
size_type get(size_type i) const {
const size_type *p = pfirst();
return is_int64 ? p[i] : size_type(((const int *)(p))[i]);
}
void set(size_type i, size_type val) {
size_type *p = pfirst();
if (is_int64) p[i] = val; else ((int *)(p))[i] = int(val);
}
};
}
#include "gmm_opt.h"
namespace gmm {
/** LU Factorization of a general (dense) matrix (real or complex).
@@ -85,24 +125,23 @@ namespace gmm {
The pivot indices in ipvt are indexed starting from 1
so that this is compatible with LAPACK (Fortran).
*/
template <typename DenseMatrix, typename Pvector>
size_type lu_factor(DenseMatrix& A, Pvector& ipvt) {
template <typename DenseMatrix>
size_type lu_factor(DenseMatrix& A, lapack_ipvt& ipvt) {
typedef typename linalg_traits<DenseMatrix>::value_type T;
typedef typename linalg_traits<Pvector>::value_type int_T;
typedef typename number_traits<T>::magnitude_type R;
size_type info(0), i, j, jp, M(mat_nrows(A)), N(mat_ncols(A));
size_type NN = std::min(M, N);
std::vector<T> c(M), r(N);
GMM_ASSERT2(ipvt.size()+1 >= NN, "IPVT too small");
for (i = 0; i+1 < NN; ++i) ipvt[i] = int_T(i);
for (i = 0; i+1 < NN; ++i) ipvt.set(i, i);
if (M || N) {
for (j = 0; j+1 < NN; ++j) {
R max = gmm::abs(A(j,j)); jp = j;
for (i = j+1; i < M; ++i) /* find pivot. */
if (gmm::abs(A(i,j)) > max) { jp = i; max = gmm::abs(A(i,j)); }
ipvt[j] = int_T(jp + 1);
ipvt.set(j, jp + 1);
if (max == R(0)) { info = j + 1; break; }
if (jp != j) for (i = 0; i < N; ++i) std::swap(A(jp, i), A(j, i));
@@ -112,7 +151,7 @@ namespace gmm {
rank_one_update(sub_matrix(A, sub_interval(j+1, M-j-1),
sub_interval(j+1, N-j-1)), c, conjugated(r));
}
ipvt[NN-1] = int_T(NN);
ipvt.set(NN-1, NN);
}
return info;
}
@@ -126,7 +165,7 @@ namespace gmm {
typedef typename linalg_traits<DenseMatrix>::value_type T;
copy(b, x);
for(size_type i = 0; i < pvector.size(); ++i) {
size_type perm = pvector[i]-1; // permutations stored in 1's offset
size_type perm = pvector.get(i)-1; // permutations stored in 1's offset
if(i != perm) { T aux = x[i]; x[i] = x[perm]; x[perm] = aux; }
}
/* solve Ax = b -> LUx = b -> Ux = L^-1 b. */
@@ -138,7 +177,7 @@ namespace gmm {
void lu_solve(const DenseMatrix &A, VectorX &x, const VectorB &b) {
typedef typename linalg_traits<DenseMatrix>::value_type T;
dense_matrix<T> B(mat_nrows(A), mat_ncols(A));
std::vector<int> ipvt(mat_nrows(A));
lapack_ipvt ipvt(mat_nrows(A));
gmm::copy(A, B);
size_type info = lu_factor(B, ipvt);
GMM_ASSERT1(!info, "Singular system, pivot = " << info);
@@ -154,10 +193,9 @@ namespace gmm {
lower_tri_solve(transposed(LU), x, false);
upper_tri_solve(transposed(LU), x, true);
for(size_type i = pvector.size(); i > 0; --i) {
size_type perm = pvector[i-1]-1; // permutations stored in 1's offset
size_type perm = pvector.get(i-1)-1; // permutations stored in 1's offset
if(i-1 != perm) { T aux = x[i-1]; x[i-1] = x[perm]; x[perm] = aux; }
}
}
@@ -212,7 +250,7 @@ namespace gmm {
typedef typename linalg_traits<DenseMatrix>::value_type T;
DenseMatrix& A = const_cast<DenseMatrix&>(A_);
dense_matrix<T> B(mat_nrows(A), mat_ncols(A));
std::vector<int> ipvt(mat_nrows(A));
lapack_ipvt ipvt(mat_nrows(A));
gmm::copy(A, B);
size_type info = lu_factor(B, ipvt);
if (doassert) GMM_ASSERT1(!info, "Non invertible matrix, pivot = "<<info);
@@ -229,7 +267,7 @@ namespace gmm {
for (size_type j = 0; j < std::min(mat_nrows(LU), mat_ncols(LU)); ++j)
det *= LU(j,j);
for(size_type i = 0; i < pvector.size(); ++i)
if (i != size_type(pvector[i]-1)) { det = -det; }
if (i != size_type(pvector.get(i)-1)) { det = -det; }
return det;
}
@@ -238,7 +276,7 @@ namespace gmm {
lu_det(const DenseMatrix& A) {
typedef typename linalg_traits<DenseMatrix>::value_type T;
dense_matrix<T> B(mat_nrows(A), mat_ncols(A));
std::vector<int> ipvt(mat_nrows(A));
lapack_ipvt ipvt(mat_nrows(A));
gmm::copy(A, B);
lu_factor(B, ipvt);
return lu_det(B, ipvt);

View File

@@ -81,7 +81,7 @@ namespace gmm {
std::vector<size_type> ns(dim), na(dim), nu(dim);
for (size_type i = 0; i < nbpts; ++i) {
for (int k = 0; k < dim; ++k) {
double a = (pts[i][k] - pmin[k]) / msize;
register double a = (pts[i][k] - pmin[k]) / msize;
ns[k] = size_type(a) - 1; na[k] = 0;
pts1[k] = int(a + overlap); pts2[k] = int(ceil(a-1.0-overlap));
}

View File

@@ -29,7 +29,7 @@
===========================================================================*/
/** @file gmm_except.h
/** @file gmm_except.h
@author Yves Renard <Yves.Renard@insa-lyon.fr>
@author Julien Pommier <Julien.Pommier@insa-toulouse.fr>
@date September 01, 2002.
@@ -39,28 +39,39 @@
#ifndef GMM_EXCEPT_H__
#define GMM_EXCEPT_H__
#include <sstream>
#include "gmm_std.h"
#include "gmm_feedback_management.h"
//provides external implementation of gmm_exception and logging.
#ifndef EXTERNAL_EXCEPT_
namespace gmm {
/* *********************************************************************** */
/* GetFEM++ generic errors. */
/* GetFEM++ generic errors. */
/* *********************************************************************** */
// std logic_error with error level information
class gmm_error: public std::logic_error {
public:
gmm_error(const std::string& what_arg): std::logic_error (what_arg) {}
gmm_error(const std::string& what_arg, int errorLevel = 1):
std::logic_error (what_arg), errorLevel_(errorLevel) {}
int errLevel() {return errorLevel_;}
private:
int errorLevel_;
};
#ifdef GETFEM_HAVE_PRETTY_FUNCTION
# define GMM_PRETTY_FUNCTION __PRETTY_FUNCTION__
#elif _MSC_VER
# define GMM_PRETTY_FUNCTION __FUNCTION__
#else
# define GMM_PRETTY_FUNCTION ""
#endif
// Errors : GMM_THROW should not be used on its own.
// GMM_ASSERT1 : Non-maskable errors. Typically for in/ouput and
// when the test do not significantly reduces the performance.
@@ -72,19 +83,29 @@ namespace gmm {
// __EXCEPTIONS is defined by gcc, _CPPUNWIND is defined by visual c++
#if defined(__EXCEPTIONS) || defined(_CPPUNWIND)
inline void short_error_throw(const char *file, int line, const char *func,
const char *errormsg) {
const char *errormsg) {
std::stringstream msg__;
msg__ << "Error in " << file << ", line " << line << " " << func
<< ": \n" << errormsg << std::ends;
<< ": \n" << errormsg << std::ends;
throw gmm::gmm_error(msg__.str());
}
# define GMM_THROW_(type, errormsg) { \
std::stringstream msg__; \
msg__ << "Error in " << __FILE__ << ", line " \
<< __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n" \
<< errormsg << std::ends; \
throw (type)(msg__.str()); \
# define GMM_THROW_(type, errormsg) { \
std::stringstream msg__; \
msg__ << "Error in " << __FILE__ << ", line " \
<< __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n" \
<< errormsg << std::ends; \
throw (type)(msg__.str()); \
}
# define GMM_THROW_AT_LEVEL(errormsg, level) \
{ \
std::stringstream msg; \
msg << "Error in " << __FILE__ << ", line " \
<< __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n" \
<< errormsg << std::ends; \
throw gmm::gmm_error(msg.str(), level); \
}
#else
#ifndef _MSC_VER
# define abort_no_return() ::abort()
@@ -94,57 +115,69 @@ namespace gmm {
#endif
inline void short_error_throw(const char *file, int line, const char *func,
const char *errormsg) {
const char *errormsg) {
std::stringstream msg__;
msg__ << "Error in " << file << ", line " << line << " " << func
<< ": \n" << errormsg << std::ends;
<< ": \n" << errormsg << std::ends;
std::cerr << msg__.str() << std::endl;
abort_no_return();
abort_no_return();
}
# define GMM_THROW_(type, errormsg) { \
std::stringstream msg__; \
msg__ << "Error in " << __FILE__ << ", line " \
<< __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n" \
<< errormsg; \
std::cerr << msg__.str() << std::endl; \
abort_no_return(); \
# define GMM_THROW_(type, errormsg) { \
std::stringstream msg__; \
msg__ << "Error in " << __FILE__ << ", line " \
<< __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n" \
<< errormsg; \
std::cerr << msg__.str() << std::endl; \
abort_no_return(); \
}
# define GMM_THROW_AT_LEVEL(errormsg, level) \
{ \
std::stringstream msg__; \
msg__ << "Error in " << __FILE__ << ", line " \
<< __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n" \
<< errormsg << " at level " << level; \
std::cerr << msg__.str() << std::endl; \
abort_no_return(); \
}
#endif
# define GMM_ASSERT1(test, errormsg) \
{ if (!(test)) GMM_THROW_(gmm::gmm_error, errormsg); }
inline void GMM_THROW() {}
inline void GMM_THROW() {}
#define GMM_THROW(a, b) { GMM_THROW_(a,b); gmm::GMM_THROW(); }
# define GMM_THROW_DEFAULT(errormsg) GMM_THROW_AT_LEVEL(errormsg, 1)
// This allows not to compile some assertions
#ifndef GMM_ASSERT_LEVEL
#if defined(NDEBUG)
# define GMM_ASSERT_LEVEL 1
#elif defined(DEBUG_MODE)
# define GMM_ASSERT_LEVEL 3
#else
# define GMM_ASSERT_LEVEL 2
#endif
#endif
# define GMM_ASSERT1(test, errormsg) { if (!(test)) GMM_THROW_AT_LEVEL(errormsg, 1); }
#if GMM_ASSERT_LEVEL < 2
# define GMM_ASSERT2(test, errormsg) {}
# define GMM_ASSERT3(test, errormsg) {}
#elif !defined(GMM_FULL_NDEBUG)
# define GMM_ASSERT2(test, errormsg) \
{ if (!(test)) GMM_THROW_(gmm::gmm_error, errormsg); }
# define GMM_ASSERT3(test, errormsg) \
{ if (!(test)) GMM_THROW_(gmm::gmm_error, errormsg); }
#elif GMM_ASSERT_LEVEL < 3
# define GMM_ASSERT2(test, errormsg){ if (!(test)) GMM_THROW_AT_LEVEL(errormsg, 2); }
# define GMM_ASSERT3(test, errormsg){}
#else
# define GMM_ASSERT2(test, errormsg) \
{ if (!(test)) GMM_THROW_(gmm::gmm_error, errormsg); }
# define GMM_ASSERT3(test, errormsg)
# define GMM_ASSERT2(test, errormsg){ if (!(test)) GMM_THROW_AT_LEVEL(errormsg, 2); }
# define GMM_ASSERT3(test, errormsg){ if (!(test)) GMM_THROW_AT_LEVEL(errormsg, 3); }
#endif
/* *********************************************************************** */
/* GetFEM++ warnings. */
/* GetFEM++ warnings. */
/* *********************************************************************** */
// This allows to dynamically hide warnings
struct warning_level {
static int level(int l = -2)
{ static int level_ = 3; return (l != -2) ? (level_ = l) : level_; }
};
inline void set_warning_level(int l) { warning_level::level(std::max(0,l)); }
inline int get_warning_level(void) { return warning_level::level(-2); }
// This allows not to compile some Warnings
#ifndef GMM_WARNING_LEVEL
# define GMM_WARNING_LEVEL 4
@@ -156,55 +189,48 @@ namespace gmm {
// 3 remark
// 4 ignored by default.
#define GMM_WARNING_MSG(level_, thestr) { \
std::stringstream msg__; \
msg__ << "Level " << level_ << " Warning in " << __FILE__ << ", line " \
<< __LINE__ << ": " << thestr; \
std::cerr << msg__.str() << std::endl; \
}
#define GMM_WARNING_MSG(level_, thestr) { \
std::stringstream msg__; \
msg__ << "Level " << level_ << " Warning in " << __FILE__ << ", line " \
<< __LINE__ << ": " << thestr; \
gmm::feedback_manager::manage()->send(msg__.str(), gmm::FeedbackType::WARNING, level_); \
}
#define GMM_WARNING0(thestr) GMM_WARNING_MSG(0, thestr)
#if GMM_WARNING_LEVEL > 0
# define GMM_WARNING1(thestr) \
{ if (1 <= gmm::warning_level::level()) GMM_WARNING_MSG(1, thestr) }
{ if (1 <= gmm::feedback_manager::warning_level()) GMM_WARNING_MSG(1, thestr) }
#else
# define GMM_WARNING1(thestr) {}
#endif
#if GMM_WARNING_LEVEL > 1
# define GMM_WARNING2(thestr) \
{ if (2 <= gmm::warning_level::level()) GMM_WARNING_MSG(2, thestr) }
{ if (2 <= gmm::feedback_manager::warning_level()) GMM_WARNING_MSG(2, thestr) }
#else
# define GMM_WARNING2(thestr) {}
#endif
#if GMM_WARNING_LEVEL > 2
# define GMM_WARNING3(thestr) \
{ if (3 <= gmm::warning_level::level()) GMM_WARNING_MSG(3, thestr) }
{ if (3 <= gmm::feedback_manager::warning_level()) GMM_WARNING_MSG(3, thestr) }
#else
# define GMM_WARNING3(thestr) {}
#endif
#if GMM_WARNING_LEVEL > 3
# define GMM_WARNING4(thestr) \
{ if (4 <= gmm::warning_level::level()) GMM_WARNING_MSG(4, thestr) }
{ if (4 <= gmm::feedback_manager::warning_level()) GMM_WARNING_MSG(4, thestr) }
#else
# define GMM_WARNING4(thestr) {}
#endif
/* *********************************************************************** */
/* GetFEM++ traces. */
/* GetFEM++ traces. */
/* *********************************************************************** */
// This allows to dynamically hide traces
struct traces_level {
static int level(int l = -2)
{ static int level_ = 3; return (l != -2) ? (level_ = l) : level_; }
};
inline void set_traces_level(int l) { traces_level::level(std::max(0,l)); }
// This allow not too compile some Warnings
#ifndef GMM_TRACES_LEVEL
# define GMM_TRACES_LEVEL 4
@@ -217,112 +243,164 @@ namespace gmm {
// 4 Susceptible to occur very often (>1000).
#define GMM_TRACE_MSG_MPI // for Parallelized version
#define GMM_TRACE_MSG(level_, thestr) { \
GMM_TRACE_MSG_MPI { \
std::stringstream msg__; \
msg__ << "Trace " << level_ << " in " << __FILE__ << ", line " \
<< __LINE__ << ": " << thestr; \
std::cout << msg__.str() << std::endl; \
} \
}
#define GMM_TRACE_MSG(level_, thestr) { \
GMM_TRACE_MSG_MPI { \
std::stringstream msg__; \
msg__ << "Trace " << level_ << " in " << __FILE__ << ", line " \
<< __LINE__ << ": " << thestr; \
gmm::feedback_manager::send(msg__.str(), gmm::FeedbackType::TRACE, level_); \
} \
}
#define GMM_TRACE_SIMPLE_MSG(level_, thestr) { \
GMM_TRACE_MSG_MPI { \
std::stringstream msg__; \
msg__ << "Trace " << level_ << ": " << thestr; \
gmm::feedback_manager::send(msg__.str(), gmm::FeedbackType::TRACE, level_); \
} \
}
#define GMM_TRACE0(thestr) GMM_TRACE_MSG(0, thestr)
#define GMM_SIMPLE_TRACE0(thestr) GMM_TRACE_MSG_SIMPLE(0, thestr)
#if GMM_TRACES_LEVEL > 0
# define GMM_TRACE1(thestr) \
{ if (1 <= gmm::traces_level::level()) GMM_TRACE_MSG(1, thestr) }
# define GMM_TRACE1(thestr) \
{ if (1 <= gmm::feedback_manager::traces_level()) GMM_TRACE_MSG(1, thestr) }
# define GMM_SIMPLE_TRACE1(thestr) \
{ if (1 <= gmm::feedback_manager::traces_level()) GMM_TRACE_SIMPLE_MSG(1, thestr) }
#else
# define GMM_TRACE1(thestr) {}
# define GMM_SIMPLE_TRACE1(thestr) {}
#endif
#if GMM_TRACES_LEVEL > 1
# define GMM_TRACE2(thestr) \
{ if (2 <= gmm::traces_level::level()) GMM_TRACE_MSG(2, thestr) }
# define GMM_TRACE2(thestr) \
{ if (2 <= gmm::feedback_manager::traces_level()) GMM_TRACE_MSG(2, thestr) }
# define GMM_SIMPLE_TRACE2(thestr) \
{ if (2 <= gmm::feedback_manager::traces_level()) GMM_TRACE_SIMPLE_MSG(2, thestr) }
#else
# define GMM_TRACE2(thestr) {}
# define GMM_SIMPLE_TRACE2(thestr) {}
#endif
#if GMM_TRACES_LEVEL > 2
# define GMM_TRACE3(thestr) \
{ if (3 <= gmm::traces_level::level()) GMM_TRACE_MSG(3, thestr) }
# define GMM_TRACE3(thestr) \
{ if (3 <= gmm::feedback_manager::traces_level()) GMM_TRACE_MSG(3, thestr) }
# define GMM_SIMPLE_TRACE3(thestr) \
{ if (3 <= gmm::feedback_manager::traces_level()) GMM_TRACE_SIMPLE_MSG(3, thestr) }
#else
# define GMM_TRACE3(thestr) {}
# define GMM_SIMPLE_TRACE3(thestr) {}
#endif
#if GMM_TRACES_LEVEL > 3
# define GMM_TRACE4(thestr) \
{ if (4 <= gmm::traces_level::level()) GMM_TRACE_MSG(4, thestr) }
# define GMM_TRACE4(thestr) \
{ if (4 <= gmm::feedback_manager::traces_level()) GMM_TRACE_MSG(4, thestr) }
# define GMM_SIMPLE_TRACE4(thestr) \
{ if (4 <= gmm::feedback_manager::traces_level()) GMM_TRACE_SIMPLE_MSG(4, thestr) }
#else
# define GMM_TRACE4(thestr) {}
# define GMM_SIMPLE_TRACE4(thestr) {}
#endif
/* ********************************************************************* */
/* Definitions for compatibility with old versions. */
/* ********************************************************************* */
#define GMM_STANDARD_CATCH_ERROR catch(std::logic_error e) \
{ \
std::cerr << "============================================\n"; \
std::cerr << "| An error has been detected !!! |\n"; \
std::cerr << "============================================\n"; \
std::cerr << e.what() << std::endl << std::endl; \
exit(1); \
} \
catch(const std::runtime_error &e) \
{ \
std::cerr << "============================================\n"; \
std::cerr << "| An error has been detected !!! |\n"; \
std::cerr << "============================================\n"; \
std::cerr << e.what() << std::endl << std::endl; \
exit(1); \
} \
catch(const std::bad_alloc &) { \
std::cerr << "============================================\n"; \
std::cerr << "| A bad allocation has been detected !!! |\n"; \
std::cerr << "============================================\n"; \
exit(1); \
} \
catch(const std::bad_typeid &) { \
std::cerr << "============================================\n"; \
std::cerr << "| A bad typeid has been detected !!! |\n"; \
std::cerr << "============================================\n"; \
exit(1); \
} \
catch(const std::bad_exception &) { \
std::cerr << "============================================\n"; \
std::cerr << "| A bad exception has been detected !!! |\n"; \
std::cerr << "============================================\n"; \
exit(1); \
} \
catch(const std::bad_cast &) { \
std::cerr << "============================================\n"; \
std::cerr << "| A bad cast has been detected !!! |\n"; \
std::cerr << "============================================\n"; \
exit(1); \
} \
catch(...) { \
std::cerr << "============================================\n"; \
std::cerr << "| An unknown error has been detected !!! |\n"; \
std::cerr << "============================================\n"; \
exit(1); \
#define GMM_STANDARD_CATCH_ERROR \
catch(gmm::gmm_error e) \
{ \
std::stringstream strStream; \
strStream << "============================================\n"; \
strStream << "| A GMM error has been detected !!! |\n"; \
strStream << "============================================\n"; \
strStream << e.what() << std::endl << std::endl; \
gmm::feedback_manager::send(strStream.str(), \
gmm::FeedbackType::ASSERT, e.errLevel()); \
gmm::feedback_manager::terminating_action(); \
} \
catch(std::logic_error e) \
{ \
std::stringstream strStream; \
strStream << "============================================\n"; \
strStream << "| An error has been detected !!! |\n"; \
strStream << "============================================\n"; \
strStream << e.what() << std::endl << std::endl; \
gmm::feedback_manager::send(strStream.str(), \
gmm::FeedbackType::ASSERT, 0); \
gmm::feedback_manager::terminating_action(); \
} \
catch(std::runtime_error e) \
{ \
std::stringstream strStream; \
strStream << "============================================\n"; \
strStream << "| A runtime error has been detected !!! |\n"; \
strStream << "============================================\n"; \
strStream << e.what() << std::endl << std::endl; \
gmm::feedback_manager::send(strStream.str(), \
gmm::FeedbackType::ASSERT, 0); \
gmm::feedback_manager::terminating_action(); \
} \
catch(std::bad_alloc) \
{ \
std::stringstream strStream; \
strStream << "============================================\n"; \
strStream << "| A bad allocation has been detected !!! |\n"; \
strStream << "============================================\n"; \
gmm::feedback_manager::send(strStream.str(), \
gmm::FeedbackType::ASSERT, 0); \
gmm::feedback_manager::terminating_action(); \
} \
catch(std::bad_typeid) \
{ \
std::stringstream strStream; \
strStream << "============================================\n"; \
strStream << "| A bad typeid has been detected !!! |\n"; \
strStream << "============================================\n"; \
gmm::feedback_manager::send(strStream.str(), \
gmm::FeedbackType::ASSERT, 0); \
gmm::feedback_manager::terminating_action(); \
} \
catch(std::bad_exception) \
{ \
std::stringstream strStream; \
strStream << "============================================\n"; \
strStream << "| A bad exception has been detected !!! |\n"; \
strStream << "============================================\n"; \
gmm::feedback_manager::send(strStream.str(), \
gmm::FeedbackType::ASSERT, 0); \
gmm::feedback_manager::terminating_action(); \
} \
catch(std::bad_cast) \
{ \
std::stringstream strStream; \
strStream << "============================================\n"; \
strStream << "| A bad_cast has been detected !!! |\n"; \
strStream << "============================================\n"; \
gmm::feedback_manager::send(strStream.str(), \
gmm::FeedbackType::ASSERT, 0); \
gmm::feedback_manager::terminating_action(); \
} \
catch(...) \
{ \
std::stringstream strStream; \
strStream << "============================================\n"; \
strStream << "| An unknown error has been detected !!! |\n"; \
strStream << "============================================\n"; \
gmm::feedback_manager::send(strStream.str(), \
gmm::FeedbackType::ASSERT, 0); \
gmm::feedback_manager::terminating_action(); \
}
// catch(ios_base::failure) {
// catch(ios_base::failure) {
// std::cerr << "============================================\n";
// std::cerr << "| A ios_base::failure has been detected !!!|\n";
// std::cerr << "============================================\n";
// exit(1);
// }
// }
#if defined(__GNUC__) && (__GNUC__ > 3)
# define GMM_SET_EXCEPTION_DEBUG \
# define GMM_SET_EXCEPTION_DEBUG \
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
#else
# define GMM_SET_EXCEPTION_DEBUG
#endif
}
#else
#include <external_except.h>
#endif /* EXTERNAL_EXCEPT_*/
} // namespace gmm
#endif /* GMM_EXCEPT_H__ */

View File

@@ -0,0 +1,174 @@
/* -*- c++ -*- (enables emacs c++ mode) */
/*===========================================================================
Copyright (C) 2002-2017 Yves Renard
This file is a part of GetFEM++
GetFEM++ is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version along with the GCC Runtime Library
Exception either version 3.1 or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License and GCC Runtime Library Exception for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
As a special exception, you may use this file as it is a part of a free
software library without restriction. Specifically, if other files
instantiate templates or use macros or inline functions from this file,
or you compile this file and link it with other files to produce an
executable, this file does not by itself cause the resulting executable
to be covered by the GNU Lesser General Public License. This exception
does not however invalidate any other reasons why the executable file
might be covered by the GNU Lesser General Public License.
===========================================================================*/
/** @file gmm_feedback_management.h
@date July 03, 2017.
@brief Support for run time management of trace, warning and assert
feedback.
*/
#ifndef GMM_FEEDBACK_MANAGEMENT_H__
#define GMM_FEEDBACK_MANAGEMENT_H__
#include <iostream>
#include <string>
#include <memory>
namespace gmm {
/* *********************************************************************** */
/* GetFEM++ warnings. */
/* *********************************************************************** */
// This allows to dynamically hide warnings
struct warning_level {
static int level(int l = -2)
{ static int level_ = 3; return (l != -2) ? (level_ = l) : level_; }
};
inline void set_warning_level(int l) { warning_level::level(l>0 ? l : 0); }
inline int get_warning_level(void) { return warning_level::level(-2); }
/* *********************************************************************** */
/* GetFEM++ traces. */
/* *********************************************************************** */
// This allows to dynamically hide traces
struct traces_level {
static int level(int l = -2)
{ static int level_ = 3; return (l != -2) ? (level_ = l) : level_; }
};
inline void set_traces_level(int l) { traces_level::level(l>0 ? l : 0); }
inline int get_traces_level(void) { return traces_level::level(); }
/* *********************************************************************** */
/* GetFEM++ feedback management */
/* *********************************************************************** */
enum class FeedbackType {
TRACE = 0,
WARNING,
ASSERT
};
// Abstract class providing feedback management interface.
// The interface consist of three functions:
// * for sending feedback message
// * for getting traces level
// * for getting warning level
// * for action to be done after feedback is handled
struct base_feedback_handler {
virtual ~base_feedback_handler() = default;
virtual void send(const std::string &message, FeedbackType messageType, size_t level) = 0;
virtual size_t traces_level() { return get_traces_level(); }
virtual size_t warning_level() { return get_warning_level(); }
virtual void terminating_action() = 0;
};
// Provides the default implementation of feedback handling.
struct default_feedback_handler final : public base_feedback_handler {
void send(const std::string &message, FeedbackType, size_t) override {
std::cerr << message << std::endl;
}
void terminating_action() override {
std::exit(1);
}
};
// This class acts as a run-time dispatcher for sending feedback
// messages and getting trace and warning levels.
class feedback_manager {
public:
// Management actions
enum Action {
SET, // Sets the feedback handler, releasing the one previously set.
GET, // Returns currently managed handler (it is still managed).
REPLACE, // Replace manager with a new one, stop managing the old one
// and returns it unmanaged to the caller. The caller is
// then responsible for managing the memory of the handler.
};
// Steals the pointer to a messenger object that provides
// feedback handling implementation.
//
// Example:
// feedback_manager::manage(new default_feedback_handler);
//
static base_feedback_handler* manage(enum Action action=GET, base_feedback_handler *pHandler=nullptr);
static void send(const std::string &message, FeedbackType type, size_t level);
static size_t traces_level();
static size_t warning_level();
// Action to be taken when feedback handling is done
static void terminating_action();
};
// Depending on action either gets, sets or replaces feedback handler. Setting handler to null resets
// it to gmm::default_feedback_handler.
inline base_feedback_handler* feedback_manager::manage(enum Action action, base_feedback_handler *pHandler) {
static std::unique_ptr<base_feedback_handler> pHandler_ =
std::move(std::unique_ptr<base_feedback_handler>(new default_feedback_handler));
base_feedback_handler *rethandler = nullptr;
switch(action) {
case SET:
pHandler_.reset(pHandler != nullptr ? pHandler : new default_feedback_handler);
rethandler = pHandler_.get();
break;
case GET:
rethandler = pHandler_.get();
break;
case REPLACE:
rethandler = pHandler_.release();
pHandler_.reset(pHandler != nullptr ? pHandler : new default_feedback_handler);
break;
}
return rethandler;
}
inline void feedback_manager::send(const std::string &message, FeedbackType type, size_t level) {
feedback_manager::manage()->send(message, type, level);
}
inline void feedback_manager::terminating_action() {
feedback_manager::manage()->terminating_action();
}
inline size_t feedback_manager::traces_level() {
return feedback_manager::manage()->traces_level();
}
inline size_t feedback_manager::warning_level() {
return feedback_manager::manage()->warning_level();
}
} // namespace gmm
#endif /* GMM_FEEDBACK_MANAGEMENT_H__ */

View File

@@ -47,42 +47,42 @@
namespace gmm {
/* ********************************************************************* */
/* Operations interfaced for T = float, double, std::complex<float> */
/* or std::complex<double> : */
/* */
/* lu_factor(dense_matrix<T>, std::vector<int>) */
/* lu_solve(dense_matrix<T>, std::vector<T>, std::vector<T>) */
/* lu_solve(dense_matrix<T>, std::vector<int>, std::vector<T>, */
/* std::vector<T>) */
/* lu_solve_transposed(dense_matrix<T>, std::vector<int>, std::vector<T>,*/
/* std::vector<T>) */
/* lu_inverse(dense_matrix<T>) */
/* lu_inverse(dense_matrix<T>, std::vector<int>, dense_matrix<T>) */
/* */
/* qr_factor(dense_matrix<T>, dense_matrix<T>, dense_matrix<T>) */
/* */
/* implicit_qr_algorithm(dense_matrix<T>, std::vector<T>) */
/* implicit_qr_algorithm(dense_matrix<T>, std::vector<T>, */
/* dense_matrix<T>) */
/* implicit_qr_algorithm(dense_matrix<T>, std::vector<std::complex<T> >) */
/* implicit_qr_algorithm(dense_matrix<T>, std::vector<std::complex<T> >, */
/* dense_matrix<T>) */
/* */
/* geev_interface_right */
/* geev_interface_left */
/* */
/* schur(dense_matrix<T>, dense_matrix<T>, dense_matrix<T>) */
/* */
/* svd(dense_matrix<T>, dense_matrix<T>, dense_matrix<T>, std::vector<T>)*/
/* svd(dense_matrix<T>, dense_matrix<T>, dense_matrix<T>, */
/* std::vector<std::complex<T> >) */
/* */
/* ********************************************************************* */
/* ********************************************************************** */
/* Operations interfaced for T = float, double, std::complex<float> */
/* or std::complex<double> : */
/* */
/* lu_factor(dense_matrix<T>, std::vector<long>) */
/* lu_solve(dense_matrix<T>, std::vector<T>, std::vector<T>) */
/* lu_solve(dense_matrix<T>, std::vector<long>, std::vector<T>, */
/* std::vector<T>) */
/* lu_solve_transposed(dense_matrix<T>, std::vector<long>, std::vector<T>,*/
/* std::vector<T>) */
/* lu_inverse(dense_matrix<T>) */
/* lu_inverse(dense_matrix<T>, std::vector<long>, dense_matrix<T>) */
/* */
/* qr_factor(dense_matrix<T>, dense_matrix<T>, dense_matrix<T>) */
/* */
/* implicit_qr_algorithm(dense_matrix<T>, std::vector<T>) */
/* implicit_qr_algorithm(dense_matrix<T>, std::vector<T>, */
/* dense_matrix<T>) */
/* implicit_qr_algorithm(dense_matrix<T>, std::vector<std::complex<T> >) */
/* implicit_qr_algorithm(dense_matrix<T>, std::vector<std::complex<T> >, */
/* dense_matrix<T>) */
/* */
/* geev_interface_right */
/* geev_interface_left */
/* */
/* schur(dense_matrix<T>, dense_matrix<T>, dense_matrix<T>) */
/* */
/* svd(dense_matrix<T>, dense_matrix<T>, dense_matrix<T>, std::vector<T>) */
/* svd(dense_matrix<T>, dense_matrix<T>, dense_matrix<T>, */
/* std::vector<std::complex<T> >) */
/* */
/* ********************************************************************** */
/* ********************************************************************* */
/* LAPACK functions used. */
/* ********************************************************************* */
/* ********************************************************************** */
/* LAPACK functions used. */
/* ********************************************************************** */
extern "C" {
void sgetrf_(...); void dgetrf_(...); void cgetrf_(...); void zgetrf_(...);
@@ -96,17 +96,20 @@ namespace gmm {
void sgeesx_(...); void dgeesx_(...); void cgeesx_(...); void zgeesx_(...);
void sgesvd_(...); void dgesvd_(...); void cgesvd_(...); void zgesvd_(...);
}
/* ********************************************************************* */
/* LU decomposition. */
/* ********************************************************************* */
# define getrf_interface(lapack_name, base_type) inline \
size_type lu_factor(dense_matrix<base_type > &A, std::vector<int> &ipvt){\
GMMLAPACK_TRACE("getrf_interface"); \
int m = int(mat_nrows(A)), n = int(mat_ncols(A)), lda(m), info(0); \
if (m && n) lapack_name(&m, &n, &A(0,0), &lda, &ipvt[0], &info); \
return size_type(info); \
/* ********************************************************************** */
/* LU decomposition. */
/* ********************************************************************** */
# define getrf_interface(lapack_name, base_type) inline \
size_type lu_factor(dense_matrix<base_type > &A, lapack_ipvt &ipvt){ \
GMMLAPACK_TRACE("getrf_interface"); \
long m = long(mat_nrows(A)), n = long(mat_ncols(A)), lda(m), info(-1L); \
if (m && n) lapack_name(&m, &n, &A(0,0), &lda, ipvt.pfirst(), &info); \
if ((info & 0xFFFFFFFF00000000L) && !(info & 0x00000000FFFFFFFFL)) \
/* For compatibility with lapack version with 32 bit integer. */ \
ipvt.set_to_int32(); \
return size_type(int(info & 0x00000000FFFFFFFFL)); \
}
getrf_interface(sgetrf_, BLAS_S)
@@ -120,13 +123,13 @@ namespace gmm {
# define getrs_interface(f_name, trans1, lapack_name, base_type) inline \
void f_name(const dense_matrix<base_type > &A, \
const std::vector<int> &ipvt, std::vector<base_type > &x, \
const lapack_ipvt &ipvt, std::vector<base_type > &x, \
const std::vector<base_type > &b) { \
GMMLAPACK_TRACE("getrs_interface"); \
int n = int(mat_nrows(A)), info, nrhs(1); \
long n = long(mat_nrows(A)), info(0), nrhs(1); \
gmm::copy(b, x); trans1; \
if (n) \
lapack_name(&t, &n, &nrhs, &(A(0,0)),&n,&ipvt[0], &x[0], &n, &info); \
lapack_name(&t,&n,&nrhs,&(A(0,0)),&n,ipvt.pfirst(),&x[0],&n,&info); \
}
# define getrs_trans_n const char t = 'N'
@@ -147,14 +150,17 @@ namespace gmm {
# define getri_interface(lapack_name, base_type) inline \
void lu_inverse(const dense_matrix<base_type > &LU, \
std::vector<int> &ipvt, const dense_matrix<base_type > &A_) { \
const lapack_ipvt &ipvt, const dense_matrix<base_type > &A_) { \
GMMLAPACK_TRACE("getri_interface"); \
dense_matrix<base_type> &A \
= const_cast<dense_matrix<base_type > &>(A_); \
int n = int(mat_nrows(A)), info, lwork(10000); base_type work[10000]; \
dense_matrix<base_type >& \
A = const_cast<dense_matrix<base_type > &>(A_); \
long n = int(mat_nrows(A)), info(0), lwork(-1); base_type work1; \
if (n) { \
std::copy(LU.begin(), LU.end(), A.begin()); \
lapack_name(&n, &A(0,0), &n, &ipvt[0], &work[0], &lwork, &info); \
gmm::copy(LU, A); \
lapack_name(&n, &A(0,0), &n, ipvt.pfirst(), &work1, &lwork, &info); \
lwork = int(gmm::real(work1)); \
std::vector<base_type > work(lwork); \
lapack_name(&n, &A(0,0), &n, ipvt.pfirst(), &work[0], &lwork,&info); \
} \
}
@@ -163,20 +169,19 @@ namespace gmm {
getri_interface(cgetri_, BLAS_C)
getri_interface(zgetri_, BLAS_Z)
/* ********************************************************************* */
/* QR factorization. */
/* ********************************************************************* */
/* ********************************************************************** */
/* QR factorization. */
/* ********************************************************************** */
# define geqrf_interface(lapack_name1, base_type) inline \
void qr_factor(dense_matrix<base_type > &A){ \
GMMLAPACK_TRACE("geqrf_interface"); \
int m = int(mat_nrows(A)), n = int(mat_ncols(A)), info, lwork(-1); \
long m = long(mat_nrows(A)), n=long(mat_ncols(A)), info(0), lwork(-1); \
base_type work1; \
if (m && n) { \
std::vector<base_type > tau(n); \
lapack_name1(&m, &n, &A(0,0), &m, &tau[0], &work1 , &lwork, &info); \
lwork = int(gmm::real(work1)); \
lwork = long(gmm::real(work1)); \
std::vector<base_type > work(lwork); \
lapack_name1(&m, &n, &A(0,0), &m, &tau[0], &work[0], &lwork, &info); \
GMM_ASSERT1(!info, "QR factorization failed"); \
@@ -194,19 +199,19 @@ namespace gmm {
void qr_factor(const dense_matrix<base_type > &A, \
dense_matrix<base_type > &Q, dense_matrix<base_type > &R) { \
GMMLAPACK_TRACE("geqrf_interface2"); \
int m = int(mat_nrows(A)), n = int(mat_ncols(A)), info, lwork(-1); \
long m = long(mat_nrows(A)), n=long(mat_ncols(A)), info(0), lwork(-1); \
base_type work1; \
if (m && n) { \
std::copy(A.begin(), A.end(), Q.begin()); \
std::vector<base_type > tau(n); \
lapack_name1(&m, &n, &Q(0,0), &m, &tau[0], &work1 , &lwork, &info); \
lwork = int(gmm::real(work1)); \
lwork = long(gmm::real(work1)); \
std::vector<base_type > work(lwork); \
lapack_name1(&m, &n, &Q(0,0), &m, &tau[0], &work[0], &lwork, &info); \
GMM_ASSERT1(!info, "QR factorization failed"); \
base_type *p = &R(0,0), *q = &Q(0,0); \
for (int j = 0; j < n; ++j, q += m-n) \
for (int i = 0; i < n; ++i, ++p, ++q) \
for (long j = 0; j < n; ++j, q += m-n) \
for (long i = 0; i < n; ++i, ++p, ++q) \
*p = (j < i) ? base_type(0) : *q; \
lapack_name2(&m, &n, &n, &Q(0,0), &m,&tau[0],&work[0],&lwork,&info); \
} \
@@ -218,9 +223,9 @@ namespace gmm {
geqrf_interface2(cgeqrf_, cungqr_, BLAS_C)
geqrf_interface2(zgeqrf_, zungqr_, BLAS_Z)
/* ********************************************************************* */
/* QR algorithm for eigenvalues search. */
/* ********************************************************************* */
/* ********************************************************************** */
/* QR algorithm for eigenvalues search. */
/* ********************************************************************** */
# define gees_interface(lapack_name, base_type) \
template <typename VECT> inline void implicit_qr_algorithm( \
@@ -229,14 +234,14 @@ namespace gmm {
double tol=gmm::default_tol(base_type()), bool compvect = true) { \
GMMLAPACK_TRACE("gees_interface"); \
typedef bool (*L_fp)(...); L_fp p = 0; \
int n = int(mat_nrows(A)), info, lwork(-1), sdim; base_type work1; \
long n=long(mat_nrows(A)), info(0), lwork(-1), sdim; base_type work1; \
if (!n) return; \
dense_matrix<base_type > H(n,n); gmm::copy(A, H); \
char jobvs = (compvect ? 'V' : 'N'), sort = 'N'; \
std::vector<double> rwork(n), eigv1(n), eigv2(n); \
lapack_name(&jobvs, &sort, p, &n, &H(0,0), &n, &sdim, &eigv1[0], \
&eigv2[0], &Q(0,0), &n, &work1, &lwork, &rwork[0], &info); \
lwork = int(gmm::real(work1)); \
lwork = long(gmm::real(work1)); \
std::vector<base_type > work(lwork); \
lapack_name(&jobvs, &sort, p, &n, &H(0,0), &n, &sdim, &eigv1[0], \
&eigv2[0], &Q(0,0), &n, &work[0], &lwork, &rwork[0],&info);\
@@ -251,14 +256,14 @@ namespace gmm {
double tol=gmm::default_tol(base_type()), bool compvect = true) { \
GMMLAPACK_TRACE("gees_interface2"); \
typedef bool (*L_fp)(...); L_fp p = 0; \
int n = int(mat_nrows(A)), info, lwork(-1), sdim; base_type work1; \
long n=long(mat_nrows(A)), info(0), lwork(-1), sdim; base_type work1; \
if (!n) return; \
dense_matrix<base_type > H(n,n); gmm::copy(A, H); \
char jobvs = (compvect ? 'V' : 'N'), sort = 'N'; \
std::vector<double> rwork(n), eigvv(n*2); \
lapack_name(&jobvs, &sort, p, &n, &H(0,0), &n, &sdim, &eigvv[0], \
&Q(0,0), &n, &work1, &lwork, &rwork[0], &rwork[0], &info); \
lwork = int(gmm::real(work1)); \
lwork = long(gmm::real(work1)); \
std::vector<base_type > work(lwork); \
lapack_name(&jobvs, &sort, p, &n, &H(0,0), &n, &sdim, &eigvv[0], \
&Q(0,0), &n, &work[0], &lwork, &rwork[0], &rwork[0],&info);\
@@ -276,18 +281,18 @@ namespace gmm {
# define jobv_left char jobvl = 'V', jobvr = 'N';
# define geev_interface(lapack_name, base_type, side) \
template <typename VECT> inline void geev_interface_ ## side( \
template <typename VECT> inline void geev_interface_ ## side( \
const dense_matrix<base_type > &A, const VECT &eigval_, \
dense_matrix<base_type > &Q) { \
GMMLAPACK_TRACE("geev_interface"); \
int n = int(mat_nrows(A)), info, lwork(-1); base_type work1; \
long n = long(mat_nrows(A)), info(0), lwork(-1); base_type work1; \
if (!n) return; \
dense_matrix<base_type > H(n,n); gmm::copy(A, H); \
jobv_ ## side \
std::vector<base_type > eigvr(n), eigvi(n); \
lapack_name(&jobvl, &jobvr, &n, &H(0,0), &n, &eigvr[0], &eigvi[0], \
&Q(0,0), &n, &Q(0,0), &n, &work1, &lwork, &info); \
lwork = int(gmm::real(work1)); \
lwork = long(gmm::real(work1)); \
std::vector<base_type > work(lwork); \
lapack_name(&jobvl, &jobvr, &n, &H(0,0), &n, &eigvr[0], &eigvi[0], \
&Q(0,0), &n, &Q(0,0), &n, &work[0], &lwork, &info); \
@@ -301,7 +306,7 @@ namespace gmm {
const dense_matrix<base_type > &A, const VECT &eigval_, \
dense_matrix<base_type > &Q) { \
GMMLAPACK_TRACE("geev_interface"); \
int n = int(mat_nrows(A)), info, lwork(-1); base_type work1; \
long n = long(mat_nrows(A)), info(0), lwork(-1); base_type work1; \
if (!n) return; \
dense_matrix<base_type > H(n,n); gmm::copy(A, H); \
jobv_ ## side \
@@ -309,7 +314,7 @@ namespace gmm {
std::vector<base_type> eigv(n); \
lapack_name(&jobvl, &jobvr, &n, &H(0,0), &n, &eigv[0], &Q(0,0), &n, \
&Q(0,0), &n, &work1, &lwork, &rwork[0], &info); \
lwork = int(gmm::real(work1)); \
lwork = long(gmm::real(work1)); \
std::vector<base_type > work(lwork); \
lapack_name(&jobvl, &jobvr, &n, &H(0,0), &n, &eigv[0], &Q(0,0), &n, \
&Q(0,0), &n, &work[0], &lwork, &rwork[0], &info); \
@@ -328,32 +333,32 @@ namespace gmm {
geev_interface2(zgeev_, BLAS_Z, left)
/* ********************************************************************* */
/* SCHUR algorithm: */
/* A = Q*S*(Q^T), with Q orthogonal and S upper quasi-triangula */
/* ********************************************************************* */
/* ********************************************************************** */
/* SCHUR algorithm: */
/* A = Q*S*(Q^T), with Q orthogonal and S upper quasi-triangula */
/* ********************************************************************** */
# define geesx_interface(lapack_name, base_type) inline \
void schur(dense_matrix<base_type> &A, \
dense_matrix<base_type> &S, \
dense_matrix<base_type> &Q) { \
GMMLAPACK_TRACE("geesx_interface"); \
int m = int(mat_nrows(A)), n = int(mat_ncols(A)); \
long m = long(mat_nrows(A)), n = long(mat_ncols(A)); \
GMM_ASSERT1(m == n, "Schur decomposition requires square matrix"); \
char jobvs = 'V', sort = 'N', sense = 'N'; \
bool select = false; \
int lwork = 8*n, sdim = 0, liwork = 1; \
long lwork = 8*n, sdim = 0, liwork = 1; \
std::vector<base_type> work(lwork), wr(n), wi(n); \
std::vector<int> iwork(liwork); \
std::vector<int> bwork(1); \
std::vector<long> iwork(liwork); \
std::vector<long> bwork(1); \
resize(S, n, n); copy(A, S); \
resize(Q, n, n); \
base_type rconde(0), rcondv(0); \
int info = -1; \
long info(0); \
lapack_name(&jobvs, &sort, &select, &sense, &n, &S(0,0), &n, \
&sdim, &wr[0], &wi[0], &Q(0,0), &n, &rconde, &rcondv, \
&work[0], &lwork, &iwork[0], &liwork, &bwork[0], &info);\
GMM_ASSERT1(!info, "SCHUR algorithm failed"); \
GMM_ASSERT1(!info, "SCHUR algorithm failed"); \
}
# define geesx_interface2(lapack_name, base_type) inline \
@@ -361,18 +366,18 @@ namespace gmm {
dense_matrix<base_type> &S, \
dense_matrix<base_type> &Q) { \
GMMLAPACK_TRACE("geesx_interface"); \
int m = int(mat_nrows(A)), n = int(mat_ncols(A)); \
long m = long(mat_nrows(A)), n = long(mat_ncols(A)); \
GMM_ASSERT1(m == n, "Schur decomposition requires square matrix"); \
char jobvs = 'V', sort = 'N', sense = 'N'; \
bool select = false; \
int lwork = 8*n, sdim = 0; \
long lwork = 8*n, sdim = 0; \
std::vector<base_type::value_type> rwork(lwork); \
std::vector<base_type> work(lwork), w(n); \
std::vector<int> bwork(1); \
std::vector<long> bwork(1); \
resize(S, n, n); copy(A, S); \
resize(Q, n, n); \
base_type rconde(0), rcondv(0); \
int info = -1; \
long info(0); \
lapack_name(&jobvs, &sort, &select, &sense, &n, &S(0,0), &n, \
&sdim, &w[0], &Q(0,0), &n, &rconde, &rcondv, \
&work[0], &lwork, &rwork[0], &bwork[0], &info); \
@@ -391,10 +396,10 @@ namespace gmm {
}
/* ********************************************************************* */
/* Interface to SVD. Does not correspond to a Gmm++ functionnality. */
/* Author : Sebastian Nowozin <sebastian.nowozin@tuebingen.mpg.de> */
/* ********************************************************************* */
/* ********************************************************************** */
/* Interface to SVD. Does not correspond to a Gmm++ functionnality. */
/* Author : Sebastian Nowozin <sebastian.nowozin@tuebingen.mpg.de> */
/* ********************************************************************** */
# define gesvd_interface(lapack_name, base_type) inline \
void svd(dense_matrix<base_type> &X, \
@@ -402,15 +407,15 @@ namespace gmm {
dense_matrix<base_type> &Vtransposed, \
std::vector<base_type> &sigma) { \
GMMLAPACK_TRACE("gesvd_interface"); \
int m = int(mat_nrows(X)), n = int(mat_ncols(X)); \
int mn_min = m < n ? m : n; \
long m = long(mat_nrows(X)), n = long(mat_ncols(X)); \
long mn_min = m < n ? m : n; \
sigma.resize(mn_min); \
std::vector<base_type> work(15 * mn_min); \
int lwork = int(work.size()); \
long lwork = long(work.size()); \
resize(U, m, m); \
resize(Vtransposed, n, n); \
char job = 'A'; \
int info = -1; \
long info(0); \
lapack_name(&job, &job, &m, &n, &X(0,0), &m, &sigma[0], &U(0,0), \
&m, &Vtransposed(0,0), &n, &work[0], &lwork, &info); \
}
@@ -421,16 +426,16 @@ namespace gmm {
dense_matrix<base_type> &Vtransposed, \
std::vector<base_type2> &sigma) { \
GMMLAPACK_TRACE("gesvd_interface"); \
int m = int(mat_nrows(X)), n = int(mat_ncols(X)); \
int mn_min = m < n ? m : n; \
long m = long(mat_nrows(X)), n = long(mat_ncols(X)); \
long mn_min = m < n ? m : n; \
sigma.resize(mn_min); \
std::vector<base_type> work(15 * mn_min); \
std::vector<base_type2> rwork(5 * mn_min); \
int lwork = int(work.size()); \
long lwork = long(work.size()); \
resize(U, m, m); \
resize(Vtransposed, n, n); \
char job = 'A'; \
int info = -1; \
long info(0); \
lapack_name(&job, &job, &m, &n, &X(0,0), &m, &sigma[0], &U(0,0), \
&m, &Vtransposed(0,0), &n, &work[0], &lwork, \
&rwork[0], &info); \

View File

@@ -37,6 +37,8 @@
#ifndef GMM_OPT_H__
#define GMM_OPT_H__
#include <gmm/gmm_dense_lu.h>
namespace gmm {
/* ********************************************************************* */
@@ -58,7 +60,7 @@ namespace gmm {
default :
{
dense_matrix<T> B(mat_nrows(A), mat_ncols(A));
std::vector<size_type> ipvt(mat_nrows(A));
lapack_ipvt ipvt(mat_nrows(A));
gmm::copy(A, B);
lu_factor(B, ipvt);
return lu_det(B, ipvt);
@@ -69,13 +71,13 @@ namespace gmm {
}
template <typename T> T lu_inverse(const dense_matrix<T> &A_, bool doassert = true) {
template <typename T> T lu_inverse(const dense_matrix<T> &A_,
bool doassert = true) {
dense_matrix<T>& A = const_cast<dense_matrix<T> &>(A_);
size_type N = mat_nrows(A);
T det(1);
if (N) {
T *p = &(A(0,0));
if (N <= 2) {
switch (N) {
case 1 : {
det = *p;
@@ -90,34 +92,35 @@ namespace gmm {
std::swap(*p, *(p+3));
*p++ /= det; *p++ /= -det; *p++ /= -det; *p++ /= det;
} break;
// case 3 : { // not stable for nearly singular matrices
// T a, b, c, d, e, f, g, h, i;
// a = (*(p+4)) * (*(p+8)) - (*(p+5)) * (*(p+7));
// b = - (*(p+1)) * (*(p+8)) + (*(p+2)) * (*(p+7));
// c = (*(p+1)) * (*(p+5)) - (*(p+2)) * (*(p+4));
// d = - (*(p+3)) * (*(p+8)) + (*(p+5)) * (*(p+6));
// e = (*(p+0)) * (*(p+8)) - (*(p+2)) * (*(p+6));
// f = - (*(p+0)) * (*(p+5)) + (*(p+2)) * (*(p+3));
// g = (*(p+3)) * (*(p+7)) - (*(p+4)) * (*(p+6));
// h = - (*(p+0)) * (*(p+7)) + (*(p+1)) * (*(p+6));
// i = (*(p+0)) * (*(p+4)) - (*(p+1)) * (*(p+3));
// det = (*p) * a + (*(p+1)) * d + (*(p+2)) * g;
// GMM_ASSERT1(det!=T(0), "non invertible matrix");
// *p++ = a / det; *p++ = b / det; *p++ = c / det;
// *p++ = d / det; *p++ = e / det; *p++ = f / det;
// *p++ = g / det; *p++ = h / det; *p++ = i / det;
// } break;
case 3 : { // not stable for nearly singular matrices
T a, b, c, d, e, f, g, h, i;
a = (*(p+4)) * (*(p+8)) - (*(p+5)) * (*(p+7));
b = - (*(p+1)) * (*(p+8)) + (*(p+2)) * (*(p+7));
c = (*(p+1)) * (*(p+5)) - (*(p+2)) * (*(p+4));
d = - (*(p+3)) * (*(p+8)) + (*(p+5)) * (*(p+6));
e = (*(p+0)) * (*(p+8)) - (*(p+2)) * (*(p+6));
f = - (*(p+0)) * (*(p+5)) + (*(p+2)) * (*(p+3));
g = (*(p+3)) * (*(p+7)) - (*(p+4)) * (*(p+6));
h = - (*(p+0)) * (*(p+7)) + (*(p+1)) * (*(p+6));
i = (*(p+0)) * (*(p+4)) - (*(p+1)) * (*(p+3));
det = (*p) * a + (*(p+1)) * d + (*(p+2)) * g;
if (std::abs(det) > 1e-5) {
*p++ = a / det; *p++ = b / det; *p++ = c / det;
*p++ = d / det; *p++ = e / det; *p++ = f / det;
*p++ = g / det; *p++ = h / det; *p++ = i / det;
break;
}
}
default : {
dense_matrix<T> B(mat_nrows(A), mat_ncols(A));
lapack_ipvt ipvt(mat_nrows(A));
gmm::copy(A, B);
size_type info = lu_factor(B, ipvt);
GMM_ASSERT1(!info, "non invertible matrix");
lu_inverse(B, ipvt, A);
return lu_det(B, ipvt);
}
}
}
else {
dense_matrix<T> B(mat_nrows(A), mat_ncols(A));
std::vector<int> ipvt(mat_nrows(A));
gmm::copy(A, B);
size_type info = lu_factor(B, ipvt);
GMM_ASSERT1(!info, "non invertible matrix");
lu_inverse(B, ipvt, A);
return lu_det(B, ipvt);
}
}
return det;
}

View File

@@ -38,8 +38,6 @@
#ifndef GMM_STD_H__
#define GMM_STD_H__
//#include <getfem/getfem_arch_config.h>
#ifndef __USE_STD_IOSTREAM
# define __USE_STD_IOSTREAM
#endif
@@ -83,13 +81,6 @@ inline void GMM_NOPERATION_(int) { }
/* Compilers detection. */
/* ********************************************************************** */
/* for sun CC 5.0 ...
#if defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x500
# include <stdcomp.h>
# undef _RWSTD_NO_CLASS_PARTIAL_SPEC
# undef _RWSTD_NO_NAMESPACE
#endif
*/
/* for VISUAL C++ ...
#if defined(_MSC_VER) // && !defined(__MWERKS__)
#define _GETFEM_MSVCPP_ _MSC_VER
@@ -133,6 +124,8 @@ inline void GMM_NOPERATION_(int) { }
#include <array>
#include <locale.h>
#include <gmm/gmm_arch_config.h>
namespace std {
#if defined(__GNUC__) && (__cplusplus <= 201103L)
template<typename _Tp>
@@ -181,7 +174,7 @@ namespace std {
#ifdef GETFEM_HAVE_OPENMP
#ifdef GMM_HAVE_OPENMP
#include <omp.h>
/**number of OpenMP threads*/
@@ -222,7 +215,7 @@ namespace gmm {
}
};
#else
/**this is the above solutions for linux, but I still needs to be tested.*/
/**this is the above solutions for linux, but it still needs to be tested.*/
//class standard_locale {
// locale_t oldloc;
// locale_t temploc;