From 7b03ad3e96658e29ecd214587280f7f4270c58c1 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Mon, 22 Dec 2008 22:34:07 +0000 Subject: [PATCH] More "numeric" work: removed all traces of Numerical Recipes, as the NR license is incompatible with our use. Replaced with Lapack for LU/SVD. Still need to recode newt & brent. --- Geo/GFace.cpp | 81 +-- Geo/Geo.cpp | 9 +- Numeric/GmshMatrix.h | 233 ++++---- ...gmsh_predicates.cpp => GmshPredicates.cpp} | 0 Numeric/Makefile | 17 +- Numeric/Numeric.cpp | 545 +++++++++++++++--- Numeric/Numeric.h | 35 +- Numeric/NumericEmbedded.cpp | 38 ++ Numeric/NumericEmbedded.h | 1 + Numeric/gsl_brent.cpp | 132 ----- Numeric/gsl_min.cpp | 265 --------- Numeric/gsl_newt.cpp | 108 ---- Post/Makefile | 2 +- configure | 56 +- configure.in | 38 +- contrib/NR/Makefile | 61 -- contrib/NR/brent.cpp | 77 --- contrib/NR/dpythag.cpp | 14 - contrib/NR/dsvdcmp.cpp | 183 ------ contrib/NR/fdjac.cpp | 29 - contrib/NR/fmin.cpp | 20 - contrib/NR/lnsrch.cpp | 65 --- contrib/NR/lubksb.cpp | 23 - contrib/NR/ludcmp.cpp | 60 -- contrib/NR/mnbrak.cpp | 67 --- contrib/NR/newt.cpp | 92 --- contrib/NR/nrutil.cpp | 293 ---------- contrib/NR/nrutil.h | 43 -- 28 files changed, 680 insertions(+), 1907 deletions(-) rename Numeric/{gmsh_predicates.cpp => GmshPredicates.cpp} (100%) delete mode 100644 Numeric/gsl_brent.cpp delete mode 100644 Numeric/gsl_min.cpp delete mode 100644 Numeric/gsl_newt.cpp delete mode 100644 contrib/NR/Makefile delete mode 100644 contrib/NR/brent.cpp delete mode 100644 contrib/NR/dpythag.cpp delete mode 100644 contrib/NR/dsvdcmp.cpp delete mode 100644 contrib/NR/fdjac.cpp delete mode 100644 contrib/NR/fmin.cpp delete mode 100644 contrib/NR/lnsrch.cpp delete mode 100644 contrib/NR/lubksb.cpp delete mode 100644 contrib/NR/ludcmp.cpp delete mode 100644 contrib/NR/mnbrak.cpp delete mode 100644 contrib/NR/newt.cpp delete mode 100644 contrib/NR/nrutil.cpp delete mode 100644 contrib/NR/nrutil.h diff --git a/Geo/GFace.cpp b/Geo/GFace.cpp index e001d89afe..85b787e0d5 100644 --- a/Geo/GFace.cpp +++ b/Geo/GFace.cpp @@ -10,6 +10,7 @@ #include "MElement.h" #include "GmshMessage.h" #include "VertexArray.h" +#include "GmshMatrix.h" #if defined(HAVE_GMSH_EMBEDDED) #include "GmshEmbedded.h" @@ -17,14 +18,6 @@ #include "Numeric.h" #include "GaussLegendre1D.h" #include "Context.h" -#if defined(HAVE_GSL) -#include <gsl/gsl_vector.h> -#include <gsl/gsl_linalg.h> -#else -#define NRANSI -#include "nrutil.h" -void dsvdcmp(double **a, int m, int n, double w[], double **v); -#endif #endif extern Context_T CTX; @@ -241,7 +234,6 @@ void GFace::computeMeanPlane(const std::vector<MVertex*> &points) void GFace::computeMeanPlane(const std::vector<SPoint3> &points) { -#if !defined(HAVE_GMSH_EMBEDDED) // The concept of a mean plane computed in the sense of least // squares is fine for plane surfaces(!), but not really the best // one for non-plane surfaces. Indeed, imagine a quarter of a circle @@ -263,63 +255,29 @@ void GFace::computeMeanPlane(const std::vector<SPoint3> &points) ym /= (double)ndata; zm /= (double)ndata; - int min; - double res[4], svd[3]; -#if defined(HAVE_GSL) - gsl_matrix *U = gsl_matrix_alloc(ndata, na); - gsl_matrix *V = gsl_matrix_alloc(na, na); - gsl_vector *W = gsl_vector_alloc(na); - gsl_vector *TMPVEC = gsl_vector_alloc(na); + Double_Matrix U(ndata, na), V(na, na); + Double_Vector sigma(na); for(int i = 0; i < ndata; i++) { - gsl_matrix_set(U, i, 0, points[i].x() - xm); - gsl_matrix_set(U, i, 1, points[i].y() - ym); - gsl_matrix_set(U, i, 2, points[i].z() - zm); + U(i, 0) = points[i].x() - xm; + U(i, 1) = points[i].y() - ym; + U(i, 2) = points[i].z() - zm; } - gsl_linalg_SV_decomp(U, V, W, TMPVEC); - svd[0] = gsl_vector_get(W, 0); - svd[1] = gsl_vector_get(W, 1); - svd[2] = gsl_vector_get(W, 2); + U.svd(V, sigma); + double res[4], svd[3]; + svd[0] = sigma(0); + svd[1] = sigma(1); + svd[2] = sigma(2); + int min; if(fabs(svd[0]) < fabs(svd[1]) && fabs(svd[0]) < fabs(svd[2])) min = 0; else if(fabs(svd[1]) < fabs(svd[0]) && fabs(svd[1]) < fabs(svd[2])) min = 1; else min = 2; - res[0] = gsl_matrix_get(V, 0, min); - res[1] = gsl_matrix_get(V, 1, min); - res[2] = gsl_matrix_get(V, 2, min); + res[0] = V(0, min); + res[1] = V(1, min); + res[2] = V(2, min); norme(res); - gsl_matrix_free(U); - gsl_matrix_free(V); - gsl_vector_free(W); - gsl_vector_free(TMPVEC); -#else - double **U = dmatrix(1, ndata, 1, na); - double **V = dmatrix(1, na, 1, na); - double *W = dvector(1, na); - for(int i = 0; i < ndata; i++) { - U[i + 1][1] = points[i].x() - xm; - U[i + 1][2] = points[i].y() - ym; - U[i + 1][3] = points[i].z() - zm; - } - dsvdcmp(U, ndata, na, W, V); - if(fabs(W[1]) < fabs(W[2]) && fabs(W[1]) < fabs(W[3])) - min = 1; - else if(fabs(W[2]) < fabs(W[1]) && fabs(W[2]) < fabs(W[3])) - min = 2; - else - min = 3; - svd[0] = W[1]; - svd[1] = W[2]; - svd[2] = W[3]; - res[0] = V[1][min]; - res[1] = V[2][min]; - res[2] = V[3][min]; - norme(res); - free_dmatrix(U, 1, ndata, 1, na); - free_dmatrix(V, 1, na, 1, na); - free_dvector(W, 1, na); -#endif double ex[3], t1[3], t2[3]; @@ -428,7 +386,6 @@ end: } } } -#endif } void GFace::getMeanPlaneData(double VX[3], double VY[3], @@ -481,17 +438,11 @@ double GFace::curvature(const SPoint2 ¶m) const SVector3 dndu = 500 * (n2 - n1); SVector3 dndv = 500 * (n4 - n3); - // double c = fabs(dot(dndu, du) + dot(dndv, dv)) / detJ; - - double ddu = dot(dndu,du); double ddv = dot(dndv,dv); double c = std::max(fabs(ddu),fabs(ddv))/detJ; - - // Msg::Info("c = %g detJ %g", c, detJ); - return c; } @@ -505,7 +456,6 @@ void GFace::XYZtoUV(const double X, const double Y, const double Z, double &U, double &V, const double relax, const bool onSurface) const { -#if !defined(HAVE_GMSH_EMBEDDED) const double Precision = 1.e-8; const int MaxIter = 25; const int NumInitGuess = 11; @@ -584,7 +534,6 @@ void GFace::XYZtoUV(const double X, const double Y, const double Z, Msg::Info("point %g %g %g : Relaxation factor = %g", X, Y, Z, 0.75 * relax); XYZtoUV(X, Y, Z, U, V, 0.75 * relax); } -#endif } SPoint2 GFace::parFromPoint(const SPoint3 &p) const diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp index 302b465c00..fe4353a52d 100644 --- a/Geo/Geo.cpp +++ b/Geo/Geo.cpp @@ -2886,9 +2886,9 @@ static Vertex *VERTEX; static double min1d(double (*funct) (double), double *xmin) { - // 0. for tolerance allows for maximum as code in gsl_brent - return (brent(CURVE->ubeg, 0.5*(CURVE->ubeg + CURVE->uend), CURVE->uend, - funct, 0., xmin)); + // tolerance==0. allows for maximum as code in gsl_brent + return brent(CURVE->ubeg, 0.5 * (CURVE->ubeg + CURVE->uend), CURVE->uend, + funct, 0., xmin); } static void projectPS(int N, double x[], double res[]) @@ -2943,8 +2943,8 @@ bool ProjectPointOnSurface(Surface *s, Vertex &p, double u[2]) int check; SURFACE = s; VERTEX = &p; - newt(x, 2, &check, projectPS); + Vertex vv = InterpolateSurface(s, x[1], x[2], 0, 0); double res[3]; projectPS(2, x, res); @@ -3091,6 +3091,7 @@ static bool IntersectCurveSurface(Curve *c, Surface *s, double x[4]) SURFACE = s; CURVE = c; newt(x, 3, &check, intersectCS); + if(check) return false; return true; } diff --git a/Numeric/GmshMatrix.h b/Numeric/GmshMatrix.h index 0df4528384..dc72f50663 100644 --- a/Numeric/GmshMatrix.h +++ b/Numeric/GmshMatrix.h @@ -7,8 +7,34 @@ #define _GMSH_MATRIX_H_ #include <math.h> +#include <algorithm> #include "GmshMessage.h" +#if defined(HAVE_BLAS) +extern "C" { + void dgemm_(const char *transa, const char *transb, + int *l, int *n, int *m, double *alpha, + const void *a, int *lda, void *b, int *ldb, + double *beta, void *c, int *ldc); + void dgemv_(const char *trans, int *m, int *n, double *alpha, + void *a, int *lda, void *x, int *incx, + double *beta, void *y, int *incy); +} +#endif + +#if defined(HAVE_LAPACK) +extern "C" { + void dgesv_(const int *N, const int *nrhs, double *A, const int *lda, + int *ipiv, double *b, const int *ldb, int *info); + void dgetrf_(const int *M, const int *N, double *A, const int *lda, + int *ipiv, int *info); + void dgesvd_(const char* jobu, const char *jobvt, const int *M, const int *N, + double *A, const int *lda, double *S, double* U, const int *ldu, + double *VT, const int *ldvt, double *work, const int *lwork, + const int *info); +} +#endif + template <class SCALAR> class Gmsh_Matrix; template <class SCALAR> @@ -60,79 +86,6 @@ class Gmsh_Matrix private: int _r, _c; SCALAR *_data; - void _back_substitution(int *indx, SCALAR *b) - { - int i, ii = -1, ip, j; - SCALAR sum; - for(i = 0; i < _c; i++){ - ip = indx[i]; - sum = b[ip]; - b[ip] = b[i]; - if(ii != -1) - for(j = ii; j <= i - 1; j++) sum -= (*this)(i, j) * b[j]; - else if(sum) ii = i; - b[i] = sum; - } - for(i = _c - 1; i >= 0; i--){ - sum = b[i]; - for(j = i + 1; j < _c; j++) sum -= (*this)(i, j) * b[j]; - b[i] = sum / (*this)(i, i); - } - } - bool _lu_decomposition(int *indx, SCALAR &determinant) - { - if(_r != _c) - Msg::Fatal("Cannot LU factorize non-square matrix"); - int i, imax, j, k; - SCALAR big, dum, sum, temp; - SCALAR *vv = new SCALAR[_c]; - determinant = 1.; - for(i = 0; i < _c; i++){ - big = 0.; - for(j = 0; j < _c; j++) - if((temp = fabs((*this)(i, j))) > big) big = temp; - if(big == 0.) { - delete [] vv; - return false; - } - vv[i] = 1. / big; - } - for(j = 0; j < _c; j++){ - for(i = 0; i < j; i++){ - sum = (*this)(i, j); - for(k = 0; k < i; k++) sum -= (*this)(i, k)*(*this)(k, j); - (*this)(i, j) = sum; - } - big = 0.; - for(i = j; i < _c; i++){ - sum = (*this)(i, j); - for(k = 0; k < j; k++) - sum -= (*this)(i, k) * (*this)(k, j); - (*this)(i, j) = sum; - if((dum = vv[i] * fabs(sum)) >= big){ - big = dum; - imax = i; - } - } - if(j != imax){ - for(k = 0; k < _c; k++){ - dum = (*this)(imax, k); - (*this)(imax, k) = (*this)(j, k); - (*this)(j, k) = dum; - } - determinant = -(determinant); - vv[imax] = vv[j]; - } - indx[j] = imax; - if((*this)(j, j) == 0.) (*this)(j, j) = 1.e-20; - if(j != _c){ - dum = 1. / ((*this)(j, j)); - for(i = j + 1; i < _c; i++) (*this)(i, j) *= dum; - } - } - delete [] vv; - return true; - } public: Gmsh_Matrix(int r, int c) : _r(r), _c(c) { @@ -179,20 +132,34 @@ class Gmsh_Matrix } inline void mult(const Gmsh_Matrix<SCALAR> &b, Gmsh_Matrix<SCALAR> &c) { +#if 0 // defined(HAVE_BLAS) + void dgemm_(const char *transa, const char *transb, + int *l, int *n, int *m, double *alpha, + const void *a, int *lda, void *b, int *ldb, + double *beta, void *c, int *ldc); +#else c.scale(0.); for(int i = 0; i < _r; i++) for(int j = 0; j < b.size2(); j++) for(int k = 0; k < _c; k++) c._data[i + _r * j] += (*this)(i, k) * b(k, j); +#endif } inline void blas_dgemm(const Gmsh_Matrix<SCALAR> &b, Gmsh_Matrix<SCALAR> &c, const SCALAR alpha=1., const SCALAR beta=1.) { +#if 0 // defined(HAVE_BLAS) + void dgemm_(const char *transa, const char *transb, + int *l, int *n, int *m, double *alpha, + const void *a, int *lda, void *b, int *ldb, + double *beta, void *c, int *ldc); +#else Gmsh_Matrix<SCALAR> temp(b.size1(), c.size2()); temp.mult(b, c); scale(beta); temp.scale(alpha); add(temp); +#endif } inline void set_all(const SCALAR &m) { @@ -217,45 +184,39 @@ class Gmsh_Matrix } inline void mult(const Gmsh_Vector<SCALAR> &x, Gmsh_Vector<SCALAR> &y) { +#if 0 //defined(HAVE_BLAS) + void dgemv_(const char *trans, int *m, int *n, double *alpha, + void *a, int *lda, void *x, int *incx, + double *beta, void *y, int *incy); +#else y.scale(0.); for(int i = 0; i < _r; i++) for(int j = 0; j < _c; j++) y._data[i] += (*this)(i, j) * x(j); +#endif } - inline bool lu_solve(const Gmsh_Vector<SCALAR> &rhs, Gmsh_Vector<SCALAR> &result) + inline Gmsh_Matrix<SCALAR> transpose() { - int *indx = new int[_c]; - SCALAR d; - if(!_lu_decomposition(indx, d)){ - delete [] indx; - return false; - } - for(int i = 0; i < _c; i++) result(i) = rhs(i); - _back_substitution(indx, result._data); - delete [] indx; - return true; + Gmsh_Matrix<SCALAR> T(size2(), size1()); + for(int i = 0; i < size1(); i++) + for(int j = 0; j < size2(); j++) + T(j, i) = (*this)(i, j); + return T; } - inline bool invert() + inline bool lu_solve(const Gmsh_Vector<SCALAR> &rhs, Gmsh_Vector<SCALAR> &result) { - Gmsh_Matrix y(_r, _c); - SCALAR *col = new SCALAR[_c]; - int *indx = new int[_c]; - SCALAR d; - if (!_lu_decomposition(indx, d)){ - delete [] col; - delete [] indx; - return false; - } - for(int j = 0; j < _c; j++){ - for(int i = 0; i < _c; i++) col[i] = 0.0; - col[j] = 1.0; - _back_substitution(indx, col); - for(int i = 0; i < _c; i++) y(i, j) = col[i]; - } - (*this) = y; - delete [] col; - delete [] indx; - return true; +#if defined(HAVE_LAPACK) + int N = size1(), nrhs = 1, lda = N, ldb = N, info; + int *ipiv = new int[N]; + for(int i = 0; i < N; i++) result(i) = rhs(i); + dgesv_(&N, &nrhs, _data, &lda, ipiv, result._data, &ldb, &info); + delete [] ipiv; + if(info == 0) return true; + Msg::Error("Problem in LAPACK LU (info=%d)", info); +#else + Msg::Error("LU factorization requires LAPACK"); +#endif + return false; } Gmsh_Matrix<SCALAR> cofactor(int i, int j) const { @@ -272,14 +233,38 @@ class Gmsh_Matrix } SCALAR determinant() const { - Gmsh_Matrix<SCALAR> tmp = *this; - SCALAR factor = 1.; - int *indx = new int[_c]; - if(!tmp._lu_decomposition(indx, factor)) return 0.; - SCALAR det = factor; - for(int i = 0; i < _c; i++) det *= tmp(i, i); - delete [] indx; + Gmsh_Matrix<SCALAR> tmp(*this); +#if defined(HAVE_LAPACK) + int M = size1(), N = size2(), lda = size1(), info; + int *ipiv = new int[std::min(M, N)]; + dgetrf_(&M, &N, tmp._data, &lda, ipiv, &info); + SCALAR det = 1.; + for(int i = 0; i < size1(); i++){ + det *= tmp(i, i); + if(ipiv[i] != i + 1) det = -det; + } return det; +#else + Msg::Error("Determinant computation requires LAPACK"); + return 0.; +#endif + } + bool svd(Gmsh_Matrix<SCALAR> &V, Gmsh_Vector<SCALAR> &S) + { +#if defined(HAVE_LAPACK) + Gmsh_Matrix<SCALAR> VT(V.size2(), V.size1()); + int M = size1(), N = size2(), LDA = size1(), LDVT = VT.size1(), info; + int LWORK = std::max(3 * std::min(M, N) + std::max(M, N), 5 * std::min(M, N)); + Gmsh_Vector<SCALAR> WORK(LWORK); + dgesvd_("O", "A", &M, &N, _data, &LDA, S._data, _data, &LDA, + VT._data, &LDVT, WORK._data, &LWORK, &info); + V = VT.transpose(); + if(info == 0) return true; + Msg::Error("Problem in LAPACK SVD (info=%d)", info); +#else + Msg::Error("Singular value decomposition requires LAPACK"); +#endif + return false; } }; @@ -403,24 +388,20 @@ class GSL_Matrix { gsl_blas_dgemv(CblasNoTrans, 1., _data, x._data, 0., b._data); } - inline bool lu_solve(const GSL_Vector &rhs, GSL_Vector &result) + inline GSL_Matrix transpose() { - int s; - gsl_permutation * p = gsl_permutation_alloc(size1()); - gsl_linalg_LU_decomp(_data, p, &s); - gsl_linalg_LU_solve(_data, p, rhs._data, result._data); - gsl_permutation_free(p); - return true; + GSL_Matrix T(size2(), size1()); + for(int i = 0; i < size1(); i++) + for(int j = 0; j < size2(); j++) + T(j, i) = (*this)(i, j); + return T; } - inline bool invert() + inline bool lu_solve(const GSL_Vector &rhs, GSL_Vector &result) { int s; gsl_permutation *p = gsl_permutation_alloc(size1()); gsl_linalg_LU_decomp(_data, p, &s); - gsl_matrix *inv = gsl_matrix_calloc(size1(), size2()); - gsl_linalg_LU_invert(_data, p, inv) ; - gsl_matrix_memcpy(_data, inv); - gsl_matrix_free(inv); + gsl_linalg_LU_solve(_data, p, rhs._data, result._data); gsl_permutation_free(p); return true; } @@ -446,6 +427,12 @@ class GSL_Matrix gsl_permutation_free(p); return gsl_linalg_LU_det(tmp._data, s); } + bool svd(GSL_Matrix &V, GSL_Vector &S) + { + GSL_Vector tmp(S.size()); + gsl_linalg_SV_decomp(_data, V._data, S._data, tmp._data); + return false; + } }; typedef GSL_Matrix Double_Matrix; diff --git a/Numeric/gmsh_predicates.cpp b/Numeric/GmshPredicates.cpp similarity index 100% rename from Numeric/gmsh_predicates.cpp rename to Numeric/GmshPredicates.cpp diff --git a/Numeric/Makefile b/Numeric/Makefile index f07d08cb20..b0eea45326 100644 --- a/Numeric/Makefile +++ b/Numeric/Makefile @@ -24,10 +24,7 @@ SRC = Numeric.cpp\ GaussQuadratureTet.cpp\ GaussQuadratureHex.cpp\ GaussLegendreSimplex.cpp\ - gmsh_predicates.cpp\ - gsl_newt.cpp\ - gsl_min.cpp\ - gsl_brent.cpp + GmshPredicates.cpp\ OBJ = ${SRC:.cpp=${OBJEXT}} @@ -56,8 +53,8 @@ depend: # DO NOT DELETE THIS LINE Numeric${OBJEXT}: Numeric.cpp ../Common/GmshMessage.h Numeric.h \ - NumericEmbedded.h -NumericEmbedded${OBJEXT}: NumericEmbedded.cpp NumericEmbedded.h \ + NumericEmbedded.h GmshMatrix.h +NumericEmbedded${OBJEXT}: NumericEmbedded.cpp NumericEmbedded.h GmshMatrix.h \ ../Common/GmshMessage.h gmshAssembler${OBJEXT}: gmshAssembler.cpp ../Geo/MVertex.h ../Geo/SPoint2.h \ ../Geo/SPoint3.h gmshAssembler.h gmshLinearSystem.h @@ -122,10 +119,4 @@ GaussQuadratureHex${OBJEXT}: GaussQuadratureHex.cpp Gauss.h Numeric.h \ NumericEmbedded.h GaussLegendre1D.h GaussLegendreSimplex${OBJEXT}: GaussLegendreSimplex.cpp Gauss.h Numeric.h \ NumericEmbedded.h GaussLegendre1D.h -gmsh_predicates${OBJEXT}: gmsh_predicates.cpp -gsl_newt${OBJEXT}: gsl_newt.cpp ../Common/GmshMessage.h Numeric.h \ - NumericEmbedded.h -gsl_min${OBJEXT}: gsl_min.cpp ../Common/GmshMessage.h Numeric.h \ - NumericEmbedded.h -gsl_brent${OBJEXT}: gsl_brent.cpp ../Common/GmshMessage.h Numeric.h \ - NumericEmbedded.h +GmshPredicates${OBJEXT}: GmshPredicates.cpp diff --git a/Numeric/Numeric.cpp b/Numeric/Numeric.cpp index 4c7d0233a2..35b4256978 100644 --- a/Numeric/Numeric.cpp +++ b/Numeric/Numeric.cpp @@ -5,16 +5,19 @@ #include "GmshMessage.h" #include "Numeric.h" +#include "GmshMatrix.h" -// Check GSL version. We need at least 1.2, since all versions <= -// 1.1.1 have a buggy SVD routine (infinite loop fixed on Sun Jun 16 -// 11:45:29 2002 in GSL's cvs tree). We check this at run time since -// Gmsh could be distributed with the gsl dynamically linked. +// This file contains the routines that depend on the GSL, some of +// which need to be reimplemented (e.g. in terms of Gmsh_Matrix) +// before we can get rid of the GSL completely. #if defined(HAVE_GSL) #include <gsl/gsl_errno.h> -#include <gsl/gsl_vector.h> +#include <gsl/gsl_math.h> +#include <gsl/gsl_min.h> +#include <gsl/gsl_multimin.h> +#include <gsl/gsl_multiroots.h> #include <gsl/gsl_linalg.h> void my_gsl_msg(const char *reason, const char *file, int line, @@ -33,90 +36,482 @@ int check_gsl() return 1; } -#else - -#define NRANSI -#include "nrutil.h" -void dsvdcmp(double **a, int m, int n, double w[], double **v); +static double (*nrfuncbrent) (double); -int check_gsl() +static double fn1(double x, void *params) { - // initilize robust geometric predicates - gmsh::exactinit() ; - return 1; + double val = nrfuncbrent(x); + return val; } -#endif +static int gsl_min_fminimizer_set_with_values_MOD(gsl_min_fminimizer *s, + gsl_function *f, + double x_minimum, double f_minimum, + double x_lower, double f_lower, + double x_upper, double f_upper) +{ + s->function = f; + s->x_minimum = x_minimum; + s->x_lower = x_lower; + s->x_upper = x_upper; + if (x_lower > x_upper){ + GSL_ERROR ("invalid interval (lower > upper)", GSL_EINVAL); + } + s->f_lower = f_lower; + s->f_upper = f_upper; + s->f_minimum = f_minimum; + return (s->type->set) (s->state, s->function, + x_minimum, f_minimum, + x_lower, f_lower, + x_upper, f_upper); +} -void invert_singular_matrix3x3(double MM[3][3], double II[3][3]) +// Returns the minimum betwen ax and cx to a given tolerance tol using +// brent's method. +double brent(double ax, double bx, double cx, + double (*f) (double), double tol, double *xmin) { - int i, j, k, n = 3; - double TT[3][3]; +#define MAXITER 100 + // The solver can stall at the following internal tolerance in brent - so + // this is about the lowest possible tolerance. + if(tol == 0.) tol = 10. * GSL_SQRT_DBL_EPSILON; + const double tolsq = tol*tol; + int status; + int iter = 0; + double a, b, c; // a < b < c + double fa, fb, fc; + const gsl_min_fminimizer_type *T; + gsl_min_fminimizer *s; + gsl_function F; - for(i = 1; i <= n; i++) { - for(j = 1; j <= n; j++) { - II[i - 1][j - 1] = 0.0; - TT[i - 1][j - 1] = 0.0; - } + // gsl wants a<b + b = bx; + if(ax < cx) { + a = ax; + c = cx; + } + else { + a = cx; + c = ax; } -#if defined(HAVE_GSL) - gsl_matrix *M = gsl_matrix_alloc(3, 3); - gsl_matrix *V = gsl_matrix_alloc(3, 3); - gsl_vector *W = gsl_vector_alloc(3); - gsl_vector *TMPVEC = gsl_vector_alloc(3); - for(i = 1; i <= n; i++) { - for(j = 1; j <= n; j++) { - gsl_matrix_set(M, i - 1, j - 1, MM[i - 1][j - 1]); + nrfuncbrent = f; + F.function = &fn1; + F.params = 0; + + fa = f(a); + fb = f(b); + fc = f(c); + if(fb > fa || fb > fc) { + if(a < c) { + b = a; + fb = fa; } - } - gsl_linalg_SV_decomp(M, V, W, TMPVEC); - for(i = 1; i <= n; i++) { - for(j = 1; j <= n; j++) { - double ww = gsl_vector_get(W, i - 1); - if(fabs(ww) > 1.e-16) { //singular value precision - TT[i - 1][j - 1] += gsl_matrix_get(M, j - 1, i - 1) / ww; - } + else { + b = c; + fb = fc; } } - for(i = 1; i <= n; i++) { - for(j = 1; j <= n; j++) { - for(k = 1; k <= n; k++) { - II[i - 1][j - 1] += - gsl_matrix_get(V, i - 1, k - 1) * TT[k - 1][j - 1]; - } - } + + // if a-c < tol, return func(b) + if(gsl_min_test_interval(a, c, tolsq, tol) == GSL_SUCCESS) { + *xmin = b; + return (fb); } - gsl_matrix_free(M); - gsl_matrix_free(V); - gsl_vector_free(W); - gsl_vector_free(TMPVEC); -#else - double **M = dmatrix(1, 3, 1, 3); - double **V = dmatrix(1, 3, 1, 3); - double *W = dvector(1, 3); - for(i = 1; i <= n; i++) { - for(j = 1; j <= n; j++) { - M[i][j] = MM[i - 1][j - 1]; - } + + T = gsl_min_fminimizer_brent; + s = gsl_min_fminimizer_alloc(T); + // gsl_min_fminimizer_set(s, &F, b, a, c); // Standard + // This mod avoids some error checks so we can have a minimum at an extent. + gsl_min_fminimizer_set_with_values_MOD(s, &F, b, fb, a, fa, c, fc); + + do { + iter++; + status = gsl_min_fminimizer_iterate(s); + if(status) + break; // solver problem + a = gsl_min_fminimizer_x_lower(s); + c = gsl_min_fminimizer_x_upper(s); + // fb = gsl_min_fminimizer_f_minimum(s); + // fa = gsl_min_fminimizer_f_lower(s); + // fc = gsl_min_fminimizer_f_upper(s); + status = gsl_min_test_interval(a, c, tolsq, tol); + // ... in case curve becomes too flat - not required? + // std::fabs(fa - fc) < (std::fabs(fb) + tol)*tol } - dsvdcmp(M, n, n, W, V); - for(i = 1; i <= n; i++) { - for(j = 1; j <= n; j++) { - if(fabs(W[i]) > 1.e-16) { //singular value precision - TT[i - 1][j - 1] += M[j][i] / W[i]; - } - } + while(status == GSL_CONTINUE && iter < MAXITER); + b = gsl_min_fminimizer_x_minimum(s); + + if(status != GSL_SUCCESS) + Msg::Error("minimization did not converge: f(%g) = %g", b, fn1(b, NULL)); + + *xmin = b; + gsl_min_fminimizer_free(s); + return fn1(b, NULL); +} + + +#define MAX_DIM_NEWT 10 +#define MAXITER 100 +#define PREC 1.e-8 + +static int nrdim; +static double nru[MAX_DIM_NEWT], nrv[MAX_DIM_NEWT]; +static void (*nrfunc) (int n, double x[], double y[]); +struct gsl_dummy{ int i; }; + +static void convert_vector_from_gsl(const gsl_vector * gv, double *v) +{ + int i, m; + m = gv->size; + for(i = 0; i < m; i++) { + v[i + 1] = gsl_vector_get(gv, i); } - for(i = 1; i <= n; i++) { - for(j = 1; j <= n; j++) { - for(k = 1; k <= n; k++) { - II[i - 1][j - 1] += V[i][k] * TT[k - 1][j - 1]; - } - } +} + +static void convert_vector_to_gsl(double *v, int n, gsl_vector * gv) +{ + int i; + for(i = 0; i < n; i++) { + gsl_vector_set(gv, i, v[i + 1]); } - free_dmatrix(M, 1, n, 1, n); - free_dmatrix(V, 1, n, 1, n); - free_dvector(W, 1, n); -#endif } + +static int gslfunc(const gsl_vector * xx, void *params, gsl_vector * f) +{ + convert_vector_from_gsl(xx, nru); + (*nrfunc) (nrdim, nru, nrv); + // Msg::Info("f(%lf,%lf) = %lf %lf\n",nru[1],nru[2],nrv[1],nrv[2]); + convert_vector_to_gsl(nrv, nrdim, f); + return GSL_SUCCESS; +} + +// Warning: for compatibility with the old newt from NR, x[] and the +// arguments of func() are indexed from 1 to n... +void newt(double x[], int n, int *check, + void (*func) (int, double[], double[])) +{ + const gsl_multiroot_fsolver_type *T; + gsl_multiroot_fsolver *s; + int status; + size_t iter = 0; + struct gsl_dummy p = { 1 }; + gsl_multiroot_function f = { &gslfunc, n, &p }; + gsl_vector *xx = gsl_vector_alloc(n); + + if(n > MAX_DIM_NEWT - 1) + Msg::Fatal("Maximum Newton dimension exceeded\n"); + nrdim = n; + + nrfunc = func; + convert_vector_to_gsl(x, n, xx); + + T = gsl_multiroot_fsolver_hybrid; + s = gsl_multiroot_fsolver_alloc(T, n); + gsl_multiroot_fsolver_set(s, &f, xx); + + do { + iter++; + status = gsl_multiroot_fsolver_iterate(s); + // Msg::Info("status %d %d %d %lf %lf\n", + // status,n,iter,gsl_vector_get(s->x,0),gsl_vector_get(s->x,1)); + if(status) + break; // solver problem + status = gsl_multiroot_test_residual(s->f, n * PREC); + } + while(status == GSL_CONTINUE && iter < MAXITER); + + if(status == GSL_CONTINUE) { + *check = 1; // problem !!! + } + else { + // Msg::Info("status %d %d %d %lf %lf\n", + // status,n,iter,gsl_vector_get(s->x,0),gsl_vector_get(s->x,1)); + convert_vector_from_gsl(s->x, x); + *check = 0; // converged + } + + gsl_multiroot_fsolver_free(s); + gsl_vector_free(xx); +} + +static double (*f_stat) (double, double, void *data); +static void (*df_stat) (double, double, double &, double &, double &, void *data); +static double (*f_stat3) (double, double, double, void *data); +static void (*df_stat3) (double, double, double, double &, double &, + double &, double &,void *data); +static double (*f_statN) (double*, void *data); +static void (*df_statN) (double*, double *, double &,void *data); + +static double fobj(const gsl_vector * x, void * data) +{ + double u, v; + u = gsl_vector_get(x, 0); + v = gsl_vector_get(x, 1); + return f_stat(u, v, data); +} + +static double fobj3(const gsl_vector * x, void * data) +{ + double u, v,w; + u = gsl_vector_get(x, 0); + v = gsl_vector_get(x, 1); + w = gsl_vector_get(x, 2); + return f_stat3(u, v, w, data); +} + +static double fobjN (const gsl_vector * x, void * data) +{ + return f_statN(x->data, data); +} + +static void dfobj (const gsl_vector * x, void * params, gsl_vector * g) +{ + double u, v, f, duf, dvf; + u = gsl_vector_get(x, 0); + v = gsl_vector_get(x, 1); + df_stat(u, v, f, duf, dvf, params); + gsl_vector_set(g, 0, duf); + gsl_vector_set(g, 1, dvf); +} + +static void dfobj3 (const gsl_vector * x, void * params, gsl_vector * g) +{ + double u, v, w,f, duf, dvf,dwf; + u = gsl_vector_get(x, 0); + v = gsl_vector_get(x, 1); + w = gsl_vector_get(x, 2); + df_stat3(u, v, w, f, duf, dvf, dwf, params); + gsl_vector_set(g, 0, duf); + gsl_vector_set(g, 1, dvf); + gsl_vector_set(g, 2, dwf); +} + +static void dfobjN(const gsl_vector * x, void * params, gsl_vector * g) +{ + double f; + df_statN(x->data, g->data,f,params); +} + +static void fdfobj(const gsl_vector * x, void * params, double * f, gsl_vector * g) +{ + double u, v, duf, dvf; + u = gsl_vector_get(x, 0); + v = gsl_vector_get(x, 1); + df_stat(u, v, *f, duf, dvf, params); + gsl_vector_set(g, 0, duf); + gsl_vector_set(g, 1, dvf); +} + +static void fdfobj3(const gsl_vector * x, void * params, double * f, gsl_vector * g) +{ + double u, v, w,duf, dvf,dwf; + u = gsl_vector_get(x, 0); + v = gsl_vector_get(x, 1); + w = gsl_vector_get(x, 2); + df_stat3(u, v, w, *f, duf, dvf, dwf, params); + gsl_vector_set(g, 0, duf); + gsl_vector_set(g, 1, dvf); + gsl_vector_set(g, 2, dwf); +} + +static void fdfobjN(const gsl_vector * x, void * params, double * f, gsl_vector * g) +{ + df_statN(x->data,g->data,*f,params); +} + +void minimize_2(double (*f) (double, double, void *data), + void (*df) (double, double, double &, double &, double &, void *data) , + void *data,int niter, + double &U, double &V, double &res) +{ + f_stat = f; + df_stat = df; + + int iter = 0; + int status; + + const gsl_multimin_fdfminimizer_type *T; + gsl_multimin_fdfminimizer *s; + gsl_vector *x; + gsl_multimin_function_fdf my_func; + + my_func.f = &fobj; + my_func.df = &dfobj; + my_func.fdf = &fdfobj; + my_func.n = 2; + my_func.params = data; + + x = gsl_vector_alloc (2); + gsl_vector_set (x, 0, U); + gsl_vector_set (x, 1, V); + + T = gsl_multimin_fdfminimizer_conjugate_fr; + s = gsl_multimin_fdfminimizer_alloc (T, 2); + + gsl_multimin_fdfminimizer_set(s, &my_func, x, 0.01, 1e-4); + + do{ + iter++; + status = gsl_multimin_fdfminimizer_iterate(s); + if(status) + break; + status = gsl_multimin_test_gradient(s->gradient, 1e-3); + } + while (status == GSL_CONTINUE && iter < niter); + + U = gsl_vector_get(s->x, 0); + V = gsl_vector_get(s->x, 1); + res = s->f; + gsl_multimin_fdfminimizer_free (s); + gsl_vector_free (x); +} + +void minimize_3(double (*f) (double, double, double,void *data), + void (*df) (double , double , double , + double &, double &, double &, double &, + void *data) , + void *data,int niter, + double &U, double &V, double &W, double &res) +{ + f_stat3 = f; + df_stat3 = df; + + int iter = 0; + int status; + + const gsl_multimin_fdfminimizer_type *T; + gsl_multimin_fdfminimizer *s; + gsl_vector *x; + gsl_multimin_function_fdf my_func; + + my_func.f = &fobj3; + my_func.df = &dfobj3; + my_func.fdf = &fdfobj3; + my_func.n = 3; + my_func.params = data; + + x = gsl_vector_alloc (3); + gsl_vector_set(x, 0, U); + gsl_vector_set(x, 1, V); + gsl_vector_set(x, 2, W); + + T = gsl_multimin_fdfminimizer_conjugate_fr; + s = gsl_multimin_fdfminimizer_alloc(T, 3); + + gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.01, 1e-4); + + do{ + iter++; + status = gsl_multimin_fdfminimizer_iterate (s); + if (status) + break; + status = gsl_multimin_test_gradient (s->gradient, 1e-3); + } + while (status == GSL_CONTINUE && iter < niter); + + U = gsl_vector_get (s->x, 0); + V = gsl_vector_get (s->x, 1); + W = gsl_vector_get (s->x, 2); + res = s->f; + gsl_multimin_fdfminimizer_free (s); + gsl_vector_free (x); +} + +void minimize_N(int N, + double (*f) (double*,void *data), + void (*df) (double*,double*,double &,void *data) , + void *data,int niter, + double *U, double &res) +{ + f_statN = f; + df_statN = df; + + int iter = 0; + int status; + + const gsl_multimin_fdfminimizer_type *T; + gsl_multimin_fdfminimizer *s; + gsl_vector *x; + gsl_multimin_function_fdf my_func; + + my_func.f = &fobjN; + my_func.df = &dfobjN; + my_func.fdf = &fdfobjN; + my_func.n = N; + my_func.params = data; + + x = gsl_vector_alloc (N); + for (int i=0;i<N;i++) + gsl_vector_set (x, i, U[i]); + + T = gsl_multimin_fdfminimizer_conjugate_fr; + s = gsl_multimin_fdfminimizer_alloc (T, N); + + gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.01, 1e-4); + + do{ + iter++; + status = gsl_multimin_fdfminimizer_iterate (s); + + if (status) + break; + + status = gsl_multimin_test_gradient (s->gradient, 1e-3); + } + while (status == GSL_CONTINUE && iter < niter); + + for (int i=0;i<N;i++) + U[i] = gsl_vector_get (s->x, i); + res = s->f; + gsl_multimin_fdfminimizer_free (s); + gsl_vector_free (x); +} + +#else + +int check_gsl() +{ + // initilize robust geometric predicates + gmsh::exactinit() ; + return 1; +} + +double brent(double ax, double bx, double cx, + double (*f) (double), double tol, double *xmin) +{ + Msg::Error("Gmsh must be compiled with GSL support for brent"); +} + +void newt(double x[], int n, int *check, + void (*func) (int, double[], double[])) +{ + Msg::Error("Gmsh must be compiled with GSL support for newt"); +} + +void minimize_2(double (*f) (double, double, void *data), + void (*df) (double, double, double &, double &, double &, void *data) , + void *data,int niter, + double &U, double &V, double &res) +{ + Msg::Error("Gmsh must be compiled with GSL support for minimize_2"); +} + +void minimize_3(double (*f) (double, double, double, void *data), + void (*df) (double, double, double , double &, double &, + double &, double &, void *data) , + void *data,int niter, + double &U, double &V, double &W, double &res) +{ + Msg::Error("Gmsh must be compiled with GSL support for minimize_3"); +} + +void minimize_N(int N, double (*f) (double*, void *data), + void (*df) (double*, double*, double &, void *data) , + void *data,int niter, + double *, double &res) +{ + Msg::Error("Gmsh must be compiled with GSL support for minimize_N"); +} + +#endif diff --git a/Numeric/Numeric.h b/Numeric/Numeric.h index 341abd4728..4dc536ba36 100644 --- a/Numeric/Numeric.h +++ b/Numeric/Numeric.h @@ -9,28 +9,23 @@ #include "NumericEmbedded.h" int check_gsl(); -void invert_singular_matrix3x3(double MM[3][3], double II[3][3]); - -// Numerical routines implemented using either Numerical Recipes or -// the GSL double brent(double ax, double bx, double cx, - double (*f)(double), double tol, double *xmin); + double (*f) (double), double tol, double *xmin); void newt(double x[], int n, int *check, - void (*vecfunc)(int, double [], double [])); -void minimize_2 (double (*f) (double, double, void *data), - void (*df) (double, double, double &, double &, double &, void *data) , - void *data,int niter, - double &U, double &V, double &res); -void minimize_3 (double (*f) (double, double, double, void *data), - void (*df) (double, double, double , double &, double &, - double &, double &, void *data), - void *data,int niter, - double &U, double &V, double &W, double &res); -void minimize_N (int N, - double (*f) (double*, void *data), - void (*df) (double*, double*, double &, void *data) , - void *data,int niter, - double *, double &res); + void (*func) (int, double[], double[])); +void minimize_2(double (*f) (double, double, void *data), + void (*df) (double, double, double &, double &, double &, void *data), + void *data,int niter, + double &U, double &V, double &res); +void minimize_3(double (*f) (double, double, double, void *data), + void (*df) (double, double, double , double &, double &, + double &, double &, void *data), + void *data,int niter, + double &U, double &V, double &W, double &res); +void minimize_N(int N, double (*f) (double*, void *data), + void (*df) (double*, double*, double &, void *data), + void *data,int niter, + double *, double &res); // Robust geometrical predicates namespace gmsh{ diff --git a/Numeric/NumericEmbedded.cpp b/Numeric/NumericEmbedded.cpp index c1963fefd1..c625836a55 100644 --- a/Numeric/NumericEmbedded.cpp +++ b/Numeric/NumericEmbedded.cpp @@ -8,6 +8,7 @@ // Msg) #include "NumericEmbedded.h" +#include "GmshMatrix.h" #include "GmshMessage.h" #define SQU(a) ((a)*(a)) @@ -449,3 +450,40 @@ void eigsort(double d[3]) } } } + +void invert_singular_matrix3x3(double MM[3][3], double II[3][3]) +{ + int i, j, k, n = 3; + double TT[3][3]; + + for(i = 1; i <= n; i++) { + for(j = 1; j <= n; j++) { + II[i - 1][j - 1] = 0.0; + TT[i - 1][j - 1] = 0.0; + } + } + + Double_Matrix M(3, 3), V(3, 3); + Double_Vector W(3); + for(i = 1; i <= n; i++){ + for(j = 1; j <= n; j++){ + M(i - 1, j - 1) = MM[i - 1][j - 1]; + } + } + M.svd(V, W); + for(i = 1; i <= n; i++) { + for(j = 1; j <= n; j++) { + double ww = W(i - 1); + if(fabs(ww) > 1.e-16) { // singular value precision + TT[i - 1][j - 1] += M(j - 1, i - 1) / ww; + } + } + } + for(i = 1; i <= n; i++) { + for(j = 1; j <= n; j++) { + for(k = 1; k <= n; k++) { + II[i - 1][j - 1] += V(i - 1, k - 1) * TT[k - 1][j - 1]; + } + } + } +} diff --git a/Numeric/NumericEmbedded.h b/Numeric/NumericEmbedded.h index 08523ad8df..1256319121 100644 --- a/Numeric/NumericEmbedded.h +++ b/Numeric/NumericEmbedded.h @@ -73,5 +73,6 @@ double InterpolateIso(double *X, double *Y, double *Z, void gradSimplex(double *x, double *y, double *z, double *v, double *grad); double ComputeVonMises(double *val); double ComputeScalarRep(int numComp, double *val); +void invert_singular_matrix3x3(double MM[3][3], double II[3][3]); #endif diff --git a/Numeric/gsl_brent.cpp b/Numeric/gsl_brent.cpp deleted file mode 100644 index 59cb3be607..0000000000 --- a/Numeric/gsl_brent.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// Gmsh - Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle -// -// See the LICENSE.txt file for license information. Please report all -// bugs and problems to <gmsh@geuz.org>. - -#if defined(HAVE_GSL) - -#include "GmshMessage.h" -#include "Numeric.h" - -#include <gsl/gsl_errno.h> -#include <gsl/gsl_math.h> -#include <gsl/gsl_min.h> - -static double (*nrfunc) (double); - -double fn1(double x, void *params) -{ - double val = nrfunc(x); - return val; -} - -int gsl_min_fminimizer_set_with_values_MOD(gsl_min_fminimizer *s, - gsl_function *f, - double x_minimum, double f_minimum, - double x_lower, double f_lower, - double x_upper, double f_upper) -{ - s->function = f; - s->x_minimum = x_minimum; - s->x_lower = x_lower; - s->x_upper = x_upper; - if (x_lower > x_upper) - { - GSL_ERROR ("invalid interval (lower > upper)", GSL_EINVAL); - } - s->f_lower = f_lower; - s->f_upper = f_upper; - s->f_minimum = f_minimum; - return (s->type->set) (s->state, s->function, - x_minimum, f_minimum, - x_lower, f_lower, - x_upper, f_upper); -} - -#define MAXITER 100 - -// Returns the minimum betwen ax and cx to a given tolerance tol using -// brent's method. - -double brent(double ax, double bx, double cx, - double (*f) (double), double tol, double *xmin) -{ - // The solver can stall at the following internal tolerance in brent - so - // this is about the lowest possible tolerance. - if(tol == 0.) tol = 10.*GSL_SQRT_DBL_EPSILON; - const double tolsq = tol*tol; - int status; - int iter = 0; - double a, b, c; // a < b < c - double fa, fb, fc; - const gsl_min_fminimizer_type *T; - gsl_min_fminimizer *s; - gsl_function F; - - // gsl wants a<b - b = bx; - if(ax < cx) { - a = ax; - c = cx; - } - else { - a = cx; - c = ax; - } - - nrfunc = f; - F.function = &fn1; - F.params = 0; - - fa = f(a); - fb = f(b); - fc = f(c); - if(fb > fa || fb > fc) { - if(a < c) { - b = a; - fb = fa; - } - else { - b = c; - fb = fc; - } - } - - // if a-c < tol, return func(b) - if(gsl_min_test_interval(a, c, tolsq, tol) == GSL_SUCCESS) { - *xmin = b; - return (fb); - } - - T = gsl_min_fminimizer_brent; - s = gsl_min_fminimizer_alloc(T); -// gsl_min_fminimizer_set(s, &F, b, a, c); // Standard - // This mod avoids some error checks so we can have a minimum at an extent. - gsl_min_fminimizer_set_with_values_MOD(s, &F, b, fb, a, fa, c, fc); - - do { - iter++; - status = gsl_min_fminimizer_iterate(s); - if(status) - break; // solver problem - a = gsl_min_fminimizer_x_lower(s); - c = gsl_min_fminimizer_x_upper(s); -// fb = gsl_min_fminimizer_f_minimum(s); -// fa = gsl_min_fminimizer_f_lower(s); -// fc = gsl_min_fminimizer_f_upper(s); - status = gsl_min_test_interval(a, c, tolsq, tol); - // ... in case curve becomes too flat - not required? -// std::fabs(fa - fc) < (std::fabs(fb) + tol)*tol - } - while(status == GSL_CONTINUE && iter < MAXITER); - b = gsl_min_fminimizer_x_minimum(s); - - if(status != GSL_SUCCESS) - Msg::Error("MIN1D not converged: f(%g) = %g", b, fn1(b, NULL)); - - *xmin = b; - gsl_min_fminimizer_free(s); - return fn1(b, NULL); -} - -#endif diff --git a/Numeric/gsl_min.cpp b/Numeric/gsl_min.cpp deleted file mode 100644 index 4a425567f5..0000000000 --- a/Numeric/gsl_min.cpp +++ /dev/null @@ -1,265 +0,0 @@ -// Gmsh - Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle -// -// See the LICENSE.txt file for license information. Please report all -// bugs and problems to <gmsh@geuz.org>. - -#include "GmshMessage.h" - -#if defined(HAVE_GSL) - -#include "Numeric.h" -#include <gsl/gsl_errno.h> -#include <gsl/gsl_math.h> -#include <gsl/gsl_multimin.h> - -static double (*f_stat) (double, double, void *data); -static void (*df_stat) (double, double, double &, double &, double &, void *data); -static double (*f_stat3) (double, double, double, void *data); -static void (*df_stat3) (double, double, double, double &, double &, double &, double &,void *data); -static double (*f_statN) (double*, void *data); -static void (*df_statN) (double*, double *, double &,void *data); - -double fobj (const gsl_vector * x, void * data){ - double u, v; - u = gsl_vector_get(x, 0); - v = gsl_vector_get(x, 1); - return f_stat(u,v,data); -} - - -double fobj3 (const gsl_vector * x, void * data){ - double u, v,w; - u = gsl_vector_get(x, 0); - v = gsl_vector_get(x, 1); - w = gsl_vector_get(x, 2); - return f_stat3(u,v,w,data); -} - -double fobjN (const gsl_vector * x, void * data){ - return f_statN(x->data,data); -} - -void dfobj (const gsl_vector * x, void * params, gsl_vector * g){ - double u, v, f, duf, dvf; - u = gsl_vector_get(x, 0); - v = gsl_vector_get(x, 1); - df_stat(u,v,f, duf,dvf,params); - gsl_vector_set(g, 0, duf); - gsl_vector_set(g, 1, dvf); -} - -void dfobj3 (const gsl_vector * x, void * params, gsl_vector * g){ - double u, v, w,f, duf, dvf,dwf; - u = gsl_vector_get(x, 0); - v = gsl_vector_get(x, 1); - w = gsl_vector_get(x, 2); - df_stat3(u,v,w,f, duf,dvf,dwf,params); - gsl_vector_set(g, 0, duf); - gsl_vector_set(g, 1, dvf); - gsl_vector_set(g, 2, dwf); -} - -void dfobjN (const gsl_vector * x, void * params, gsl_vector * g){ - double f; - df_statN(x->data, g->data,f,params); -} - -void fdfobj (const gsl_vector * x, void * params, double * f, gsl_vector * g){ - double u, v, duf, dvf; - u = gsl_vector_get(x, 0); - v = gsl_vector_get(x, 1); - df_stat(u,v,*f, duf,dvf,params); - gsl_vector_set(g, 0, duf); - gsl_vector_set(g, 1, dvf); -} - -void fdfobj3 (const gsl_vector * x, void * params, double * f, gsl_vector * g){ - double u, v, w,duf, dvf,dwf; - u = gsl_vector_get(x, 0); - v = gsl_vector_get(x, 1); - w = gsl_vector_get(x, 2); - df_stat3(u,v,w,*f, duf,dvf,dwf,params); - gsl_vector_set(g, 0, duf); - gsl_vector_set(g, 1, dvf); - gsl_vector_set(g, 2, dwf); -} - -void fdfobjN (const gsl_vector * x, void * params, double * f, gsl_vector * g){ - df_statN(x->data,g->data,*f,params); -} - -void minimize_2 ( double (*f) (double, double, void *data), - void (*df) (double, double, double &, double &, double &, void *data) , - void *data,int niter, - double &U, double &V, double &res){ - f_stat = f; - df_stat = df; - - int iter = 0; - int status; - - const gsl_multimin_fdfminimizer_type *T; - gsl_multimin_fdfminimizer *s; - gsl_vector *x; - gsl_multimin_function_fdf my_func; - - my_func.f = &fobj; - my_func.df = &dfobj; - my_func.fdf = &fdfobj; - my_func.n = 2; - my_func.params = data; - - x = gsl_vector_alloc (2); - gsl_vector_set (x, 0, U); - gsl_vector_set (x, 1, V); - - T = gsl_multimin_fdfminimizer_conjugate_fr; - s = gsl_multimin_fdfminimizer_alloc (T, 2); - - gsl_multimin_fdfminimizer_set(s, &my_func, x, 0.01, 1e-4); - - do{ - iter++; - status = gsl_multimin_fdfminimizer_iterate(s); - if(status) - break; - status = gsl_multimin_test_gradient(s->gradient, 1e-3); - } - while (status == GSL_CONTINUE && iter < niter); - - U = gsl_vector_get(s->x, 0); - V = gsl_vector_get(s->x, 1); - res = s->f; - gsl_multimin_fdfminimizer_free (s); - gsl_vector_free (x); -} - -void minimize_3(double (*f) (double, double, double,void *data), - void (*df) (double , double , double , - double &, double &, double &, double &, - void *data) , - void *data,int niter, - double &U, double &V, double &W, double &res) -{ - f_stat3 = f; - df_stat3 = df; - - int iter = 0; - int status; - - const gsl_multimin_fdfminimizer_type *T; - gsl_multimin_fdfminimizer *s; - gsl_vector *x; - gsl_multimin_function_fdf my_func; - - my_func.f = &fobj3; - my_func.df = &dfobj3; - my_func.fdf = &fdfobj3; - my_func.n = 3; - my_func.params = data; - - x = gsl_vector_alloc (3); - gsl_vector_set(x, 0, U); - gsl_vector_set(x, 1, V); - gsl_vector_set(x, 2, W); - - T = gsl_multimin_fdfminimizer_conjugate_fr; - s = gsl_multimin_fdfminimizer_alloc(T, 3); - - gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.01, 1e-4); - - do{ - iter++; - status = gsl_multimin_fdfminimizer_iterate (s); - if (status) - break; - status = gsl_multimin_test_gradient (s->gradient, 1e-3); - } - while (status == GSL_CONTINUE && iter < niter); - - U = gsl_vector_get (s->x, 0); - V = gsl_vector_get (s->x, 1); - W = gsl_vector_get (s->x, 2); - res = s->f; - gsl_multimin_fdfminimizer_free (s); - gsl_vector_free (x); -} - -void minimize_N(int N, - double (*f) (double*,void *data), - void (*df) (double*,double*,double &,void *data) , - void *data,int niter, - double *U, double &res){ - f_statN = f; - df_statN = df; - - int iter = 0; - int status; - - const gsl_multimin_fdfminimizer_type *T; - gsl_multimin_fdfminimizer *s; - gsl_vector *x; - gsl_multimin_function_fdf my_func; - - my_func.f = &fobjN; - my_func.df = &dfobjN; - my_func.fdf = &fdfobjN; - my_func.n = N; - my_func.params = data; - - x = gsl_vector_alloc (N); - for (int i=0;i<N;i++) - gsl_vector_set (x, i, U[i]); - - T = gsl_multimin_fdfminimizer_conjugate_fr; - s = gsl_multimin_fdfminimizer_alloc (T, N); - - gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.01, 1e-4); - - do{ - iter++; - status = gsl_multimin_fdfminimizer_iterate (s); - - if (status) - break; - - status = gsl_multimin_test_gradient (s->gradient, 1e-3); - } - while (status == GSL_CONTINUE && iter < niter); - - for (int i=0;i<N;i++) - U[i] = gsl_vector_get (s->x, i); - res = s->f; - gsl_multimin_fdfminimizer_free (s); - gsl_vector_free (x); - -} - -#else - -void minimize_2 ( double (*f) (double, double, void *data), - void (*df) (double, double, double &, double &, double &, void *data) , - void *data,int niter, - double &U, double &V, double &res) -{ - Msg::Error("Gmsh must be compiled with GSL support for minimize_2"); -} - -void minimize_3 ( double (*f) (double, double, double, void *data), - void (*df) (double, double, double , double &, double &, double &, double &, void *data) , - void *data,int niter, - double &U, double &V, double &W, double &res) -{ - Msg::Error("Gmsh must be compiled with GSL support for minimize_3"); -} - -void minimize_N (int N, - double (*f) (double*, void *data), - void (*df) (double*, double*, double &, void *data) , - void *data,int niter, - double *, double &res) -{ - Msg::Error("Gmsh must be compiled with GSL support for minimize_N"); -} - -#endif diff --git a/Numeric/gsl_newt.cpp b/Numeric/gsl_newt.cpp deleted file mode 100644 index f8dfc1e3ea..0000000000 --- a/Numeric/gsl_newt.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// Gmsh - Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle -// -// See the LICENSE.txt file for license information. Please report all -// bugs and problems to <gmsh@geuz.org>. -// -// Contributor(s): -// Nicolas Tardieu -// - -// This implements a Newton method using the GSL. - -#include "GmshMessage.h" - -#if defined(HAVE_GSL) - -#include "Numeric.h" - -#include <gsl/gsl_math.h> -#include <gsl/gsl_errno.h> -#include <gsl/gsl_multiroots.h> -#include <gsl/gsl_linalg.h> - -#define MAX_DIM_NEWT 10 -#define MAXITER 100 -#define PREC 1.e-8 - -int nrdim; -double nru[MAX_DIM_NEWT], nrv[MAX_DIM_NEWT]; -static void (*nrfunc) (int n, double x[], double y[]); -struct gsl_dummy{ int i; }; - -void convert_vector_from_gsl(const gsl_vector * gv, double *v) -{ - int i, m; - m = gv->size; - for(i = 0; i < m; i++) { - v[i + 1] = gsl_vector_get(gv, i); - } -} - -void convert_vector_to_gsl(double *v, int n, gsl_vector * gv) -{ - int i; - for(i = 0; i < n; i++) { - gsl_vector_set(gv, i, v[i + 1]); - } -} - -int gslfunc(const gsl_vector * xx, void *params, gsl_vector * f) -{ - convert_vector_from_gsl(xx, nru); - (*nrfunc) (nrdim, nru, nrv); - // Msg::Info("f(%lf,%lf) = %lf %lf\n",nru[1],nru[2],nrv[1],nrv[2]); - convert_vector_to_gsl(nrv, nrdim, f); - return GSL_SUCCESS; -} - -// Warning: for compatibility with the old newt from NR, x[] and the -// arguments of func() are indexed from 1 to n... - -void newt(double x[], int n, int *check, - void (*func) (int, double[], double[])) -{ - const gsl_multiroot_fsolver_type *T; - gsl_multiroot_fsolver *s; - int status; - size_t iter = 0; - struct gsl_dummy p = { 1 }; - gsl_multiroot_function f = { &gslfunc, n, &p }; - gsl_vector *xx = gsl_vector_alloc(n); - - if(n > MAX_DIM_NEWT - 1) - Msg::Fatal("Maximum Newton dimension exceeded\n"); - nrdim = n; - - nrfunc = func; - convert_vector_to_gsl(x, n, xx); - - T = gsl_multiroot_fsolver_hybrid; - s = gsl_multiroot_fsolver_alloc(T, n); - gsl_multiroot_fsolver_set(s, &f, xx); - - do { - iter++; - status = gsl_multiroot_fsolver_iterate(s); - // Msg::Info("status %d %d %d %lf %lf\n", - // status,n,iter,gsl_vector_get(s->x,0),gsl_vector_get(s->x,1)); - if(status) - break; // solver problem - status = gsl_multiroot_test_residual(s->f, n * PREC); - } - while(status == GSL_CONTINUE && iter < MAXITER); - - if(status == GSL_CONTINUE) { - *check = 1; // problem !!! - } - else { - // Msg::Info("status %d %d %d %lf %lf\n", - // status,n,iter,gsl_vector_get(s->x,0),gsl_vector_get(s->x,1)); - convert_vector_from_gsl(s->x, x); - *check = 0; // converged - } - - gsl_multiroot_fsolver_free(s); - gsl_vector_free(xx); -} - -#endif diff --git a/Post/Makefile b/Post/Makefile index 36d3fd23bb..8f1f9363a8 100644 --- a/Post/Makefile +++ b/Post/Makefile @@ -126,7 +126,7 @@ adaptiveData${OBJEXT}: adaptiveData.cpp adaptiveData.h ../Numeric/GmshMatrix.h \ ../Common/GmshMessage.h ../Plugin/Plugin.h ../Common/Options.h \ ../Post/ColorTable.h ../Post/PView.h ../Geo/SPoint3.h \ ../Post/PViewDataList.h ../Post/PViewData.h ../Geo/SBoundingBox3d.h \ - ../Geo/SPoint3.h ../Common/ListUtils.h + ../Geo/SPoint3.h ../Common/ListUtils.h ../Common/OS.h OctreePost${OBJEXT}: OctreePost.cpp ../Common/Octree.h \ ../Common/OctreeInternals.h OctreePost.h ../Common/ListUtils.h PView.h \ ../Geo/SPoint3.h PViewDataList.h PViewData.h ../Geo/SBoundingBox3d.h \ diff --git a/configure b/configure index cb2a8f1277..6b661cfdcc 100755 --- a/configure +++ b/configure @@ -1316,7 +1316,8 @@ Optional Packages: --with-mpi-prefix=PFX prefix where MPI is installed --with-fftw3-prefix=PFX prefix where FFTW3 is installed --with-fm-prefix=PFX prefix where FourierModel is installed - --with-blas-prefix=PFX prefix where BLAS (and LAPACK) are installed + --with-blas-lapack-prefix=PFX + prefix where BLAS and LAPACK are installed Some influential environment variables: CC C compiler command @@ -1841,9 +1842,9 @@ if test "${with_fm_prefix+set}" = set; then fi -# Check whether --with-blas-prefix was given. -if test "${with_blas_prefix+set}" = set; then - withval=$with_blas_prefix; BLAS_PREFIX=$withval +# Check whether --with-blas-lapack-prefix was given. +if test "${with_blas_lapack_prefix+set}" = set; then + withval=$with_blas_lapack_prefix; BLAS_LAPACK_PREFIX=$withval fi @@ -5128,43 +5129,6 @@ fi fi fi fi -if test "x${GSL}" != "xyes"; then - { echo "$as_me:$LINENO: checking for ./contrib/NR/dsvdcmp.cpp" >&5 -echo $ECHO_N "checking for ./contrib/NR/dsvdcmp.cpp... $ECHO_C" >&6; } -if test "${ac_cv_file___contrib_NR_dsvdcmp_cpp+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - test "$cross_compiling" = yes && - { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 -echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} - { (exit 1); exit 1; }; } -if test -r "./contrib/NR/dsvdcmp.cpp"; then - ac_cv_file___contrib_NR_dsvdcmp_cpp=yes -else - ac_cv_file___contrib_NR_dsvdcmp_cpp=no -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_file___contrib_NR_dsvdcmp_cpp" >&5 -echo "${ECHO_T}$ac_cv_file___contrib_NR_dsvdcmp_cpp" >&6; } -if test $ac_cv_file___contrib_NR_dsvdcmp_cpp = yes; then - NR="yes" -fi - - if test "x${NR}" = "xyes"; then - GMSH_DIRS="${GMSH_DIRS} contrib/NR" - GMSH_LIBS="${GMSH_LIBS} -lGmshNR" - echo "********************************************************************" - echo " You are building a non-free version of Gmsh, using code copyright" - echo " (C) 1986-92 Numerical Recipes Software." - echo " To use the GSL instead, run configure again with the --enable-gsl" - echo " option." - echo "********************************************************************" - else - { { echo "$as_me:$LINENO: error: Could not find GSL, aborting." >&5 -echo "$as_me: error: Could not find GSL, aborting." >&2;} - { (exit 1); exit 1; }; } - fi -fi if test "x$enable_fm" != "xno"; then if test "x${FM_PREFIX}" != "x"; then @@ -5316,8 +5280,8 @@ echo "$as_me: WARNING: Could not find FFTW3: disabling FourierModel." >&2;} fi fi -if test "x${BLAS_PREFIX}" != "x"; then - LDFLAGS="-L${BLAS_PREFIX} -L${BLAS_PREFIX}/lib ${LDFLAGS}" +if test "x${BLAS_LAPACK_PREFIX}" != "x"; then + LDFLAGS="-L${BLAS_LAPACK_PREFIX} -L${BLAS_LAPACK_PREFIX}/lib ${LDFLAGS}" fi { echo "$as_me:$LINENO: checking for cblas_dgemm in -lcblas" >&5 echo $ECHO_N "checking for cblas_dgemm in -lcblas... $ECHO_C" >&6; } @@ -5452,8 +5416,8 @@ fi fi if test "x${CBLAS}" = "xyes"; then - if test "x${BLAS_PREFIX}" != "x"; then - BLAS_PATH="-L${BLAS_PREFIX} -L${BLAS_PREFIX}/lib" + if test "x${BLAS_LAPACK_PREFIX}" != "x"; then + BLAS_PATH="-L${BLAS_LAPACK_PREFIX} -L${BLAS_LAPACK_PREFIX}/lib" fi FLAGS="${FLAGS} -DHAVE_CBLAS" else @@ -5463,7 +5427,7 @@ else fi fi -if test "x${FM}" = "xyes"; then +if test "x${FM}" = "xyes" -o "x${GSL}" != "xyes"; then ac_ext=f ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' diff --git a/configure.in b/configure.in index 296cb4a024..3f7eb290f4 100644 --- a/configure.in +++ b/configure.in @@ -69,10 +69,10 @@ AC_ARG_WITH(fm-prefix, AC_HELP_STRING([--with-fm-prefix=PFX], [prefix where FourierModel is installed]), [FM_PREFIX=$withval]) -AC_ARG_WITH(blas-prefix, - AC_HELP_STRING([--with-blas-prefix=PFX], - [prefix where BLAS (and LAPACK) are installed]), - [BLAS_PREFIX=$withval]) +AC_ARG_WITH(blas-lapack-prefix, + AC_HELP_STRING([--with-blas-lapack-prefix=PFX], + [prefix where BLAS and LAPACK are installed]), + [BLAS_LAPACK_PREFIX=$withval]) dnl Parse '--enable' command line options AC_ARG_ENABLE(gsl, @@ -667,22 +667,6 @@ if test "x$enable_gsl" != "xno"; then fi fi fi -if test "x${GSL}" != "xyes"; then - dnl Check if non-free numerical recipes routines are in the tree - AC_CHECK_FILE(./contrib/NR/dsvdcmp.cpp,NR="yes") - if test "x${NR}" = "xyes"; then - GMSH_DIRS="${GMSH_DIRS} contrib/NR" - GMSH_LIBS="${GMSH_LIBS} -lGmshNR" - echo "********************************************************************" - echo " You are building a non-free version of Gmsh, using code copyright" - echo " (C) 1986-92 Numerical Recipes Software." - echo " To use the GSL instead, run configure again with the --enable-gsl" - echo " option." - echo "********************************************************************" - else - AC_MSG_ERROR([Could not find GSL, aborting.]) - fi -fi dnl Check for FourierModel if test "x$enable_fm" != "xno"; then @@ -718,16 +702,16 @@ if test "x$enable_fm" != "xno"; then fi dnl Check for C version of BLAS -if test "x${BLAS_PREFIX}" != "x"; then - LDFLAGS="-L${BLAS_PREFIX} -L${BLAS_PREFIX}/lib ${LDFLAGS}" +if test "x${BLAS_LAPACK_PREFIX}" != "x"; then + LDFLAGS="-L${BLAS_LAPACK_PREFIX} -L${BLAS_LAPACK_PREFIX}/lib ${LDFLAGS}" fi AC_CHECK_LIB(cblas,cblas_dgemm,CBLAS="yes" BLAS_LIBS="-lcblas") if test "x${CBLAS}" != "xyes"; then AC_CHECK_LIB(cblas,cblas_dgemm,CBLAS="yes" BLAS_LIBS="-lcblas -latlas",[],-latlas) fi if test "x${CBLAS}" = "xyes"; then - if test "x${BLAS_PREFIX}" != "x"; then - BLAS_PATH="-L${BLAS_PREFIX} -L${BLAS_PREFIX}/lib" + if test "x${BLAS_LAPACK_PREFIX}" != "x"; then + BLAS_PATH="-L${BLAS_LAPACK_PREFIX} -L${BLAS_LAPACK_PREFIX}/lib" fi FLAGS="${FLAGS} -DHAVE_CBLAS" else @@ -738,9 +722,9 @@ else fi fi -dnl Check for Fortran version of blas and lapack (only used in -dnl FourierModel at the moment) -if test "x${FM}" = "xyes"; then +dnl Check for Fortran version of blas and lapack (only used when not +dnl using GSL, or of FourierModel is linked in) +if test "x${FM}" = "xyes" -o "x${GSL}" != "xyes"; then AC_PROG_F77 case "${F77}" in *gfortran*) diff --git a/contrib/NR/Makefile b/contrib/NR/Makefile deleted file mode 100644 index a56f425626..0000000000 --- a/contrib/NR/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# Gmsh - Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle -# -# See the LICENSE.txt file for license information. Please report all -# bugs and problems to <gmsh@geuz.org>. - -include ../../variables - -LIB = ../../lib/libGmshNR${LIBEXT} - -INC = ${DASH}I../../Common ${DASH}I. - -# don't optimize this library: there are some problems with gcc... -CFLAGS = ${FLAGS} ${INC} - -SRC = brent.cpp\ - dpythag.cpp\ - dsvdcmp.cpp\ - fdjac.cpp\ - fmin.cpp\ - lnsrch.cpp\ - lubksb.cpp\ - ludcmp.cpp\ - newt.cpp\ - nrutil.cpp - -OBJ = ${SRC:.cpp=${OBJEXT}} - -.SUFFIXES: ${OBJEXT} .cpp - -${LIB}: ${OBJ} - ${AR} ${ARFLAGS}${LIB} ${OBJ} - ${RANLIB} ${LIB} - -cpobj: ${OBJ} - cp -f ${OBJ} ../../lib/ - -.cpp${OBJEXT}: - ${CXX} ${CFLAGS} ${DASH}c $< - -clean: - ${RM} *.o *.obj - -depend: - (sed '/^# DO NOT DELETE THIS LINE/q' Makefile && \ - ${CXX} -MM ${CFLAGS} ${SRC} | sed 's/.o:/$${OBJEXT}:/g' \ - ) > Makefile.new - cp Makefile Makefile.bak - cp Makefile.new Makefile - rm -f Makefile.new - -# DO NOT DELETE THIS LINE -brent${OBJEXT}: brent.cpp nrutil.h -dpythag${OBJEXT}: dpythag.cpp nrutil.h -dsvdcmp${OBJEXT}: dsvdcmp.cpp nrutil.h -fdjac${OBJEXT}: fdjac.cpp nrutil.h -fmin${OBJEXT}: fmin.cpp nrutil.h -lnsrch${OBJEXT}: lnsrch.cpp nrutil.h -lubksb${OBJEXT}: lubksb.cpp -ludcmp${OBJEXT}: ludcmp.cpp nrutil.h -newt${OBJEXT}: newt.cpp nrutil.h -nrutil${OBJEXT}: nrutil.cpp ../../Common/GmshMessage.h diff --git a/contrib/NR/brent.cpp b/contrib/NR/brent.cpp deleted file mode 100644 index 8dc82e8813..0000000000 --- a/contrib/NR/brent.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" -#define ITMAX 100 -#define CGOLD 0.3819660 -#define ZEPS 1.0e-10 -#define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d); - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -double brent(double ax, double bx, double cx, double (*f)(double), double tol, - double *xmin) -{ - int iter; - double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; - double e=0.0; - - a=(ax < cx ? ax : cx); - b=(ax > cx ? ax : cx); - x=w=v=bx; - fw=fv=fx=(*f)(x); - for (iter=1;iter<=ITMAX;iter++) { - xm=0.5*(a+b); - tol2=2.0*(tol1=tol*fabs(x)+ZEPS); - if (fabs(x-xm) <= (tol2-0.5*(b-a))) { - *xmin=x; - return fx; - } - if (fabs(e) > tol1) { - r=(x-w)*(fx-fv); - q=(x-v)*(fx-fw); - p=(x-v)*q-(x-w)*r; - q=2.0*(q-r); - if (q > 0.0) p = -p; - q=fabs(q); - etemp=e; - e=d; - if (fabs(p) >= fabs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) - d=CGOLD*(e=(x >= xm ? a-x : b-x)); - else { - d=p/q; - u=x+d; - if (u-a < tol2 || b-u < tol2) - d=SIGN(tol1,xm-x); - } - } else { - d=CGOLD*(e=(x >= xm ? a-x : b-x)); - } - u=(fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); - fu=(*f)(u); - if (fu <= fx) { - if (u >= x) a=x; else b=x; - SHFT(v,w,x,u) - SHFT(fv,fw,fx,fu) - } else { - if (u < x) a=u; else b=u; - if (fu <= fw || w == x) { - v=w; - w=u; - fv=fw; - fw=fu; - } else if (fu <= fv || v == x || v == w) { - v=u; - fv=fu; - } - } - } - nrerror("Too many iterations in brent"); - *xmin=x; - return fx; -} -#undef ITMAX -#undef CGOLD -#undef ZEPS -#undef SHFT -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/contrib/NR/dpythag.cpp b/contrib/NR/dpythag.cpp deleted file mode 100644 index 4585295c43..0000000000 --- a/contrib/NR/dpythag.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" - -double dpythag(double a, double b) -{ - double absa,absb; - absa=fabs(a); - absb=fabs(b); - if (absa > absb) return absa*sqrt(1.0+DSQR(absb/absa)); - else return (absb == 0.0 ? 0.0 : absb*sqrt(1.0+DSQR(absa/absb))); -} -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/contrib/NR/dsvdcmp.cpp b/contrib/NR/dsvdcmp.cpp deleted file mode 100644 index 81317ec7db..0000000000 --- a/contrib/NR/dsvdcmp.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" - -void dsvdcmp(double **a, int m, int n, double w[], double **v) -{ - double dpythag(double a, double b); - int flag,i,its,j,jj,k,l,nm; - double anorm,c,f,g,h,s,scale,x,y,z,*rv1; - - rv1=dvector(1,n); - g=scale=anorm=0.0; - for (i=1;i<=n;i++) { - l=i+1; - rv1[i]=scale*g; - g=s=scale=0.0; - if (i <= m) { - for (k=i;k<=m;k++) scale += fabs(a[k][i]); - if (scale) { - for (k=i;k<=m;k++) { - a[k][i] /= scale; - s += a[k][i]*a[k][i]; - } - f=a[i][i]; - g = -SIGN(sqrt(s),f); - h=f*g-s; - a[i][i]=f-g; - for (j=l;j<=n;j++) { - for (s=0.0,k=i;k<=m;k++) s += a[k][i]*a[k][j]; - f=s/h; - for (k=i;k<=m;k++) a[k][j] += f*a[k][i]; - } - for (k=i;k<=m;k++) a[k][i] *= scale; - } - } - w[i]=scale *g; - g=s=scale=0.0; - if (i <= m && i != n) { - for (k=l;k<=n;k++) scale += fabs(a[i][k]); - if (scale) { - for (k=l;k<=n;k++) { - a[i][k] /= scale; - s += a[i][k]*a[i][k]; - } - f=a[i][l]; - g = -SIGN(sqrt(s),f); - h=f*g-s; - a[i][l]=f-g; - for (k=l;k<=n;k++) rv1[k]=a[i][k]/h; - for (j=l;j<=m;j++) { - for (s=0.0,k=l;k<=n;k++) s += a[j][k]*a[i][k]; - for (k=l;k<=n;k++) a[j][k] += s*rv1[k]; - } - for (k=l;k<=n;k++) a[i][k] *= scale; - } - } - anorm=DMAX(anorm,(fabs(w[i])+fabs(rv1[i]))); - } - for (i=n;i>=1;i--) { - if (i < n) { - if (g) { - for (j=l;j<=n;j++) v[j][i]=(a[i][j]/a[i][l])/g; - for (j=l;j<=n;j++) { - for (s=0.0,k=l;k<=n;k++) s += a[i][k]*v[k][j]; - for (k=l;k<=n;k++) v[k][j] += s*v[k][i]; - } - } - for (j=l;j<=n;j++) v[i][j]=v[j][i]=0.0; - } - v[i][i]=1.0; - g=rv1[i]; - l=i; - } - for (i=IMIN(m,n);i>=1;i--) { - l=i+1; - g=w[i]; - for (j=l;j<=n;j++) a[i][j]=0.0; - if (g) { - g=1.0/g; - for (j=l;j<=n;j++) { - for (s=0.0,k=l;k<=m;k++) s += a[k][i]*a[k][j]; - f=(s/a[i][i])*g; - for (k=i;k<=m;k++) a[k][j] += f*a[k][i]; - } - for (j=i;j<=m;j++) a[j][i] *= g; - } else for (j=i;j<=m;j++) a[j][i]=0.0; - ++a[i][i]; - } - for (k=n;k>=1;k--) { - for (its=1;its<=30;its++) { - flag=1; - for (l=k;l>=1;l--) { - nm=l-1; - if ((double)(fabs(rv1[l])+anorm) == anorm) { - flag=0; - break; - } - if ((double)(fabs(w[nm])+anorm) == anorm) break; - } - if (flag) { - c=0.0; - s=1.0; - for (i=l;i<=k;i++) { - f=s*rv1[i]; - rv1[i]=c*rv1[i]; - if ((double)(fabs(f)+anorm) == anorm) break; - g=w[i]; - h=dpythag(f,g); - w[i]=h; - h=1.0/h; - c=g*h; - s = -f*h; - for (j=1;j<=m;j++) { - y=a[j][nm]; - z=a[j][i]; - a[j][nm]=y*c+z*s; - a[j][i]=z*c-y*s; - } - } - } - z=w[k]; - if (l == k) { - if (z < 0.0) { - w[k] = -z; - for (j=1;j<=n;j++) v[j][k] = -v[j][k]; - } - break; - } - if (its == 30) nrerror("no convergence in 30 dsvdcmp iterations"); - x=w[l]; - nm=k-1; - y=w[nm]; - g=rv1[nm]; - h=rv1[k]; - f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); - g=dpythag(f,1.0); - f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x; - c=s=1.0; - for (j=l;j<=nm;j++) { - i=j+1; - g=rv1[i]; - y=w[i]; - h=s*g; - g=c*g; - z=dpythag(f,h); - rv1[j]=z; - c=f/z; - s=h/z; - f=x*c+g*s; - g = g*c-x*s; - h=y*s; - y *= c; - for (jj=1;jj<=n;jj++) { - x=v[jj][j]; - z=v[jj][i]; - v[jj][j]=x*c+z*s; - v[jj][i]=z*c-x*s; - } - z=dpythag(f,h); - w[j]=z; - if (z) { - z=1.0/z; - c=f*z; - s=h*z; - } - f=c*g+s*y; - x=c*y-s*g; - for (jj=1;jj<=m;jj++) { - y=a[jj][j]; - z=a[jj][i]; - a[jj][j]=y*c+z*s; - a[jj][i]=z*c-y*s; - } - } - rv1[l]=0.0; - rv1[k]=f; - w[k]=x; - } - } - free_dvector(rv1,1,n); -} -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/contrib/NR/fdjac.cpp b/contrib/NR/fdjac.cpp deleted file mode 100644 index 7767ff1bc4..0000000000 --- a/contrib/NR/fdjac.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" -#define EPS 1.0e-4 - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -void fdjac(int n, double x[], double fvec[], double **df, - void (*vecfunc)(int, double [], double [])) -{ - int i,j; - double h,temp,*f; - - f=dvector(1,n); - for (j=1;j<=n;j++) { - temp=x[j]; - h=EPS*fabs(temp); - if (h == 0.0) h=EPS; - x[j]=temp+h; - h=x[j]-temp; - (*vecfunc)(n,x,f); - x[j]=temp; - for (i=1;i<=n;i++) df[i][j]=(f[i]-fvec[i])/h; - } - free_dvector(f,1,n); -} -#undef EPS -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/contrib/NR/fmin.cpp b/contrib/NR/fmin.cpp deleted file mode 100644 index f461aa7a05..0000000000 --- a/contrib/NR/fmin.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#define NRANSI -#include "nrutil.h" - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -extern int nn; -extern double *fvec; -extern void (*nrfuncv)(int n, double v[], double f[]); - -double fmin(double x[]) -{ - int i; - double sum; - - (*nrfuncv)(nn,x,fvec); - for (sum=0.0,i=1;i<=nn;i++) sum += SQR(fvec[i]); - return 0.5*sum; -} -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/contrib/NR/lnsrch.cpp b/contrib/NR/lnsrch.cpp deleted file mode 100644 index e4a5346a5f..0000000000 --- a/contrib/NR/lnsrch.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" -#define ALF 1.0e-4 -#define TOLX 1.0e-7 - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -void lnsrch(int n, double xold[], double fold, double g[], double p[], double x[], - double *f, double stpmax, int *check, double (*func)(double [])) -{ - int i; - double a,alam,alam2,alamin,b,disc,f2,fold2,rhs1,rhs2,slope,sum,temp, - test,tmplam; - - *check=0; - for (sum=0.0,i=1;i<=n;i++) sum += p[i]*p[i]; - sum=sqrt(sum); - if (sum > stpmax) - for (i=1;i<=n;i++) p[i] *= stpmax/sum; - for (slope=0.0,i=1;i<=n;i++) - slope += g[i]*p[i]; - test=0.0; - for (i=1;i<=n;i++) { - temp=fabs(p[i])/FMAX(fabs(xold[i]),1.0); - if (temp > test) test=temp; - } - alamin=TOLX/test; - alam=1.0; - for (;;) { - for (i=1;i<=n;i++) x[i]=xold[i]+alam*p[i]; - *f=(*func)(x); - if (alam < alamin) { - for (i=1;i<=n;i++) x[i]=xold[i]; - *check=1; - return; - } else if (*f <= fold+ALF*alam*slope) return; - else { - if (alam == 1.0) - tmplam = -slope/(2.0*(*f-fold-slope)); - else { - rhs1 = *f-fold-alam*slope; - rhs2=f2-fold2-alam2*slope; - a=(rhs1/(alam*alam)-rhs2/(alam2*alam2))/(alam-alam2); - b=(-alam2*rhs1/(alam*alam)+alam*rhs2/(alam2*alam2))/(alam-alam2); - if (a == 0.0) tmplam = -slope/(2.0*b); - else { - disc=b*b-3.0*a*slope; - if (disc<0.0) nrerror("Roundoff problem in lnsrch."); - else tmplam=(-b+sqrt(disc))/(3.0*a); - } - if (tmplam>0.5*alam) - tmplam=0.5*alam; - } - } - alam2=alam; - f2 = *f; - fold2=fold; - alam=FMAX(tmplam,0.1*alam); - } -} -#undef ALF -#undef TOLX -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/contrib/NR/lubksb.cpp b/contrib/NR/lubksb.cpp deleted file mode 100644 index 202c826e2f..0000000000 --- a/contrib/NR/lubksb.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* This file has been modified for inclusion in Gmsh (float->double) */ - -void lubksb(double **a, int n, int *indx, double b[]) -{ - int i,ii=0,ip,j; - double sum; - - for (i=1;i<=n;i++) { - ip=indx[i]; - sum=b[ip]; - b[ip]=b[i]; - if (ii) - for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j]; - else if (sum) ii=i; - b[i]=sum; - } - for (i=n;i>=1;i--) { - sum=b[i]; - for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j]; - b[i]=sum/a[i][i]; - } -} -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/contrib/NR/ludcmp.cpp b/contrib/NR/ludcmp.cpp deleted file mode 100644 index 8f4e0c17fc..0000000000 --- a/contrib/NR/ludcmp.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" -#define TINY 1.0e-20; - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -void ludcmp(double **a, int n, int *indx, double *d) -{ - int i,imax,j,k; - double big,dum,sum,temp; - double *vv; - - vv=dvector(1,n); - *d=1.0; - for (i=1;i<=n;i++) { - big=0.0; - for (j=1;j<=n;j++) - if ((temp=fabs(a[i][j])) > big) big=temp; - if (big == 0.0) nrerror("Singular matrix in routine ludcmp"); - vv[i]=1.0/big; - } - for (j=1;j<=n;j++) { - for (i=1;i<j;i++) { - sum=a[i][j]; - for (k=1;k<i;k++) sum -= a[i][k]*a[k][j]; - a[i][j]=sum; - } - big=0.0; - for (i=j;i<=n;i++) { - sum=a[i][j]; - for (k=1;k<j;k++) - sum -= a[i][k]*a[k][j]; - a[i][j]=sum; - if ( (dum=vv[i]*fabs(sum)) >= big) { - big=dum; - imax=i; - } - } - if (j != imax) { - for (k=1;k<=n;k++) { - dum=a[imax][k]; - a[imax][k]=a[j][k]; - a[j][k]=dum; - } - *d = -(*d); - vv[imax]=vv[j]; - } - indx[j]=imax; - if (a[j][j] == 0.0) a[j][j]=TINY; - if (j != n) { - dum=1.0/(a[j][j]); - for (i=j+1;i<=n;i++) a[i][j] *= dum; - } - } - free_dvector(vv,1,n); -} -#undef TINY -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/contrib/NR/mnbrak.cpp b/contrib/NR/mnbrak.cpp deleted file mode 100644 index 9aedccc886..0000000000 --- a/contrib/NR/mnbrak.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" -#define GOLD 1.618034 -#define GLIMIT 100.0 -#define TINY 1.0e-20 -#define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d); - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -void mnbrak(double *ax, double *bx, double *cx, double *fa, double *fb, double *fc, - double (*func)(double)) -{ - double ulim,u,r,q,fu,dum; - - *fa=(*func)(*ax); - *fb=(*func)(*bx); - if (*fb > *fa) { - SHFT(dum,*ax,*bx,dum) - SHFT(dum,*fb,*fa,dum) - } - *cx=(*bx)+GOLD*(*bx-*ax); - *fc=(*func)(*cx); - while (*fb > *fc) { - r=(*bx-*ax)*(*fb-*fc); - q=(*bx-*cx)*(*fb-*fa); - u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/ - (2.0*SIGN(FMAX(fabs(q-r),TINY),q-r)); - ulim=(*bx)+GLIMIT*(*cx-*bx); - if ((*bx-u)*(u-*cx) > 0.0) { - fu=(*func)(u); - if (fu < *fc) { - *ax=(*bx); - *bx=u; - *fa=(*fb); - *fb=fu; - return; - } else if (fu > *fb) { - *cx=u; - *fc=fu; - return; - } - u=(*cx)+GOLD*(*cx-*bx); - fu=(*func)(u); - } else if ((*cx-u)*(u-ulim) > 0.0) { - fu=(*func)(u); - if (fu < *fc) { - SHFT(*bx,*cx,u,*cx+GOLD*(*cx-*bx)) - SHFT(*fb,*fc,fu,(*func)(u)) - } - } else if ((u-ulim)*(ulim-*cx) >= 0.0) { - u=ulim; - fu=(*func)(u); - } else { - u=(*cx)+GOLD*(*cx-*bx); - fu=(*func)(u); - } - SHFT(*ax,*bx,*cx,u) - SHFT(*fa,*fb,*fc,fu) - } -} -#undef GOLD -#undef GLIMIT -#undef TINY -#undef SHFT -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/contrib/NR/newt.cpp b/contrib/NR/newt.cpp deleted file mode 100644 index b09482177e..0000000000 --- a/contrib/NR/newt.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" -#define MAXITS 200 -#define TOLF 1.0e-4 -#define TOLMIN 1.0e-6 -#define TOLX 1.0e-7 -#define STPMX 100.0 - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -int nn; -double *fvec; -void (*nrfuncv)(int n, double v[], double f[]); -#define FREERETURN {free_dvector(fvec,1,n);free_dvector(xold,1,n);\ - free_dvector(p,1,n);free_dvector(g,1,n);free_dmatrix(fjac,1,n,1,n);\ - free_ivector(indx,1,n);return;} - -void newt(double x[], int n, int *check, - void (*vecfunc)(int, double [], double [])) -{ - void fdjac(int n, double x[], double fvec[], double **df, - void (*vecfunc)(int, double [], double [])); - double fmin(double x[]); - void lnsrch(int n, double xold[], double fold, double g[], double p[], double x[], - double *f, double stpmax, int *check, double (*func)(double [])); - void lubksb(double **a, int n, int *indx, double b[]); - void ludcmp(double **a, int n, int *indx, double *d); - int i,its,j,*indx; - double d,den,f,fold,stpmax,sum,temp,test,**fjac,*g,*p,*xold; - - indx=ivector(1,n); - fjac=dmatrix(1,n,1,n); - g=dvector(1,n); - p=dvector(1,n); - xold=dvector(1,n); - fvec=dvector(1,n); - nn=n; - nrfuncv=vecfunc; - f=fmin(x); - test=0.0; - for (i=1;i<=n;i++) - if (fabs(fvec[i]) > test) test=fabs(fvec[i]); - if (test<0.01*TOLF) FREERETURN - for (sum=0.0,i=1;i<=n;i++) sum += SQR(x[i]); - stpmax=STPMX*FMAX(sqrt(sum),(double)n); - for (its=1;its<=MAXITS;its++) { - fdjac(n,x,fvec,fjac,vecfunc); - for (i=1;i<=n;i++) { - for (sum=0.0,j=1;j<=n;j++) sum += fjac[j][i]*fvec[j]; - g[i]=sum; - } - for (i=1;i<=n;i++) xold[i]=x[i]; - fold=f; - for (i=1;i<=n;i++) p[i] = -fvec[i]; - ludcmp(fjac,n,indx,&d); - lubksb(fjac,n,indx,p); - lnsrch(n,xold,fold,g,p,x,&f,stpmax,check,fmin); - test=0.0; - for (i=1;i<=n;i++) - if (fabs(fvec[i]) > test) test=fabs(fvec[i]); - if (test < TOLF) { - *check=0; - FREERETURN - } - if (*check) { - test=0.0; - den=FMAX(f,0.5*n); - for (i=1;i<=n;i++) { - temp=fabs(g[i])*FMAX(fabs(x[i]),1.0)/den; - if (temp > test) test=temp; - } - *check=(test < TOLMIN ? 1 : 0); - FREERETURN - } - test=0.0; - for (i=1;i<=n;i++) { - temp=(fabs(x[i]-xold[i]))/FMAX(fabs(x[i]),1.0); - if (temp > test) test=temp; - } - if (test < TOLX) FREERETURN - } - nrerror("MAXITS exceeded in newt"); -} -#undef MAXITS -#undef TOLF -#undef TOLMIN -#undef TOLX -#undef STPMX -#undef FREERETURN -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/contrib/NR/nrutil.cpp b/contrib/NR/nrutil.cpp deleted file mode 100644 index 0666bc287a..0000000000 --- a/contrib/NR/nrutil.cpp +++ /dev/null @@ -1,293 +0,0 @@ -// This file has been modified for inclusion in Gmsh - -#include <stdio.h> -#include <stddef.h> -#include <stdlib.h> -#include "GmshMessage.h" - -#define NR_END 1 -#define FREE_ARG char* - -void nrerror(char error_text[]) -/* Numerical Recipes standard error handler */ -{ - Msg::Error("%s", error_text); - /* - fprintf(stderr,"Numerical Recipes run-time error...\n"); - fprintf(stderr,"%s\n",error_text); - fprintf(stderr,"...now exiting to system...\n"); - exit(1); - */ -} - -float *vector(long nl, long nh) -/* allocate a float vector with subscript range v[nl..nh] */ -{ - float *v; - - v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float))); - if (!v) nrerror("allocation failure in vector()"); - return v-nl+NR_END; -} - -int *ivector(long nl, long nh) -/* allocate an int vector with subscript range v[nl..nh] */ -{ - int *v; - - v=(int *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(int))); - if (!v) nrerror("allocation failure in ivector()"); - return v-nl+NR_END; -} - -unsigned char *cvector(long nl, long nh) -/* allocate an unsigned char vector with subscript range v[nl..nh] */ -{ - unsigned char *v; - - v=(unsigned char *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(unsigned char))); - if (!v) nrerror("allocation failure in cvector()"); - return v-nl+NR_END; -} - -unsigned long *lvector(long nl, long nh) -/* allocate an unsigned long vector with subscript range v[nl..nh] */ -{ - unsigned long *v; - - v=(unsigned long *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(long))); - if (!v) nrerror("allocation failure in lvector()"); - return v-nl+NR_END; -} - -double *dvector(long nl, long nh) -/* allocate a double vector with subscript range v[nl..nh] */ -{ - double *v; - - v=(double *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(double))); - if (!v) nrerror("allocation failure in dvector()"); - return v-nl+NR_END; -} - -float **matrix(long nrl, long nrh, long ncl, long nch) -/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */ -{ - long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; - float **m; - - /* allocate pointers to rows */ - m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*))); - if (!m) nrerror("allocation failure 1 in matrix()"); - m += NR_END; - m -= nrl; - - /* allocate rows and set pointers to them */ - m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float))); - if (!m[nrl]) nrerror("allocation failure 2 in matrix()"); - m[nrl] += NR_END; - m[nrl] -= ncl; - - for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol; - - /* return pointer to array of pointers to rows */ - return m; -} - -double **dmatrix(long nrl, long nrh, long ncl, long nch) -/* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */ -{ - long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; - double **m; - - /* allocate pointers to rows */ - m=(double **) malloc((size_t)((nrow+NR_END)*sizeof(double*))); - if (!m) nrerror("allocation failure 1 in matrix()"); - m += NR_END; - m -= nrl; - - /* allocate rows and set pointers to them */ - m[nrl]=(double *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double))); - if (!m[nrl]) nrerror("allocation failure 2 in matrix()"); - m[nrl] += NR_END; - m[nrl] -= ncl; - - for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol; - - /* return pointer to array of pointers to rows */ - return m; -} - -int **imatrix(long nrl, long nrh, long ncl, long nch) -/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */ -{ - long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; - int **m; - - /* allocate pointers to rows */ - m=(int **) malloc((size_t)((nrow+NR_END)*sizeof(int*))); - if (!m) nrerror("allocation failure 1 in matrix()"); - m += NR_END; - m -= nrl; - - - /* allocate rows and set pointers to them */ - m[nrl]=(int *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(int))); - if (!m[nrl]) nrerror("allocation failure 2 in matrix()"); - m[nrl] += NR_END; - m[nrl] -= ncl; - - for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol; - - /* return pointer to array of pointers to rows */ - return m; -} - -float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch, - long newrl, long newcl) -/* point a submatrix [newrl..][newcl..] to a[oldrl..oldrh][oldcl..oldch] */ -{ - long i,j,nrow=oldrh-oldrl+1,ncol=oldcl-newcl; - float **m; - - /* allocate array of pointers to rows */ - m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*))); - if (!m) nrerror("allocation failure in submatrix()"); - m += NR_END; - m -= newrl; - - /* set pointers to rows */ - for(i=oldrl,j=newrl;i<=oldrh;i++,j++) m[j]=a[i]+ncol; - - /* return pointer to array of pointers to rows */ - return m; -} - -float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch) -/* allocate a float matrix m[nrl..nrh][ncl..nch] that points to the matrix -declared in the standard C manner as a[nrow][ncol], where nrow=nrh-nrl+1 -and ncol=nch-ncl+1. The routine should be called with the address -&a[0][0] as the first argument. */ -{ - long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1; - float **m; - - /* allocate pointers to rows */ - m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*))); - if (!m) nrerror("allocation failure in convert_matrix()"); - m += NR_END; - m -= nrl; - - /* set pointers to rows */ - m[nrl]=a-ncl; - for(i=1,j=nrl+1;i<nrow;i++,j++) m[j]=m[j-1]+ncol; - /* return pointer to array of pointers to rows */ - return m; -} - -float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh) -/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */ -{ - long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1; - float ***t; - - /* allocate pointers to pointers to rows */ - t=(float ***) malloc((size_t)((nrow+NR_END)*sizeof(float**))); - if (!t) nrerror("allocation failure 1 in f3tensor()"); - t += NR_END; - t -= nrl; - - /* allocate pointers to rows and set pointers to them */ - t[nrl]=(float **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float*))); - if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()"); - t[nrl] += NR_END; - t[nrl] -= ncl; - - /* allocate rows and set pointers to them */ - t[nrl][ncl]=(float *) malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(float))); - if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()"); - t[nrl][ncl] += NR_END; - t[nrl][ncl] -= ndl; - - for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep; - for(i=nrl+1;i<=nrh;i++) { - t[i]=t[i-1]+ncol; - t[i][ncl]=t[i-1][ncl]+ncol*ndep; - for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep; - } - - /* return pointer to array of pointers to rows */ - return t; -} - -void free_vector(float *v, long nl, long nh) -/* free a float vector allocated with vector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_ivector(int *v, long nl, long nh) -/* free an int vector allocated with ivector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_cvector(unsigned char *v, long nl, long nh) -/* free an unsigned char vector allocated with cvector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_lvector(unsigned long *v, long nl, long nh) -/* free an unsigned long vector allocated with lvector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_dvector(double *v, long nl, long nh) -/* free a double vector allocated with dvector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_matrix(float **m, long nrl, long nrh, long ncl, long nch) -/* free a float matrix allocated by matrix() */ -{ - free((FREE_ARG) (m[nrl]+ncl-NR_END)); - free((FREE_ARG) (m+nrl-NR_END)); -} - -void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch) -/* free a double matrix allocated by dmatrix() */ -{ - free((FREE_ARG) (m[nrl]+ncl-NR_END)); - free((FREE_ARG) (m+nrl-NR_END)); -} - -void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch) -/* free an int matrix allocated by imatrix() */ -{ - free((FREE_ARG) (m[nrl]+ncl-NR_END)); - free((FREE_ARG) (m+nrl-NR_END)); -} - -void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch) -/* free a submatrix allocated by submatrix() */ -{ - free((FREE_ARG) (b+nrl-NR_END)); -} - -void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch) -/* free a matrix allocated by convert_matrix() */ -{ - free((FREE_ARG) (b+nrl-NR_END)); -} - -void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch, - long ndl, long ndh) -/* free a float f3tensor allocated by f3tensor() */ -{ - free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END)); - free((FREE_ARG) (t[nrl]+ncl-NR_END)); - free((FREE_ARG) (t+nrl-NR_END)); -} diff --git a/contrib/NR/nrutil.h b/contrib/NR/nrutil.h deleted file mode 100644 index 25aa402060..0000000000 --- a/contrib/NR/nrutil.h +++ /dev/null @@ -1,43 +0,0 @@ -// This file has been modified for inclusion in GetDP - -#ifndef _NR_UTILS_H_ -#define _NR_UTILS_H_ - -#include <math.h> - -#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) -#define DSQR(a) ((a)*(a)) -#define SQR(a) ((a)*(a)) -#define DMIN(a,b) ((a)<(b) ? (a) : (b)) -#define DMAX(a,b) ((a)>(b) ? (a) : (b)) -#define FMIN(a,b) ((a)<(b) ? (a) : (b)) -#define FMAX(a,b) ((a)>(b) ? (a) : (b)) -#define IMIN(a,b) ((a)<(b) ? (a) : (b)) -#define IMAX(a,b) ((a)>(b) ? (a) : (b)) - -void nrerror(char error_text[]); -int *ivector(long nl, long nh); -unsigned char *cvector(long nl, long nh); -unsigned long *lvector(long nl, long nh); -double *dvector(long nl, long nh); -float **matrix(long nrl, long nrh, long ncl, long nch); -double **dmatrix(long nrl, long nrh, long ncl, long nch); -int **imatrix(long nrl, long nrh, long ncl, long nch); -float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch, - long newrl, long newcl); -float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch); -float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh); -void free_vector(float *v, long nl, long nh); -void free_ivector(int *v, long nl, long nh); -void free_cvector(unsigned char *v, long nl, long nh); -void free_lvector(unsigned long *v, long nl, long nh); -void free_dvector(double *v, long nl, long nh); -void free_matrix(float **m, long nrl, long nrh, long ncl, long nch); -void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch); -void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch); -void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch); -void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch); -void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch, - long ndl, long ndh); - -#endif -- GitLab