mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-12-08 13:04:56 +00:00
Windows fixes
This commit is contained in:
7
gmm/gmm_arch_config.h
Normal file
7
gmm/gmm_arch_config.h
Normal 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
|
||||
@@ -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 */
|
||||
/* ******************************************************************** */
|
||||
|
||||
@@ -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); \
|
||||
}
|
||||
|
||||
|
||||
@@ -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 !");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
356
gmm/gmm_except.h
356
gmm/gmm_except.h
@@ -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__ */
|
||||
|
||||
174
gmm/gmm_feedback_management.h
Normal file
174
gmm/gmm_feedback_management.h
Normal 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__ */
|
||||
@@ -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); \
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user