diff --git a/facb927.diff b/facb927.diff deleted file mode 100644 index ccbafc0615956c3196f67a473f76c6e7b7da9cf2..0000000000000000000000000000000000000000 --- a/facb927.diff +++ /dev/null @@ -1,2412 +0,0 @@ -From facb9273c571b6bef430e71b31ff229abd6d1a46 Mon Sep 17 00:00:00 2001 -From: Mark Abraham -Date: Mon, 11 Jun 2018 08:30:19 +0200 -Subject: [PATCH] Bump lmfit support to version 7 - -The breaking API change means that distributions will not be able to -build GROMACS reliably with support for lmfit of arbitrary versions. -Nor does lmfit provide any support for querying the version. Tools -that call such fitting will now issue a fatal error. - -Updated the FindLmfit and other cmake code to make better use of -modern cmake idioms for managing build targets. lmfit support is now -handled by a tri-state GMX_USE_LMFIT cmake variable, which defaults to -using the bundled version. - -Reorganized aspects of gmx_lmcurve to better encapsulate the -dependency, now that we have to support the absence of lmfit. - -Updated install guide and COPYING file. - -Refs #2533 - -Change-Id: I6b14e08be216f803326b0ad9215b8d89bb0962c1 ---- - -diff --git a/COPYING b/COPYING -index 4cc52a2..ba2710e 100644 ---- a/COPYING -+++ b/COPYING -@@ -1249,7 +1249,7 @@ - -- - Copyright (c) 1980-1999 University of Chicago, - as operator of Argonne National Laboratory -- Copyright (c) 2004-2013 Joachim Wuttke, Forschungszentrum Juelich GmbH -+ Copyright (c) 2004-2015 Joachim Wuttke, Forschungszentrum Juelich GmbH - - All rights reserved. - -diff --git a/cmake/FindLmfit.cmake b/cmake/FindLmfit.cmake -index 5bf489a..9dd23f1 100644 ---- a/cmake/FindLmfit.cmake -+++ b/cmake/FindLmfit.cmake -@@ -1,7 +1,7 @@ - # - # This file is part of the GROMACS molecular simulation package. - # --# Copyright (c) 2016, by the GROMACS development team, led by -+# Copyright (c) 2016,2018, by the GROMACS development team, led by - # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, - # and including many others, as listed in the AUTHORS file in the - # top-level source directory and at http://www.gromacs.org. -@@ -32,19 +32,20 @@ - # To help us fund GROMACS development, we humbly ask that you cite - # the research papers on the package. Check out http://www.gromacs.org. - --# This package tries to find an external lmfit library. It is intended --# to work with pkg-config, because that is the mechanism supported in --# lmfit. Upon exit, the following variables may be set: -+# This package tries to find an external lmfit library, version -+# 7. Note that pkg-config support was removed before version 7, so is -+# no longer supported here. Upon exit, the following variables may be -+# set: - # - # LMFIT_FOUND - lmfit was found - # LMFIT_INCLUDE_DIR - lmfit include directory --# LMFIT_LIBRARIES - lmfit libraries -+# LMFIT_LIBRARY - lmfit library - # LMFIT_LINKS_OK - lmfit libraries link correctly - # LMFIT_VERSION - lmfit version string as "major.minor" - # --# If you cannot use pkg-config for some reason, then setting --# LMFIT_INCLUDE_DIRS and LMFIT_LIBRARY_DIRS on the cmake command line --# to suitable values will work. -+# CMake will search the CMAKE_PREFIX_PATH in the usual way, but if you -+# need more control then setting LMFIT_INCLUDE_DIR and LMFIT_LIBRARY -+# on the cmake command line to suitable values will work. - - include(CMakePushCheckState) - cmake_push_check_state() -@@ -55,12 +56,12 @@ - # lmfit doesn't support CMake-based find_package version - # checking in 6.1, so this code does nothing. - if(LMFIT_FIND_VERSION_EXACT) -- pkg_check_modules(PC_LMFIT lmfit=${LMFIT_FIND_VERSION}) -+ pkg_check_modules(PC_LMFIT QUIET lmfit=${LMFIT_FIND_VERSION}) - else() -- pkg_check_modules(PC_LMFIT lmfit>=${LMFIT_FIND_VERSION}) -+ pkg_check_modules(PC_LMFIT QUIET lmfit>=${LMFIT_FIND_VERSION}) - endif() - else() -- pkg_check_modules(PC_LMFIT lmfit) -+ pkg_check_modules(PC_LMFIT QUIET lmfit) - if (PC_LMFIT_VERSION) - string(REGEX REPLACE "^([0-9]+):([0-9]+)" "\\1.\\2" LMFIT_VERSION "${PC_LMFIT_VERSION}") - endif() -@@ -68,20 +69,15 @@ - endif() - - # Try to find lmfit, perhaps with help from pkg-config --find_path(LMFIT_INCLUDE_DIRS lmcurve.h HINTS "${PC_LMFIT_INCLUDE_DIRS}" PATH_SUFFIXES include) --find_library(LMFIT_LIBRARY_DIRS NAMES lmfit HINTS "${PC_LMFIT_LIBRARY_DIRS}" PATH_SUFFIXES lib64 lib) -+find_path(LMFIT_INCLUDE_DIR lmcurve.h HINTS "${PC_LMFIT_INCLUDE_DIRS}" PATH_SUFFIXES include) -+find_library(LMFIT_LIBRARY NAMES lmfit HINTS "${PC_LMFIT_LIBRARY_DIRS}" PATH_SUFFIXES lib64 lib) - - # Make sure we can also link, so that cross-compilation is properly supported --if (LMFIT_INCLUDE_DIRS AND LMFIT_LIBRARY_DIRS) -+if (LMFIT_INCLUDE_DIR AND LMFIT_LIBRARY) - include(CheckCXXSourceCompiles) -- set(CMAKE_REQUIRED_INCLUDES ${LMFIT_INCLUDE_DIRS}) -- set(CMAKE_REQUIRED_LIBRARIES ${LMFIT_LIBRARY_DIRS}) -+ set(CMAKE_REQUIRED_INCLUDES ${LMFIT_INCLUDE_DIR}) -+ set(CMAKE_REQUIRED_LIBRARIES ${LMFIT_LIBRARY}) - check_cxx_source_compiles("#include \nint main(){lmcurve(0,0,0,0,0,0,0,0);}" LMFIT_LINKS_OK) --endif() -- --if (LMFIT_LINKS_OK) -- set(LMFIT_INCLUDE_DIR ${LMFIT_INCLUDE_DIRS}) -- set(LMFIT_LIBRARIES ${LMFIT_LIBRARY_DIRS}) - endif() - - include(FindPackageHandleStandardArgs) -@@ -90,11 +86,19 @@ - LMFIT_FOUND - REQUIRED_VARS - LMFIT_INCLUDE_DIR -- LMFIT_LIBRARIES -+ LMFIT_LIBRARY - LMFIT_LINKS_OK - VERSION_VAR - LMFIT_VERSION) - --mark_as_advanced(LMFIT_INCLUDE_DIRS LMFIT_LIBRARY_DIRS) -+mark_as_advanced(LMFIT_INCLUDE_DIR LMFIT_LIBRARY) -+ -+if (LMFIT_FOUND) -+ add_library(lmfit INTERFACE IMPORTED) -+ set_target_properties(lmfit PROPERTIES -+ INTERFACE_INCLUDE_DIRECTORIES "${LMFIT_INCLUDE_DIR}" -+ INTERFACE_LINK_LIBRARIES "${LMFIT_LIBRARY}" -+ ) -+endif() - - cmake_pop_check_state() -diff --git a/cmake/gmxManageLmfit.cmake b/cmake/gmxManageLmfit.cmake -index 182928f..5953a19 100644 ---- a/cmake/gmxManageLmfit.cmake -+++ b/cmake/gmxManageLmfit.cmake -@@ -32,21 +32,16 @@ - # To help us fund GROMACS development, we humbly ask that you cite - # the research papers on the package. Check out http://www.gromacs.org. - --set(GMX_LMFIT_MINIMUM_REQUIRED_VERSION "6.1") --set(GMX_BUNDLED_LMFIT_DIR "${CMAKE_SOURCE_DIR}/src/external/lmfit") -+# Note that lmfit does not have a stable API, so GROMACS only supports -+# the same version that it bundles. -+set(GMX_LMFIT_REQUIRED_VERSION "7.0") - --option(GMX_EXTERNAL_LMFIT "Use external lmfit instead of compiling the version bundled with GROMACS." OFF) --mark_as_advanced(GMX_EXTERNAL_LMFIT) -+include(gmxOptionUtilities) - --macro(manage_lmfit) -- if(GMX_EXTERNAL_LMFIT) -- # Find an external lmfit library. -- find_package(Lmfit ${GMX_LMFIT_REQUIRED_VERSION}) -- if(NOT LMFIT_FOUND OR LMFIT_VERSION VERSION_LESS GMX_LMFIT_REQUIRED_VERSION) -- message(FATAL_ERROR "External lmfit >= ${GMX_LMFIT_REQUIRED_VERSION} could not be found, please adjust your pkg-config path to include the lmfit.pc file") -- endif() -- endif() --endmacro() -+gmx_option_multichoice(GMX_USE_LMFIT -+ "Use external lmfit instead of compiling the version bundled with GROMACS." -+ INTERNAL -+ INTERNAL EXTERNAL NONE) - - macro(get_lmfit_properties LMFIT_SOURCES_VAR LMFIT_LIBRARIES_VAR LMFIT_INCLUDE_DIR_VAR LMFIT_INCLUDE_DIR_ORDER_VAR) - if (GMX_EXTERNAL_LMFIT) -@@ -62,5 +57,29 @@ - endif() - endmacro() - --manage_lmfit() -+function(manage_lmfit) -+ if(GMX_USE_LMFIT STREQUAL "INTERNAL") -+ set(BUNDLED_LMFIT_DIR "${CMAKE_SOURCE_DIR}/src/external/lmfit") -+ file(GLOB LMFIT_SOURCES ${BUNDLED_LMFIT_DIR}/*.cpp) - -+ # Create a fake library for lmfit for libgromacs to depend on -+ add_library(lmfit INTERFACE) -+ target_sources(lmfit INTERFACE ${LMFIT_SOURCES}) -+ target_include_directories(lmfit INTERFACE -+ $) -+ target_link_libraries(libgromacs PRIVATE lmfit) -+ -+ set(HAVE_LMFIT_VALUE TRUE) -+ elseif(GMX_USE_LMFIT STREQUAL "EXTERNAL") -+ # Find an external lmfit library. -+ find_package(Lmfit ${GMX_LMFIT_MINIMUM_REQUIRED_VERSION}) -+ if(NOT LMFIT_FOUND) -+ message(FATAL_ERROR "External lmfit could not be found, please adjust your pkg-config path to include the lmfit.pc file") -+ endif() -+ target_link_libraries(libgromacs PRIVATE lmfit) -+ set(HAVE_LMFIT_VALUE TRUE) -+ else() -+ set(HAVE_LMFIT_VALUE FALSE) -+ endif() -+ set(HAVE_LMFIT ${HAVE_LMFIT_VALUE} CACHE BOOL "Whether lmfit library support is enabled") -+endfunction() -diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt -index 9b38d75..3f050b5 100644 ---- a/docs/CMakeLists.txt -+++ b/docs/CMakeLists.txt -@@ -366,7 +366,7 @@ - REQUIRED_CUDA_COMPUTE_CAPABILITY REGRESSIONTEST_VERSION - SOURCE_MD5SUM REGRESSIONTEST_MD5SUM_STRING - GMX_TNG_MINIMUM_REQUIRED_VERSION -- GMX_LMFIT_MINIMUM_REQUIRED_VERSION -+ GMX_LMFIT_REQUIRED_VERSION - COMMENT "Configuring Sphinx configuration file") - gmx_add_sphinx_input_file(${SPHINX_CONFIG_VARS_FILE}) - gmx_add_sphinx_source_files(FILES ${SPHINX_SOURCE_FILES}) -diff --git a/docs/conf-vars.py.cmakein b/docs/conf-vars.py.cmakein -index f4c3e02..038014a 100644 ---- a/docs/conf-vars.py.cmakein -+++ b/docs/conf-vars.py.cmakein -@@ -1,7 +1,7 @@ - # - # This file is part of the GROMACS molecular simulation package. - # --# Copyright (c) 2015,2016,2017, by the GROMACS development team, led by -+# Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by - # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, - # and including many others, as listed in the AUTHORS file in the - # top-level source directory and at http://www.gromacs.org. -@@ -48,5 +48,5 @@ - ('SOURCE_MD5SUM', '@SOURCE_MD5SUM@'), - ('REGRESSIONTEST_MD5SUM', '@REGRESSIONTEST_MD5SUM_STRING@'), - ('GMX_TNG_MINIMUM_REQUIRED_VERSION', '@GMX_TNG_MINIMUM_REQUIRED_VERSION@'), -- ('GMX_LMFIT_MINIMUM_REQUIRED_VERSION', '@GMX_LMFIT_MINIMUM_REQUIRED_VERSION@') -+ ('GMX_LMFIT_REQUIRED_VERSION', '@GMX_LMFIT_REQUIRED_VERSION@') - ] -diff --git a/docs/install-guide/index.rst b/docs/install-guide/index.rst -index 48fe2c3..5324629 100644 ---- a/docs/install-guide/index.rst -+++ b/docs/install-guide/index.rst -@@ -340,10 +340,14 @@ - by setting ``-DGMX_EXTERNAL_TNG=yes``, but TNG - |GMX_TNG_MINIMUM_REQUIRED_VERSION| is bundled in the |Gromacs| - source already. --* An external lmfit library for Levenberg-Marquardt curve fitting -- can be used by setting ``-DGMX_EXTERNAL_LMFIT=yes``, but lmfit -- |GMX_LMFIT_MINIMUM_REQUIRED_VERSION| is bundled in the |Gromacs| -- source already. -+* The lmfit library for Levenberg-Marquardt curve fitting is used in -+ |Gromacs|. Only lmfit |GMX_LMFIT_REQUIRED_VERSION| is supported. A -+ reduced version of that library is bundled in the |Gromacs| -+ distribution, and the default build uses it. That default may be -+ explicitly enabled with ``-DGMX_USE_LMFIT=internal``. To use an -+ external lmfit library, set ``-DGMX_USE_LMFIT=external``, and adjust -+ ``CMAKE_PREFIX_PATH`` as needed. lmfit support can be disabled with -+ ``-DGMX_USE_LMFIT=none``. - * zlib is used by TNG for compressing some kinds of trajectory data - * Building the |Gromacs| documentation is optional, and requires - ImageMagick, pdflatex, bibtex, doxygen, python 2.7, sphinx -diff --git a/src/config.h.cmakein b/src/config.h.cmakein -index b7e5964..d0c3c35 100644 ---- a/src/config.h.cmakein -+++ b/src/config.h.cmakein -@@ -377,6 +377,9 @@ - /* Define if we have feenableexcept */ - #cmakedefine01 HAVE_FEENABLEEXCEPT - -+/* Define if we have lmfit support */ -+#cmakedefine01 HAVE_LMFIT -+ - /*! \endcond */ - - #endif -diff --git a/src/external/lmfit/README b/src/external/lmfit/README -index 3c0557b..4b8d7c6 100644 ---- a/src/external/lmfit/README -+++ b/src/external/lmfit/README -@@ -1,5 +1,5 @@ - This directory contains only the barebones version of the --lmfit package, version 6.1. Full version is available from -+lmfit package, version 7.0. Full version is available from - http://apps.jcns.fz-juelich.de/doku/sc/lmfit - - The license under which lmfit is bundled may be found in the GROMACS -diff --git a/src/external/lmfit/lmmin.cpp b/src/external/lmfit/lmmin.cpp -index eb2d298..813fe5d 100644 ---- a/src/external/lmfit/lmmin.cpp -+++ b/src/external/lmfit/lmmin.cpp -@@ -16,40 +16,41 @@ - #include - #include - #include --#include -+#include - #include - #include "lmmin.h" - --using namespace std; -- --static double lm_enorm(int n, const double* x); -- --#define MIN(a, b) (((a) <= (b)) ? (a) : (b)) --#define MAX(a, b) (((a) >= (b)) ? (a) : (b)) --#define SQR(x) (x) * (x) -+#define MIN(a,b) (((a)<=(b)) ? (a) : (b)) -+#define MAX(a,b) (((a)>=(b)) ? (a) : (b)) -+#define SQR(x) (x)*(x) - - /* Declare functions that do the heavy numerics. - Implementions are in this source file, below lmmin. -- Dependences: lmmin calls lmpar, which calls qrfac and qrsolv. */ --static void lm_lmpar(const int n, double* r, const int ldr, const int* Pivot, -- const double* diag, const double* qtb, const double delta, -- double* par, double* x, double* Sdiag, double* aux, double* xdi); --static void lm_qrfac(const int m, const int n, double* A, int* Pivot, double* Rdiag, -- double* Acnorm, double* W); --static void lm_qrsolv(const int n, double* r, const int ldr, const int* Pivot, -- const double* diag, const double* qtb, double* x, -- double* Sdiag, double* W); -+ Dependences: lmmin calls qrfac and lmpar; lmpar calls qrsolv. */ -+void lm_lmpar( -+ const int n, double *const r, const int ldr, int *const ipvt, -+ double *const diag, double *const qtb, double delta, double *const par, -+ double *const x, -+ double *const sdiag, double *const aux, double *const xdi); -+void lm_qrfac( -+ const int m, const int n, double *const a, int *const ipvt, -+ double *const rdiag, double *const acnorm, double *const wa ); -+void lm_qrsolv( -+ const int n, double *const r, const int ldr, int *const ipvt, -+ double *const diag, double *const qtb, double *const x, -+ double *const sdiag, double *const wa); - --/******************************************************************************/ --/* Numeric constants */ --/******************************************************************************/ - --/* Set machine-dependent constants to values from float.h. */ --#define LM_MACHEP DBL_EPSILON /* resolution of arithmetic */ --#define LM_DWARF DBL_MIN /* smallest nonzero number */ -+/*****************************************************************************/ -+/* Numeric constants */ -+/*****************************************************************************/ -+ -+/* machine-dependent constants from float.h */ -+#define LM_MACHEP DBL_EPSILON /* resolution of arithmetic */ -+#define LM_DWARF DBL_MIN /* smallest nonzero number */ - #define LM_SQRT_DWARF sqrt(DBL_MIN) /* square should not underflow */ - #define LM_SQRT_GIANT sqrt(DBL_MAX) /* square should not overflow */ --#define LM_USERTOL 30 * LM_MACHEP /* users are recommended to require this */ -+#define LM_USERTOL 30*LM_MACHEP /* users are recommended to require this */ - - /* If the above values do not work, the following seem good for an x86: - LM_MACHEP .555e-16 -@@ -65,19 +66,19 @@ - LM_USER_TOL 1.e-14 - */ - --/* Predefined control parameter sets (msgfile=NULL means stdout). */ - const lm_control_struct lm_control_double = { -- LM_USERTOL, LM_USERTOL, LM_USERTOL, LM_USERTOL, -- 100., 100, 1, NULL, 0, -1, -1}; -+ LM_USERTOL, LM_USERTOL, LM_USERTOL, LM_USERTOL, 100., 100, 1, -+ NULL, 0, -1, -1 }; - const lm_control_struct lm_control_float = { -- 1.e-7, 1.e-7, 1.e-7, 1.e-7, -- 100., 100, 1, NULL, 0, -1, -1}; -+ 1.e-7, 1.e-7, 1.e-7, 1.e-7, 100., 100, 1, -+ NULL, 0, -1, -1 }; - --/******************************************************************************/ --/* Message texts (indexed by status.info) */ --/******************************************************************************/ - --const char* lm_infmsg[] = { -+/*****************************************************************************/ -+/* Message texts (indexed by status.info) */ -+/*****************************************************************************/ -+ -+const char *lm_infmsg[] = { - "found zero (sum of squares below underflow limit)", - "converged (the relative error in the sum of squares is at most tol)", - "converged (the relative error of the parameter vector is at most tol)", -@@ -90,66 +91,86 @@ - "crashed (not enough memory)", - "exploded (fatal coding error: improper input parameters)", - "stopped (break requested within function evaluation)", -- "found nan (function value is not-a-number or infinite)"}; -+ "found nan (function value is not-a-number or infinite)", -+ "won't fit (no free parameter)" -+}; - --/******************************************************************************/ --/* Monitoring auxiliaries. */ --/******************************************************************************/ -+const char *lm_shortmsg[] = { -+ "found zero", // 0 -+ "converged (f)", // 1 -+ "converged (p)", // 2 -+ "converged (2)", // 3 -+ "degenerate", // 4 -+ "call limit", // 5 -+ "failed (f)", // 6 -+ "failed (p)", // 7 -+ "failed (o)", // 8 -+ "no memory", // 9 -+ "invalid input", // 10 -+ "user break", // 11 -+ "found nan", // 12 -+ "no free par" // 13 -+}; - --static void lm_print_pars(int nout, const double* par, FILE* fout) -+ -+/*****************************************************************************/ -+/* Monitoring auxiliaries. */ -+/*****************************************************************************/ -+ -+static void lm_print_pars(const int nout, const double *par, FILE* fout) - { -- int i; -- for (i = 0; i < nout; ++i) -- fprintf(fout, " %16.9g", par[i]); -+ fprintf(fout, " pars:"); -+ for (int i = 0; i < nout; ++i) -+ fprintf(fout, " %23.16g", par[i]); - fprintf(fout, "\n"); - } - --/******************************************************************************/ --/* lmmin (main minimization routine) */ --/******************************************************************************/ - --void lmmin(const int n, double* x, const int m, const void* data, -- void (*evaluate)(const double* par, const int m_dat, -- const void* data, double* fvec, int* userbreak), -- const lm_control_struct* C, lm_status_struct* S) -+/*****************************************************************************/ -+/* lmmin (main minimization routine) */ -+/*****************************************************************************/ -+ -+void lmmin( -+ const int n, double *const x, const int m, const double* y, -+ const void *const data, -+ void (*const evaluate)( -+ const double *const par, const int m_dat, const void *const data, -+ double *const fvec, int *const userbreak), -+ const lm_control_struct *const C, lm_status_struct *const S) - { - int j, i; -- double actred, dirder, fnorm, fnorm1, gnorm, pnorm, prered, ratio, step, -- sum, temp, temp1, temp2, temp3; -- -- /*** Initialize internal variables. ***/ -+ double actred, dirder, fnorm, fnorm1, gnorm, pnorm, -+ prered, ratio, step, sum, temp, temp1, temp2, temp3; -+ static double p1 = 0.1, p0001 = 1.0e-4; - - int maxfev = C->patience * (n+1); - -- int inner_success; /* flag for loop control */ -- double lmpar = 0; /* Levenberg-Marquardt parameter */ -+ int inner_success; /* flag for loop control */ -+ double lmpar = 0; /* Levenberg-Marquardt parameter */ - double delta = 0; - double xnorm = 0; - double eps = sqrt(MAX(C->epsilon, LM_MACHEP)); /* for forward differences */ - -- int nout = C->n_maxpri == -1 ? n : MIN(C->n_maxpri, n); -+ int nout = C->n_maxpri==-1 ? n : MIN(C->n_maxpri, n); - -- /* Reinterpret C->msgfile=NULL as stdout (which is unavailable for -- compile-time initialization of lm_control_double and similar). */ -+ /* The workaround msgfile=NULL is needed for default initialization */ - FILE* msgfile = C->msgfile ? C->msgfile : stdout; - -- /*** Default status info; must be set before first return statement. ***/ -- -- S->outcome = 0; /* status code */ -+ /* Default status info; must be set ahead of first return statements */ -+ S->outcome = 0; /* status code */ - S->userbreak = 0; -- S->nfev = 0; /* function evaluation counter */ -+ S->nfev = 0; /* function evaluation counter */ - -- /*** Check input parameters for errors. ***/ -+/*** Check input parameters for errors. ***/ - -- if (n <= 0) { -+ if ( n < 0 ) { - fprintf(stderr, "lmmin: invalid number of parameters %i\n", n); -- S->outcome = 10; -+ S->outcome = 10; /* invalid parameter */ - return; - } - if (m < n) { - fprintf(stderr, "lmmin: number of data points (%i) " -- "smaller than number of parameters (%i)\n", -- m, n); -+ "smaller than number of parameters (%i)\n", m, n); - S->outcome = 10; - return; - } -@@ -173,93 +194,99 @@ - } - if (C->scale_diag != 0 && C->scale_diag != 1) { - fprintf(stderr, "lmmin: logical variable scale_diag=%i, " -- "should be 0 or 1\n", -- C->scale_diag); -+ "should be 0 or 1\n", C->scale_diag); - S->outcome = 10; - return; - } - -- /*** Allocate work space. ***/ -+/*** Allocate work space. ***/ - - /* Allocate total workspace with just one system call */ -- char* ws; -- if ((ws = (char *)malloc((2*m + 5*n + m*n) * sizeof(double) + -- n * sizeof(int))) == NULL) { -+ char *ws; -+ if ( ( ws = static_cast(malloc( -+ (2*m+5*n+m*n)*sizeof(double) + n*sizeof(int)) ) ) == NULL ) { - S->outcome = 9; - return; - } - - /* Assign workspace segments. */ -- char* pws = ws; -- double* fvec = (double*)pws; -- pws += m * sizeof(double) / sizeof(char); -- double* diag = (double*)pws; -- pws += n * sizeof(double) / sizeof(char); -- double* qtf = (double*)pws; -- pws += n * sizeof(double) / sizeof(char); -- double* fjac = (double*)pws; -- pws += n * m * sizeof(double) / sizeof(char); -- double* wa1 = (double*)pws; -- pws += n * sizeof(double) / sizeof(char); -- double* wa2 = (double*)pws; -- pws += n * sizeof(double) / sizeof(char); -- double* wa3 = (double*)pws; -- pws += n * sizeof(double) / sizeof(char); -- double* wf = (double*)pws; -- pws += m * sizeof(double) / sizeof(char); -- int* Pivot = (int*)pws; -- //pws += n * sizeof(int) / sizeof(char); -+ char *pws = ws; -+ double *fvec = (double*) pws; pws += m * sizeof(double)/sizeof(char); -+ double *diag = (double*) pws; pws += n * sizeof(double)/sizeof(char); -+ double *qtf = (double*) pws; pws += n * sizeof(double)/sizeof(char); -+ double *fjac = (double*) pws; pws += n*m*sizeof(double)/sizeof(char); -+ double *wa1 = (double*) pws; pws += n * sizeof(double)/sizeof(char); -+ double *wa2 = (double*) pws; pws += n * sizeof(double)/sizeof(char); -+ double *wa3 = (double*) pws; pws += n * sizeof(double)/sizeof(char); -+ double *wf = (double*) pws; pws += m * sizeof(double)/sizeof(char); -+ int *ipvt = (int*) pws; pws += n * sizeof(int) /sizeof(char); - -- /* Initialize diag. */ -- if (!C->scale_diag) -+ /* Initialize diag */ // TODO: check whether this is still needed -+ if (!C->scale_diag) { - for (j = 0; j < n; j++) -- diag[j] = 1; -- -- /*** Evaluate function at starting point and calculate norm. ***/ -- -- if (C->verbosity) { -- fprintf(msgfile, "lmmin start "); -- lm_print_pars(nout, x, msgfile); -+ diag[j] = 1.; - } -- (*evaluate)(x, m, data, fvec, &(S->userbreak)); -- if (C->verbosity > 4) -- for (i = 0; i < m; ++i) -- fprintf(msgfile, " fvec[%4i] = %18.8g\n", i, fvec[i]); -- S->nfev = 1; -- if (S->userbreak) -- goto terminate; -- fnorm = lm_enorm(m, fvec); -- if (C->verbosity) -- fprintf(msgfile, " fnorm = %18.8g\n", fnorm); - -- if (!std::isfinite(fnorm)) { -+/*** Evaluate function at starting point and calculate norm. ***/ -+ -+ if( C->verbosity&1 ) -+ fprintf(msgfile, "lmmin start (ftol=%g gtol=%g xtol=%g)\n", -+ C->ftol, C->gtol, C->xtol); -+ if( C->verbosity&2 ) -+ lm_print_pars(nout, x, msgfile); -+ (*evaluate)(x, m, data, fvec, &(S->userbreak)); -+ if( C->verbosity&8 ) -+ { -+ if (y) { -+ for( i=0; infev = 1; -+ if ( S->userbreak ) -+ goto terminate; -+ if ( n == 0 ) { -+ S->outcome = 13; /* won't fit */ -+ goto terminate; -+ } -+ fnorm = lm_fnorm(m, fvec, y); -+ if( C->verbosity&2 ) -+ fprintf(msgfile, " fnorm = %24.16g\n", fnorm); -+ if( !isfinite(fnorm) ){ -+ if( C->verbosity ) -+ fprintf(msgfile, "nan case 1\n"); - S->outcome = 12; /* nan */ - goto terminate; -- } else if (fnorm <= LM_DWARF) { -+ } else if( fnorm <= LM_DWARF ){ - S->outcome = 0; /* sum of squares almost zero, nothing to do */ - goto terminate; - } - -- /*** The outer loop: compute gradient, then descend. ***/ -+/*** The outer loop: compute gradient, then descend. ***/ - -- for (int outer = 0;; ++outer) { -+ for( int outer=0; ; ++outer ) { - -- /** Calculate the Jacobian. **/ -+/*** [outer] Calculate the Jacobian. ***/ -+ - for (j = 0; j < n; j++) { - temp = x[j]; -- step = MAX(eps * eps, eps * fabs(temp)); -+ step = MAX(eps*eps, eps * fabs(temp)); - x[j] += step; /* replace temporarily */ - (*evaluate)(x, m, data, wf, &(S->userbreak)); - ++(S->nfev); -- if (S->userbreak) -+ if ( S->userbreak ) - goto terminate; - for (i = 0; i < m; i++) - fjac[j*m+i] = (wf[i] - fvec[i]) / step; - x[j] = temp; /* restore */ - } -- if (C->verbosity >= 10) { -+ if ( C->verbosity&16 ) { - /* print the entire matrix */ -- printf("\nlmmin Jacobian\n"); -+ printf("Jacobian\n"); - for (i = 0; i < m; i++) { - printf(" "); - for (j = 0; j < n; j++) -@@ -268,34 +295,39 @@ - } - } - -- /** Compute the QR factorization of the Jacobian. **/ -+/*** [outer] Compute the QR factorization of the Jacobian. ***/ - -- /* fjac is an m by n array. The upper n by n submatrix of fjac is made -- * to contain an upper triangular matrix R with diagonal elements of -- * nonincreasing magnitude such that -- * -- * P^T*(J^T*J)*P = R^T*R -- * -- * (NOTE: ^T stands for matrix transposition), -- * -- * where P is a permutation matrix and J is the final calculated -- * Jacobian. Column j of P is column Pivot(j) of the identity matrix. -- * The lower trapezoidal part of fjac contains information generated -- * during the computation of R. -- * -- * Pivot is an integer array of length n. It defines a permutation -- * matrix P such that jac*P = Q*R, where jac is the final calculated -- * Jacobian, Q is orthogonal (not stored), and R is upper triangular -- * with diagonal elements of nonincreasing magnitude. Column j of P -- * is column Pivot(j) of the identity matrix. -- */ -+/* fjac is an m by n array. The upper n by n submatrix of fjac -+ * is made to contain an upper triangular matrix R with diagonal -+ * elements of nonincreasing magnitude such that -+ * -+ * P^T*(J^T*J)*P = R^T*R -+ * -+ * (NOTE: ^T stands for matrix transposition), -+ * -+ * where P is a permutation matrix and J is the final calculated -+ * Jacobian. Column j of P is column ipvt(j) of the identity matrix. -+ * The lower trapezoidal part of fjac contains information generated -+ * during the computation of R. -+ * -+ * ipvt is an integer array of length n. It defines a permutation -+ * matrix P such that jac*P = Q*R, where jac is the final calculated -+ * Jacobian, Q is orthogonal (not stored), and R is upper triangular -+ * with diagonal elements of nonincreasing magnitude. Column j of P -+ * is column ipvt(j) of the identity matrix. -+ */ - -- lm_qrfac(m, n, fjac, Pivot, wa1, wa2, wa3); -- /* return values are Pivot, wa1=rdiag, wa2=acnorm */ -+ lm_qrfac(m, n, fjac, ipvt, wa1, wa2, wa3); -+ /* return values are ipvt, wa1=rdiag, wa2=acnorm */ - -- /** Form Q^T * fvec, and store first n components in qtf. **/ -- for (i = 0; i < m; i++) -- wf[i] = fvec[i]; -+/*** [outer] Form Q^T * fvec, and store first n components in qtf. ***/ -+ -+ if (y) -+ for (i = 0; i < m; i++) -+ wf[i] = fvec[i] - y[i]; -+ else -+ for (i = 0; i < m; i++) -+ wf[i] = fvec[i]; - - for (j = 0; j < n; j++) { - temp3 = fjac[j*m+j]; -@@ -311,15 +343,16 @@ - qtf[j] = wf[j]; - } - -- /** Compute norm of scaled gradient and detect degeneracy. **/ -+/*** [outer] Compute norm of scaled gradient and detect degeneracy. ***/ -+ - gnorm = 0; - for (j = 0; j < n; j++) { -- if (wa2[Pivot[j]] == 0) -+ if (wa2[ipvt[j]] == 0) - continue; - sum = 0; - for (i = 0; i <= j; i++) - sum += fjac[j*m+i] * qtf[i]; -- gnorm = MAX(gnorm, fabs(sum / wa2[Pivot[j]] / fnorm)); -+ gnorm = MAX(gnorm, fabs( sum / wa2[ipvt[j]] / fnorm )); - } - - if (gnorm <= C->gtol) { -@@ -327,8 +360,10 @@ - goto terminate; - } - -- /** Initialize or update diag and delta. **/ -- if (!outer) { /* first iteration only */ -+/*** [outer] Initialize / update diag and delta. ***/ -+ -+ if ( !outer ) { -+ /* first iteration only */ - if (C->scale_diag) { - /* diag := norms of the columns of the initial Jacobian */ - for (j = 0; j < n; j++) -@@ -337,129 +372,140 @@ - for (j = 0; j < n; j++) - wa3[j] = diag[j] * x[j]; - xnorm = lm_enorm(n, wa3); -- if (C->verbosity >= 2) { -- fprintf(msgfile, "lmmin diag "); -- lm_print_pars(nout, x, msgfile); // xnorm -- fprintf(msgfile, " xnorm = %18.8g\n", xnorm); -- } -- /* Only now print the header for the loop table. */ -- if (C->verbosity >= 3) { -- fprintf(msgfile, " o i lmpar prered" -- " ratio dirder delta" -- " pnorm fnorm"); -- for (i = 0; i < nout; ++i) -- fprintf(msgfile, " p%i", i); -- fprintf(msgfile, "\n"); -- } - } else { - xnorm = lm_enorm(n, x); - } -- if (!std::isfinite(xnorm)) { -+ if( !isfinite(xnorm) ){ -+ if( C->verbosity ) -+ fprintf(msgfile, "nan case 2\n"); - S->outcome = 12; /* nan */ - goto terminate; - } -- /* Initialize the step bound delta. */ -- if (xnorm) -+ /* initialize the step bound delta. */ -+ if ( xnorm ) - delta = C->stepbound * xnorm; - else - delta = C->stepbound; -+ /* only now print the header for the loop table */ -+ if( C->verbosity&2 ) { -+ fprintf(msgfile, " #o #i lmpar prered actred" -+ " ratio dirder delta" -+ " pnorm fnorm"); -+ for (i = 0; i < nout; ++i) -+ fprintf(msgfile, " p%i", i); -+ fprintf(msgfile, "\n"); -+ } - } else { - if (C->scale_diag) { - for (j = 0; j < n; j++) -- diag[j] = MAX(diag[j], wa2[j]); -+ diag[j] = MAX( diag[j], wa2[j] ); - } - } - -- /** The inner loop. **/ -+/*** The inner loop. ***/ - int inner = 0; - do { - -- /** Determine the Levenberg-Marquardt parameter. **/ -- lm_lmpar(n, fjac, m, Pivot, diag, qtf, delta, &lmpar, -+/*** [inner] Determine the Levenberg-Marquardt parameter. ***/ -+ -+ lm_lmpar(n, fjac, m, ipvt, diag, qtf, delta, &lmpar, - wa1, wa2, wf, wa3); - /* used return values are fjac (partly), lmpar, wa1=x, wa3=diag*x */ - -- /* Predict scaled reduction. */ -+ /* predict scaled reduction */ - pnorm = lm_enorm(n, wa3); -- if (!std::isfinite(pnorm)) { -+ if( !isfinite(pnorm) ){ -+ if( C->verbosity ) -+ fprintf(msgfile, "nan case 3\n"); - S->outcome = 12; /* nan */ - goto terminate; - } -- temp2 = lmpar * SQR(pnorm / fnorm); -+ temp2 = lmpar * SQR( pnorm / fnorm ); - for (j = 0; j < n; j++) { - wa3[j] = 0; - for (i = 0; i <= j; i++) -- wa3[i] -= fjac[j*m+i] * wa1[Pivot[j]]; -+ wa3[i] -= fjac[j*m+i] * wa1[ipvt[j]]; - } -- temp1 = SQR(lm_enorm(n, wa3) / fnorm); -- if (!std::isfinite(temp1)) { -+ temp1 = SQR( lm_enorm(n, wa3) / fnorm ); -+ if( !isfinite(temp1) ){ -+ if( C->verbosity ) -+ fprintf(msgfile, "nan case 4\n"); - S->outcome = 12; /* nan */ - goto terminate; - } -- prered = temp1 + 2*temp2; -+ prered = temp1 + 2 * temp2; - dirder = -temp1 + temp2; /* scaled directional derivative */ - -- /* At first call, adjust the initial step bound. */ -- if (!outer && pnorm < delta) -+ /* at first call, adjust the initial step bound. */ -+ if ( !outer && !inner && pnorm < delta ) - delta = pnorm; - -- /** Evaluate the function at x + p. **/ -+/*** [inner] Evaluate the function at x + p. ***/ -+ - for (j = 0; j < n; j++) - wa2[j] = x[j] - wa1[j]; -- (*evaluate)(wa2, m, data, wf, &(S->userbreak)); -+ -+ (*evaluate)( wa2, m, data, wf, &(S->userbreak) ); - ++(S->nfev); -- if (S->userbreak) -+ if ( S->userbreak ) - goto terminate; -- fnorm1 = lm_enorm(m, wf); -- if (!std::isfinite(fnorm1)) { -- S->outcome = 12; /* nan */ -- goto terminate; -+ fnorm1 = lm_fnorm(m, wf, y); -+ // exceptionally, for this norm we do not test for infinity -+ // because we can deal with it without terminating. -+ -+/*** [inner] Evaluate the scaled reduction. ***/ -+ -+ /* actual scaled reduction (supports even the case fnorm1=infty) */ -+ if (p1 * fnorm1 < fnorm) -+ actred = 1 - SQR(fnorm1 / fnorm); -+ else -+ actred = -1; -+ -+ /* ratio of actual to predicted reduction */ -+ ratio = prered ? actred/prered : 0; -+ -+ if( C->verbosity&32 ) { -+ if (y) { -+ for( i=0; iverbosity == 2) { -- fprintf(msgfile, "lmmin (%i:%i) ", outer, inner); -- lm_print_pars(nout, wa2, msgfile); // fnorm1, -- } else if (C->verbosity >= 3) { -- printf("%3i %2i %9.2g %9.2g %14.6g" -+ if( C->verbosity&2 ) { -+ printf("%3i %2i %9.2g %9.2g %9.2g %14.6g" - " %9.2g %10.3e %10.3e %21.15e", -- outer, inner, lmpar, prered, ratio, -+ outer, inner, lmpar, prered, actred, ratio, - dirder, delta, pnorm, fnorm1); - for (i = 0; i < nout; ++i) - fprintf(msgfile, " %16.9g", wa2[i]); - fprintf(msgfile, "\n"); - } - -- /* Update the step bound. */ -- if (ratio <= 0.25) { -- if (actred >= 0) -- temp = 0.5; -- else if (actred > -99) /* -99 = 1-1/0.1^2 */ -- temp = MAX(dirder / (2*dirder + actred), 0.1); -- else -- temp = 0.1; -- delta = temp * MIN(delta, pnorm / 0.1); -- lmpar /= temp; -- } else if (ratio >= 0.75) { -- delta = 2 * pnorm; -- lmpar *= 0.5; -- } else if (!lmpar) { -- delta = 2 * pnorm; -- } -+ /* update the step bound */ -+ if (ratio <= 0.25) { -+ if (actred >= 0) -+ temp = 0.5; -+ else -+ temp = 0.5 * dirder / (dirder + 0.5 * actred); -+ if (p1 * fnorm1 >= fnorm || temp < p1) -+ temp = p1; -+ delta = temp * MIN(delta, pnorm / p1); -+ lmpar /= temp; -+ } else if (lmpar == 0 || ratio >= 0.75) { -+ delta = 2 * pnorm; -+ lmpar *= 0.5; -+ } - -- /** On success, update solution, and test for convergence. **/ -+/*** [inner] On success, update solution, and test for convergence. ***/ - -- inner_success = ratio >= 1e-4; -- if (inner_success) { -+ inner_success = ratio >= p0001; -+ if ( inner_success ) { - -- /* Update x, fvec, and their norms. */ -+ /* update x, fvec, and their norms */ - if (C->scale_diag) { - for (j = 0; j < n; j++) { - x[j] = wa2[j]; -@@ -472,172 +518,193 @@ - for (i = 0; i < m; i++) - fvec[i] = wf[i]; - xnorm = lm_enorm(n, wa2); -- if (!std::isfinite(xnorm)) { -+ if( !isfinite(xnorm) ){ -+ if( C->verbosity ) -+ fprintf(msgfile, "nan case 6\n"); - S->outcome = 12; /* nan */ - goto terminate; - } - fnorm = fnorm1; - } - -- /* Convergence tests. */ -+ /* convergence tests */ - S->outcome = 0; -- if (fnorm <= LM_DWARF) -- goto terminate; /* success: sum of squares almost zero */ -- /* Test two criteria (both may be fulfilled). */ -+ if( fnorm<=LM_DWARF ) -+ goto terminate; /* success: sum of squares almost zero */ -+ /* test two criteria (both may be fulfilled) */ - if (fabs(actred) <= C->ftol && prered <= C->ftol && ratio <= 2) -- S->outcome = 1; /* success: x almost stable */ -+ S->outcome = 1; /* success: x almost stable */ - if (delta <= C->xtol * xnorm) - S->outcome += 2; /* success: sum of squares almost stable */ - if (S->outcome != 0) { - goto terminate; - } - -- /** Tests for termination and stringent tolerances. **/ -- if (S->nfev >= maxfev) { -+/*** [inner] Tests for termination and stringent tolerances. ***/ -+ -+ if ( S->nfev >= maxfev ){ - S->outcome = 5; - goto terminate; - } -- if (fabs(actred) <= LM_MACHEP && prered <= LM_MACHEP && -- ratio <= 2) { -+ if ( fabs(actred) <= LM_MACHEP && -+ prered <= LM_MACHEP && ratio <= 2 ){ - S->outcome = 6; - goto terminate; - } -- if (delta <= LM_MACHEP * xnorm) { -+ if ( delta <= LM_MACHEP*xnorm ){ - S->outcome = 7; - goto terminate; - } -- if (gnorm <= LM_MACHEP) { -+ if ( gnorm <= LM_MACHEP ){ - S->outcome = 8; - goto terminate; - } - -- /** End of the inner loop. Repeat if iteration unsuccessful. **/ -- ++inner; -- } while (!inner_success); -+/*** [inner] End of the loop. Repeat if iteration unsuccessful. ***/ - -- }; /*** End of the outer loop. ***/ -+ ++inner; -+ } while ( !inner_success ); -+ -+/*** [outer] End of the loop. ***/ -+ -+ }; - - terminate: -- S->fnorm = lm_enorm(m, fvec); -- if (C->verbosity >= 2) -- printf("lmmin outcome (%i) xnorm %g ftol %g xtol %g\n", S->outcome, -- xnorm, C->ftol, C->xtol); -- if (C->verbosity & 1) { -- fprintf(msgfile, "lmmin final "); -- lm_print_pars(nout, x, msgfile); // S->fnorm, -- fprintf(msgfile, " fnorm = %18.8g\n", S->fnorm); -+ S->fnorm = lm_fnorm(m, fvec, y); -+ if( C->verbosity&1 ) -+ fprintf(msgfile, "lmmin terminates with outcome %i\n", S->outcome); -+ if( C->verbosity&2 ) -+ lm_print_pars(nout, x, msgfile); -+ if( C->verbosity&8 ) { -+ if (y) { -+ for( i=0; iuserbreak) /* user-requested break */ -+ if( C->verbosity&2 ) -+ fprintf(msgfile, " fnorm=%24.16g xnorm=%24.16g\n", S->fnorm, xnorm); -+ if ( S->userbreak ) /* user-requested break */ - S->outcome = 11; - -- /*** Deallocate the workspace. ***/ -+/*** Deallocate the workspace. ***/ - free(ws); - - } /*** lmmin. ***/ - --/******************************************************************************/ --/* lm_lmpar (determine Levenberg-Marquardt parameter) */ --/******************************************************************************/ - --static void lm_lmpar(const int n, double* r, const int ldr, const int* Pivot, -- const double* diag, const double* qtb, const double delta, -- double* par, double* x, double* Sdiag, double* aux, double* xdi) -+/*****************************************************************************/ -+/* lm_lmpar (determine Levenberg-Marquardt parameter) */ -+/*****************************************************************************/ -+ -+void lm_lmpar( -+ const int n, double *const r, const int ldr, int *const ipvt, -+ double *const diag, double *const qtb, double delta, double *const par, -+ double *const x, double *const sdiag, double *const aux, double *const xdi) -+{ - /* Given an m by n matrix A, an n by n nonsingular diagonal matrix D, - * an m-vector b, and a positive number delta, the problem is to - * determine a parameter value par such that if x solves the system - * - * A*x = b and sqrt(par)*D*x = 0 - * -- * in the least squares sense, and dxnorm is the Euclidean norm of D*x, -- * then either par=0 and (dxnorm-delta) < 0.1*delta, or par>0 and -- * abs(dxnorm-delta) < 0.1*delta. -+ * in the least squares sense, and dxnorm is the euclidean -+ * norm of D*x, then either par=0 and (dxnorm-delta) < 0.1*delta, -+ * or par>0 and abs(dxnorm-delta) < 0.1*delta. - * - * Using lm_qrsolv, this subroutine completes the solution of the -- * problem if it is provided with the necessary information from the -- * QR factorization, with column pivoting, of A. That is, if A*P = Q*R, -- * where P is a permutation matrix, Q has orthogonal columns, and R is -- * an upper triangular matrix with diagonal elements of nonincreasing -- * magnitude, then lmpar expects the full upper triangle of R, the -- * permutation matrix P, and the first n components of Q^T*b. On output -- * lmpar also provides an upper triangular matrix S such that -+ * problem if it is provided with the necessary information from -+ * the QR factorization, with column pivoting, of A. That is, if -+ * A*P = Q*R, where P is a permutation matrix, Q has orthogonal -+ * columns, and R is an upper triangular matrix with diagonal -+ * elements of nonincreasing magnitude, then lmpar expects the -+ * full upper triangle of R, the permutation matrix P, and the -+ * first n components of Q^T*b. On output lmpar also provides an -+ * upper triangular matrix S such that - * - * P^T*(A^T*A + par*D*D)*P = S^T*S. - * - * S is employed within lmpar and may be of separate interest. - * -- * Only a few iterations are generally needed for convergence of the -- * algorithm. If, however, the limit of 10 iterations is reached, then -- * the output par will contain the best value obtained so far. -+ * Only a few iterations are generally needed for convergence -+ * of the algorithm. If, however, the limit of 10 iterations -+ * is reached, then the output par will contain the best value -+ * obtained so far. - * - * Parameters: - * - * n is a positive integer INPUT variable set to the order of r. - * -- * r is an n by n array. On INPUT the full upper triangle must contain -- * the full upper triangle of the matrix R. On OUTPUT the full upper -- * triangle is unaltered, and the strict lower triangle contains the -- * strict upper triangle (transposed) of the upper triangular matrix S. -+ * r is an n by n array. On INPUT the full upper triangle -+ * must contain the full upper triangle of the matrix R. -+ * On OUTPUT the full upper triangle is unaltered, and the -+ * strict lower triangle contains the strict upper triangle -+ * (transposed) of the upper triangular matrix S. - * -- * ldr is a positive integer INPUT variable not less than n which -- * specifies the leading dimension of the array R. -+ * ldr is a positive integer INPUT variable not less than n -+ * which specifies the leading dimension of the array R. - * -- * Pivot is an integer INPUT array of length n which defines the -- * permutation matrix P such that A*P = Q*R. Column j of P is column -- * Pivot(j) of the identity matrix. -+ * ipvt is an integer INPUT array of length n which defines the -+ * permutation matrix P such that A*P = Q*R. Column j of P -+ * is column ipvt(j) of the identity matrix. - * -- * diag is an INPUT array of length n which must contain the diagonal -- * elements of the matrix D. -+ * diag is an INPUT array of length n which must contain the -+ * diagonal elements of the matrix D. - * - * qtb is an INPUT array of length n which must contain the first - * n elements of the vector Q^T*b. - * -- * delta is a positive INPUT variable which specifies an upper bound -- * on the Euclidean norm of D*x. -+ * delta is a positive INPUT variable which specifies an upper -+ * bound on the euclidean norm of D*x. - * -- * par is a nonnegative variable. On INPUT par contains an initial -- * estimate of the Levenberg-Marquardt parameter. On OUTPUT par -- * contains the final estimate. -+ * par is a nonnegative variable. On INPUT par contains an -+ * initial estimate of the Levenberg-Marquardt parameter. -+ * On OUTPUT par contains the final estimate. - * -- * x is an OUTPUT array of length n which contains the least-squares -- * solution of the system A*x = b, sqrt(par)*D*x = 0, for the output par. -+ * x is an OUTPUT array of length n which contains the least -+ * squares solution of the system A*x = b, sqrt(par)*D*x = 0, -+ * for the output par. - * -- * Sdiag is an array of length n needed as workspace; on OUTPUT it -- * contains the diagonal elements of the upper triangular matrix S. -+ * sdiag is an array of length n needed as workspace; on OUTPUT -+ * it contains the diagonal elements of the upper triangular -+ * matrix S. - * - * aux is a multi-purpose work array of length n. - * - * xdi is a work array of length n. On OUTPUT: diag[j] * x[j]. - * - */ --{ - int i, iter, j, nsing; - double dxnorm, fp, fp_old, gnorm, parc, parl, paru; - double sum, temp; - static double p1 = 0.1; - -- /*** Compute and store in x the Gauss-Newton direction. If the Jacobian -- is rank-deficient, obtain a least-squares solution. ***/ -+/*** lmpar: compute and store in x the gauss-newton direction. if the -+ jacobian is rank-deficient, obtain a least squares solution. ***/ - - nsing = n; - for (j = 0; j < n; j++) { - aux[j] = qtb[j]; -- if (r[j*ldr+j] == 0 && nsing == n) -+ if (r[j * ldr + j] == 0 && nsing == n) - nsing = j; - if (nsing < n) - aux[j] = 0; - } -- for (j = nsing-1; j >= 0; j--) { -- aux[j] = aux[j] / r[j+ldr*j]; -+ for (j = nsing - 1; j >= 0; j--) { -+ aux[j] = aux[j] / r[j + ldr * j]; - temp = aux[j]; - for (i = 0; i < j; i++) -- aux[i] -= r[j*ldr+i] * temp; -+ aux[i] -= r[j * ldr + i] * temp; - } - - for (j = 0; j < n; j++) -- x[Pivot[j]] = aux[j]; -+ x[ipvt[j]] = aux[j]; - -- /*** Initialize the iteration counter, evaluate the function at the origin, -- and test for acceptance of the Gauss-Newton direction. ***/ -+/*** lmpar: initialize the iteration counter, evaluate the function at the -+ origin, and test for acceptance of the gauss-newton direction. ***/ - - for (j = 0; j < n; j++) - xdi[j] = diag[j] * x[j]; -@@ -645,65 +712,67 @@ - fp = dxnorm - delta; - if (fp <= p1 * delta) { - #ifdef LMFIT_DEBUG_MESSAGES -- printf("debug lmpar nsing=%d, n=%d, terminate[fp<=p1*del]\n", nsing, n); -+ printf("debug lmpar nsing %d n %d, terminate (fp= n) { - for (j = 0; j < n; j++) -- aux[j] = diag[Pivot[j]] * xdi[Pivot[j]] / dxnorm; -+ aux[j] = diag[ipvt[j]] * xdi[ipvt[j]] / dxnorm; - - for (j = 0; j < n; j++) { - sum = 0; - for (i = 0; i < j; i++) -- sum += r[j*ldr+i] * aux[i]; -- aux[j] = (aux[j] - sum) / r[j+ldr*j]; -+ sum += r[j * ldr + i] * aux[i]; -+ aux[j] = (aux[j] - sum) / r[j + ldr * j]; - } - temp = lm_enorm(n, aux); - parl = fp / delta / temp / temp; - } - -- /*** Calculate an upper bound, paru, for the zero of the function. ***/ -+/*** lmpar: calculate an upper bound, paru, for the zero of the function. ***/ - - for (j = 0; j < n; j++) { - sum = 0; - for (i = 0; i <= j; i++) -- sum += r[j*ldr+i] * qtb[i]; -- aux[j] = sum / diag[Pivot[j]]; -+ sum += r[j * ldr + i] * qtb[i]; -+ aux[j] = sum / diag[ipvt[j]]; - } - gnorm = lm_enorm(n, aux); - paru = gnorm / delta; - if (paru == 0) - paru = LM_DWARF / MIN(delta, p1); - -- /*** If the input par lies outside of the interval (parl,paru), -- set par to the closer endpoint. ***/ -+/*** lmpar: if the input par lies outside of the interval (parl,paru), -+ set par to the closer endpoint. ***/ - - *par = MAX(*par, parl); - *par = MIN(*par, paru); - if (*par == 0) - *par = gnorm / dxnorm; - -- /*** Iterate. ***/ -+/*** lmpar: iterate. ***/ - -- for (iter = 0;; iter++) { -+ for (iter=0; ; iter++) { - -- /** Evaluate the function at the current value of par. **/ -+ /** evaluate the function at the current value of par. **/ -+ - if (*par == 0) - *par = MAX(LM_DWARF, 0.001 * paru); - temp = sqrt(*par); - for (j = 0; j < n; j++) - aux[j] = temp * diag[j]; - -- lm_qrsolv(n, r, ldr, Pivot, aux, qtb, x, Sdiag, xdi); -- /* return values are r, x, Sdiag */ -+ lm_qrsolv(n, r, ldr, ipvt, aux, qtb, x, sdiag, xdi); -+ /* return values are r, x, sdiag */ - - for (j = 0; j < n; j++) - xdi[j] = diag[j] * x[j]; /* used as output */ -@@ -711,49 +780,58 @@ - fp_old = fp; - fp = dxnorm - delta; - -- /** If the function is small enough, accept the current value -+ /** if the function is small enough, accept the current value - of par. Also test for the exceptional cases where parl - is zero or the number of iterations has reached 10. **/ -- if (fabs(fp) <= p1 * delta || -- (parl == 0 && fp <= fp_old && fp_old < 0) || iter == 10) { -+ -+ if (fabs(fp) <= p1 * delta -+ || (parl == 0 && fp <= fp_old && fp_old < 0) -+ || iter == 10) { - #ifdef LMFIT_DEBUG_MESSAGES -- printf("debug lmpar nsing=%d, iter=%d, " -- "par=%.4e [%.4e %.4e], delta=%.4e, fp=%.4e\n", -+ printf("debug lmpar nsing %d iter %d " -+ "par %.4e [%.4e %.4e] delta %.4e fp %.4e\n", - nsing, iter, *par, parl, paru, delta, fp); - #endif - break; /* the only exit from the iteration. */ - } - -- /** Compute the Newton correction. **/ -+ /** compute the Newton correction. **/ -+ - for (j = 0; j < n; j++) -- aux[j] = diag[Pivot[j]] * xdi[Pivot[j]] / dxnorm; -+ aux[j] = diag[ipvt[j]] * xdi[ipvt[j]] / dxnorm; - - for (j = 0; j < n; j++) { -- aux[j] = aux[j] / Sdiag[j]; -- for (i = j+1; i < n; i++) -- aux[i] -= r[j*ldr+i] * aux[j]; -+ aux[j] = aux[j] / sdiag[j]; -+ for (i = j + 1; i < n; i++) -+ aux[i] -= r[j * ldr + i] * aux[j]; - } - temp = lm_enorm(n, aux); - parc = fp / delta / temp / temp; - -- /** Depending on the sign of the function, update parl or paru. **/ -+ /** depending on the sign of the function, update parl or paru. **/ -+ - if (fp > 0) - parl = MAX(parl, *par); -- else /* fp < 0 [the case fp==0 is precluded by the break condition] */ -+ else if (fp < 0) - paru = MIN(paru, *par); -+ /* the case fp==0 is precluded by the break condition */ - -- /** Compute an improved estimate for par. **/ -+ /** compute an improved estimate for par. **/ -+ - *par = MAX(parl, *par + parc); -+ - } - - } /*** lm_lmpar. ***/ - --/******************************************************************************/ --/* lm_qrfac (QR factorization, from lapack) */ --/******************************************************************************/ -+/*****************************************************************************/ -+/* lm_qrfac (QR factorization, from lapack) */ -+/*****************************************************************************/ - --static void lm_qrfac(const int m, const int n, double* A, int* Pivot, double* Rdiag, -- double* Acnorm, double* W) -+void lm_qrfac( -+ const int m, const int n, double *const A, int *const Pivot, -+ double *const Rdiag, double *const Acnorm, double *const W) -+{ - /* - * This subroutine uses Householder transformations with column pivoting - * to compute a QR factorization of the m by n matrix A. That is, qrfac -@@ -772,27 +850,27 @@ - * - * n is an INPUT parameter set to the number of columns of A. - * -- * A is an m by n array. On INPUT, A contains the matrix for which the -- * QR factorization is to be computed. On OUTPUT the strict upper -- * trapezoidal part of A contains the strict upper trapezoidal part -- * of R, and the lower trapezoidal part of A contains a factored form -- * of Q (the non-trivial elements of the vectors w described above). -+ * A is an m by n array. On INPUT, A contains the matrix for -+ * which the QR factorization is to be computed. On OUTPUT -+ * the strict upper trapezoidal part of A contains the strict -+ * upper trapezoidal part of R, and the lower trapezoidal -+ * part of A contains a factored form of Q (the non-trivial -+ * elements of the vectors w described above). - * - * Pivot is an integer OUTPUT array of length n that describes the -- * permutation matrix P. Column j of P is column Pivot(j) of the -- * identity matrix. -+ * permutation matrix P: -+ * Column j of P is column ipvt(j) of the identity matrix. - * -- * Rdiag is an OUTPUT array of length n which contains the diagonal -- * elements of R. -+ * Rdiag is an OUTPUT array of length n which contains the -+ * diagonal elements of R. - * -- * Acnorm is an OUTPUT array of length n which contains the norms of -- * the corresponding columns of the input matrix A. If this information -- * is not needed, then Acnorm can share storage with Rdiag. -+ * Acnorm is an OUTPUT array of length n which contains the norms -+ * of the corresponding columns of the input matrix A. If this -+ * information is not needed, then Acnorm can share storage with Rdiag. - * - * W is a work array of length n. - * - */ --{ - int i, j, k, kmax; - double ajnorm, sum, temp; - -@@ -802,16 +880,19 @@ - - /** Compute initial column norms; - initialize Pivot with identity permutation. ***/ -+ - for (j = 0; j < n; j++) { - W[j] = Rdiag[j] = Acnorm[j] = lm_enorm(m, &A[j*m]); - Pivot[j] = j; - } - - /** Loop over columns of A. **/ -- assert(n <= m); -+ -+ assert( n <= m ); - for (j = 0; j < n; j++) { - - /** Bring the column of largest norm into the pivot position. **/ -+ - kmax = j; - for (k = j+1; k < n; k++) - if (Rdiag[k] > Rdiag[kmax]) -@@ -834,6 +915,7 @@ - - /** Compute the Householder reflection vector w_j to reduce the - j-th column of A to a multiple of the j-th unit vector. **/ -+ - ajnorm = lm_enorm(m-j, &A[j*m+j]); - if (ajnorm == 0) { - Rdiag[j] = 0; -@@ -850,6 +932,7 @@ - - /** Apply the Householder transformation U_w := 1 - 2*w_j.w_j/|w_j|^2 - to the remaining columns, and update the norms. **/ -+ - for (k = j+1; k < n; k++) { - /* Compute scalar product w_j * a_j. */ - sum = 0; -@@ -866,12 +949,12 @@ - /* No idea what happens here. */ - if (Rdiag[k] != 0) { - temp = A[m*k+j] / Rdiag[k]; -- if (fabs(temp) < 1) { -- Rdiag[k] *= sqrt(1 - SQR(temp)); -+ if ( fabs(temp)<1 ) { -+ Rdiag[k] *= sqrt(1-SQR(temp)); - temp = Rdiag[k] / W[k]; - } else - temp = 0; -- if (temp == 0 || 0.05 * SQR(temp) <= LM_MACHEP) { -+ if ( temp == 0 || 0.05 * SQR(temp) <= LM_MACHEP ) { - Rdiag[k] = lm_enorm(m-j-1, &A[m*k+j+1]); - W[k] = Rdiag[k]; - } -@@ -882,13 +965,16 @@ - } - } /*** lm_qrfac. ***/ - --/******************************************************************************/ --/* lm_qrsolv (linear least-squares) */ --/******************************************************************************/ - --static void lm_qrsolv(const int n, double* r, const int ldr, const int* Pivot, -- const double* diag, const double* qtb, double* x, -- double* Sdiag, double* W) -+/*****************************************************************************/ -+/* lm_qrsolv (linear least-squares) */ -+/*****************************************************************************/ -+ -+void lm_qrsolv( -+ const int n, double *const r, const int ldr, int *const ipvt, -+ double *const diag, double *const qtb, double *const x, -+ double *const sdiag, double *const wa) -+{ - /* - * Given an m by n matrix A, an n by n diagonal matrix D, and an - * m-vector b, the problem is to determine an x which solves the -@@ -921,145 +1007,152 @@ - * - * n is a positive integer INPUT variable set to the order of R. - * -- * r is an n by n array. On INPUT the full upper triangle must contain -- * the full upper triangle of the matrix R. On OUTPUT the full upper -- * triangle is unaltered, and the strict lower triangle contains the -- * strict upper triangle (transposed) of the upper triangular matrix S. -+ * r is an n by n array. On INPUT the full upper triangle must -+ * contain the full upper triangle of the matrix R. On OUTPUT -+ * the full upper triangle is unaltered, and the strict lower -+ * triangle contains the strict upper triangle (transposed) of -+ * the upper triangular matrix S. - * -- * ldr is a positive integer INPUT variable not less than n which -- * specifies the leading dimension of the array R. -+ * ldr is a positive integer INPUT variable not less than n -+ * which specifies the leading dimension of the array R. - * -- * Pivot is an integer INPUT array of length n which defines the -- * permutation matrix P such that A*P = Q*R. Column j of P is column -- * Pivot(j) of the identity matrix. -+ * ipvt is an integer INPUT array of length n which defines the -+ * permutation matrix P such that A*P = Q*R. Column j of P -+ * is column ipvt(j) of the identity matrix. - * -- * diag is an INPUT array of length n which must contain the diagonal -- * elements of the matrix D. -+ * diag is an INPUT array of length n which must contain the -+ * diagonal elements of the matrix D. - * - * qtb is an INPUT array of length n which must contain the first - * n elements of the vector Q^T*b. - * -- * x is an OUTPUT array of length n which contains the least-squares -- * solution of the system A*x = b, D*x = 0. -+ * x is an OUTPUT array of length n which contains the least -+ * squares solution of the system A*x = b, D*x = 0. - * -- * Sdiag is an OUTPUT array of length n which contains the diagonal -- * elements of the upper triangular matrix S. -+ * sdiag is an OUTPUT array of length n which contains the -+ * diagonal elements of the upper triangular matrix S. - * -- * W is a work array of length n. -+ * wa is a work array of length n. - * - */ --{ - int i, kk, j, k, nsing; - double qtbpj, sum, temp; - double _sin, _cos, _tan, _cot; /* local variables, not functions */ - -- /*** Copy R and Q^T*b to preserve input and initialize S. -- In particular, save the diagonal elements of R in x. ***/ -+/*** qrsolv: copy R and Q^T*b to preserve input and initialize S. -+ In particular, save the diagonal elements of R in x. ***/ - - for (j = 0; j < n; j++) { - for (i = j; i < n; i++) -- r[j*ldr+i] = r[i*ldr+j]; -- x[j] = r[j*ldr+j]; -- W[j] = qtb[j]; -+ r[j * ldr + i] = r[i * ldr + j]; -+ x[j] = r[j * ldr + j]; -+ wa[j] = qtb[j]; - } - -- /*** Eliminate the diagonal matrix D using a Givens rotation. ***/ -+/*** qrsolv: eliminate the diagonal matrix D using a Givens rotation. ***/ - - for (j = 0; j < n; j++) { - -- /*** Prepare the row of D to be eliminated, locating the diagonal -- element using P from the QR factorization. ***/ -+/*** qrsolv: prepare the row of D to be eliminated, locating the -+ diagonal element using P from the QR factorization. ***/ - -- if (diag[Pivot[j]] != 0) { -- for (k = j; k < n; k++) -- Sdiag[k] = 0; -- Sdiag[j] = diag[Pivot[j]]; -+ if (diag[ipvt[j]] == 0) -+ goto L90; -+ for (k = j; k < n; k++) -+ sdiag[k] = 0; -+ sdiag[j] = diag[ipvt[j]]; - -- /*** The transformations to eliminate the row of D modify only -- a single element of Q^T*b beyond the first n, which is -- initially 0. ***/ -+/*** qrsolv: the transformations to eliminate the row of D modify only -+ a single element of Q^T*b beyond the first n, which is initially 0. ***/ - -- qtbpj = 0; -- for (k = j; k < n; k++) { -+ qtbpj = 0; -+ for (k = j; k < n; k++) { - -- /** Determine a Givens rotation which eliminates the -- appropriate element in the current row of D. **/ -- if (Sdiag[k] == 0) -- continue; -- kk = k + ldr * k; -- if (fabs(r[kk]) < fabs(Sdiag[k])) { -- _cot = r[kk] / Sdiag[k]; -- _sin = 1 / hypot(1, _cot); -- _cos = _sin * _cot; -- } else { -- _tan = Sdiag[k] / r[kk]; -- _cos = 1 / hypot(1, _tan); -- _sin = _cos * _tan; -- } -+ /** determine a Givens rotation which eliminates the -+ appropriate element in the current row of D. **/ - -- /** Compute the modified diagonal element of R and -- the modified element of (Q^T*b,0). **/ -- r[kk] = _cos * r[kk] + _sin * Sdiag[k]; -- temp = _cos * W[k] + _sin * qtbpj; -- qtbpj = -_sin * W[k] + _cos * qtbpj; -- W[k] = temp; -+ if (sdiag[k] == 0) -+ continue; -+ kk = k + ldr * k; -+ if (fabs(r[kk]) < fabs(sdiag[k])) { -+ _cot = r[kk] / sdiag[k]; -+ _sin = 1 / sqrt(1 + SQR(_cot)); -+ _cos = _sin * _cot; -+ } else { -+ _tan = sdiag[k] / r[kk]; -+ _cos = 1 / sqrt(1 + SQR(_tan)); -+ _sin = _cos * _tan; -+ } - -- /** Accumulate the tranformation in the row of S. **/ -- for (i = k+1; i < n; i++) { -- temp = _cos * r[k*ldr+i] + _sin * Sdiag[i]; -- Sdiag[i] = -_sin * r[k*ldr+i] + _cos * Sdiag[i]; -- r[k*ldr+i] = temp; -- } -+ /** compute the modified diagonal element of R and -+ the modified element of (Q^T*b,0). **/ -+ -+ r[kk] = _cos * r[kk] + _sin * sdiag[k]; -+ temp = _cos * wa[k] + _sin * qtbpj; -+ qtbpj = -_sin * wa[k] + _cos * qtbpj; -+ wa[k] = temp; -+ -+ /** accumulate the tranformation in the row of S. **/ -+ -+ for (i = k + 1; i < n; i++) { -+ temp = _cos * r[k * ldr + i] + _sin * sdiag[i]; -+ sdiag[i] = -_sin * r[k * ldr + i] + _cos * sdiag[i]; -+ r[k * ldr + i] = temp; - } - } - -- /** Store the diagonal element of S and restore -+ L90: -+ /** store the diagonal element of S and restore - the corresponding diagonal element of R. **/ -- Sdiag[j] = r[j*ldr+j]; -- r[j*ldr+j] = x[j]; -+ -+ sdiag[j] = r[j * ldr + j]; -+ r[j * ldr + j] = x[j]; - } - -- /*** Solve the triangular system for z. If the system is singular, then -- obtain a least-squares solution. ***/ -+/*** qrsolv: solve the triangular system for z. If the system is -+ singular, then obtain a least squares solution. ***/ - - nsing = n; - for (j = 0; j < n; j++) { -- if (Sdiag[j] == 0 && nsing == n) -+ if (sdiag[j] == 0 && nsing == n) - nsing = j; - if (nsing < n) -- W[j] = 0; -+ wa[j] = 0; - } - -- for (j = nsing-1; j >= 0; j--) { -+ for (j = nsing - 1; j >= 0; j--) { - sum = 0; -- for (i = j+1; i < nsing; i++) -- sum += r[j*ldr+i] * W[i]; -- W[j] = (W[j] - sum) / Sdiag[j]; -+ for (i = j + 1; i < nsing; i++) -+ sum += r[j * ldr + i] * wa[i]; -+ wa[j] = (wa[j] - sum) / sdiag[j]; - } - -- /*** Permute the components of z back to components of x. ***/ -+/*** qrsolv: permute the components of z back to components of x. ***/ - - for (j = 0; j < n; j++) -- x[Pivot[j]] = W[j]; -+ x[ipvt[j]] = wa[j]; - - } /*** lm_qrsolv. ***/ - --/******************************************************************************/ --/* lm_enorm (Euclidean norm) */ --/******************************************************************************/ - --static double lm_enorm(int n, const double* x) -+/*****************************************************************************/ -+/* lm_enorm (Euclidean norm) */ -+/*****************************************************************************/ -+ -+double lm_enorm(const int n, const double *const x) -+{ - /* This function calculates the Euclidean norm of an n-vector x. - * -- * The Euclidean norm is computed by accumulating the sum of squares -- * in three different sums. The sums of squares for the small and large -- * components are scaled so that no overflows occur. Non-destructive -- * underflows are permitted. Underflows and overflows do not occur in -- * the computation of the unscaled sum of squares for the intermediate -- * components. The definitions of small, intermediate and large components -+ * The Euclidean norm is computed by accumulating the sum of -+ * squares in three different sums. The sums of squares for the -+ * small and large components are scaled so that no overflows -+ * occur. Non-destructive underflows are permitted. Underflows -+ * and overflows do not occur in the computation of the unscaled -+ * sum of squares for the intermediate components. -+ * The definitions of small, intermediate and large components - * depend on two constants, LM_SQRT_DWARF and LM_SQRT_GIANT. The main -- * restrictions on these constants are that LM_SQRT_DWARF**2 not underflow -- * and LM_SQRT_GIANT**2 not overflow. -+ * restrictions on these constants are that LM_SQRT_DWARF**2 not -+ * underflow and LM_SQRT_GIANT**2 not overflow. - * - * Parameters: - * -@@ -1067,9 +1160,8 @@ - * - * x is an INPUT array of length n. - */ --{ - int i; -- double agiant, s1, s2, s3, xabs, x1max, x3max; -+ double agiant, s1, s2, s3, xabs, x1max, x3max, temp; - - s1 = 0; - s2 = 0; -@@ -1078,27 +1170,33 @@ - x3max = 0; - agiant = LM_SQRT_GIANT / n; - -- /** Sum squares. **/ -+ /** sum squares. **/ -+ - for (i = 0; i < n; i++) { - xabs = fabs(x[i]); - if (xabs > LM_SQRT_DWARF) { -- if (xabs < agiant) { -- s2 += SQR(xabs); -- } else if (xabs > x1max) { -- s1 = 1 + s1 * SQR(x1max / xabs); -+ if ( xabs < agiant ) { -+ s2 += xabs * xabs; -+ } else if ( xabs > x1max ) { -+ temp = x1max / xabs; -+ s1 = 1 + s1 * SQR(temp); - x1max = xabs; - } else { -- s1 += SQR(xabs / x1max); -+ temp = xabs / x1max; -+ s1 += SQR(temp); - } -- } else if (xabs > x3max) { -- s3 = 1 + s3 * SQR(x3max / xabs); -+ } else if ( xabs > x3max ) { -+ temp = x3max / xabs; -+ s3 = 1 + s3 * SQR(temp); - x3max = xabs; - } else if (xabs != 0) { -- s3 += SQR(xabs / x3max); -+ temp = xabs / x3max; -+ s3 += SQR(temp); - } - } - -- /** Calculate the norm. **/ -+ /** calculation of norm. **/ -+ - if (s1 != 0) - return x1max * sqrt(s1 + (s2 / x1max) / x1max); - else if (s2 != 0) -@@ -1110,3 +1208,80 @@ - return x3max * sqrt(s3); - - } /*** lm_enorm. ***/ -+ -+ -+/*****************************************************************************/ -+/* lm_fnorm (Euclidean norm of difference) */ -+/*****************************************************************************/ -+ -+double lm_fnorm(const int n, const double *const x, const double *const y) -+{ -+/* This function calculates the Euclidean norm of an n-vector x-y. -+ * -+ * The Euclidean norm is computed by accumulating the sum of -+ * squares in three different sums. The sums of squares for the -+ * small and large components are scaled so that no overflows -+ * occur. Non-destructive underflows are permitted. Underflows -+ * and overflows do not occur in the computation of the unscaled -+ * sum of squares for the intermediate components. -+ * The definitions of small, intermediate and large components -+ * depend on two constants, LM_SQRT_DWARF and LM_SQRT_GIANT. The main -+ * restrictions on these constants are that LM_SQRT_DWARF**2 not -+ * underflow and LM_SQRT_GIANT**2 not overflow. -+ * -+ * Parameters: -+ * -+ * n is a positive integer INPUT variable. -+ * -+ * x, y are INPUT arrays of length n. -+ */ -+ if (!y) -+ return lm_enorm(n, x); -+ int i; -+ double agiant, s1, s2, s3, xabs, x1max, x3max, temp; -+ -+ s1 = 0; -+ s2 = 0; -+ s3 = 0; -+ x1max = 0; -+ x3max = 0; -+ agiant = LM_SQRT_GIANT / n; -+ -+ /** sum squares. **/ -+ -+ for (i = 0; i < n; i++) { -+ xabs = fabs(x[i]-y[i]); -+ if (xabs > LM_SQRT_DWARF) { -+ if ( xabs < agiant ) { -+ s2 += xabs * xabs; -+ } else if ( xabs > x1max ) { -+ temp = x1max / xabs; -+ s1 = 1 + s1 * SQR(temp); -+ x1max = xabs; -+ } else { -+ temp = xabs / x1max; -+ s1 += SQR(temp); -+ } -+ } else if ( xabs > x3max ) { -+ temp = x3max / xabs; -+ s3 = 1 + s3 * SQR(temp); -+ x3max = xabs; -+ } else if (xabs != 0) { -+ temp = xabs / x3max; -+ s3 += SQR(temp); -+ } -+ } -+ -+ /** calculation of norm. **/ -+ -+ if (s1 != 0) -+ return x1max * sqrt(s1 + (s2 / x1max) / x1max); -+ else if (s2 != 0) -+ if (s2 >= x3max) -+ return sqrt(s2 * (1 + (x3max / s2) * (x3max * s3))); -+ else -+ return sqrt(x3max * ((s2 / x3max) + (x3max * s3))); -+ else -+ return x3max * sqrt(s3); -+ -+} /*** lm_fnorm. ***/ -diff --git a/src/external/lmfit/lmmin.h b/src/external/lmfit/lmmin.h -index 17b4880..d2ccfae 100644 ---- a/src/external/lmfit/lmmin.h -+++ b/src/external/lmfit/lmmin.h -@@ -17,9 +17,15 @@ - - #include "lmstruct.h" - --/*! \brief -- * Levenberg-Marquardt minimization. -- * -+/* Levenberg-Marquardt minimization. */ -+void lmmin( -+ const int n_par, double* par, const int m_dat, const double* y, -+ const void* data, -+ void (*evaluate)( -+ const double* par, const int m_dat, const void* data, -+ double* fvec, int* userbreak), -+ const lm_control_struct* control, lm_status_struct* status); -+/* - * This routine contains the core algorithm of our library. - * - * It minimizes the sum of the squares of m nonlinear functions -@@ -29,14 +35,16 @@ - * - * Parameters: - * -- * \param[in] n_par The number of variables (INPUT, positive integer). -- * \param par The parameters to be fitted -- * x is the solution vector (INPUT/OUTPUT, array of length n). -+ * n_par is the number of variables (INPUT, positive integer). -+ * -+ * par is the solution vector (INPUT/OUTPUT, array of length n). - * On input it must be set to an estimated solution. - * On output it yields the final estimate of the solution. - * -- * m is the number of functions to be minimized (INPUT, positive integer). -+ * m_dat is the number of functions to be minimized (INPUT, positive integer). - * It must fulfill m>=n. -+ * -+ * y contains data to be fitted. Use a null pointer if there are no data. - * - * data is a pointer that is ignored by lmmin; it is however forwarded - * to the user-supplied functions evaluate and printout. -@@ -56,9 +64,9 @@ - * status contains OUTPUT variables that inform about the fit result, - * as declared and explained in lmstruct.h - */ --void lmmin( const int n_par, double *par, const int m_dat, const void *data, -- void (*evaluate) (const double *par, const int m_dat, const void *data, -- double *fvec, int *userbreak), -- const lm_control_struct *control, lm_status_struct *status ); -+ -+/* Refined calculation of Eucledian norm. */ -+double lm_enorm(const int, const double*); -+double lm_fnorm(const int, const double*, const double*); - - #endif /* LMMIN_H */ -diff --git a/src/external/lmfit/lmstruct.h b/src/external/lmfit/lmstruct.h -index d545ff1..1f513b3 100644 ---- a/src/external/lmfit/lmstruct.h -+++ b/src/external/lmfit/lmstruct.h -@@ -39,23 +39,23 @@ - stepbound itself. In most cases stepbound should lie - in the interval (0.1,100.0). Generally, the value - 100.0 is recommended. */ -- int patience; /* Used to set the maximum number of function evaluations -+ int patience; /* Used to set the maximum number of function evaluations - to patience*(number_of_parameters+1). */ -- int scale_diag; /* If 1, the variables will be rescaled internally. -+ int scale_diag; /* If 1, the variables will be rescaled internally. - Recommended value is 1. */ - FILE* msgfile; /* Progress messages will be written to this file. */ -- int verbosity; /* OR'ed: 1: print some messages; 2: print Jacobian. */ -- int n_maxpri; /* -1, or max number of parameters to print. */ -- int m_maxpri; /* -1, or max number of residuals to print. */ -+ int verbosity; /* OR'ed: 1: print some messages; 2: print Jacobian. */ -+ int n_maxpri; /* -1, or max number of parameters to print. */ -+ int m_maxpri; /* -1, or max number of residuals to print. */ - } lm_control_struct; - - /* Collection of output parameters for status info. */ - typedef struct { -- double fnorm; /* norm of the residue vector fvec. */ -- int nfev; /* actual number of iterations. */ -- int outcome; /* Status indicator. Nonnegative values are used as index -- for the message text lm_infmsg, set in lmmin.c. */ -- int userbreak; /* Set when function evaluation requests termination. */ -+ double fnorm; /* norm of the residue vector fvec. */ -+ int nfev; /* actual number of iterations. */ -+ int outcome; /* Status indicator. Nonnegative values are used as index -+ for the message text lm_infmsg, set in lmmin.c. */ -+ int userbreak; /* Set when function evaluation requests termination. */ - } lm_status_struct; - - /* Preset (and recommended) control parameter settings. */ -diff --git a/src/gromacs/CMakeLists.txt b/src/gromacs/CMakeLists.txt -index 6f1b3e9..7aab572 100644 ---- a/src/gromacs/CMakeLists.txt -+++ b/src/gromacs/CMakeLists.txt -@@ -138,10 +138,6 @@ - tmpi_get_source_list(THREAD_MPI_SOURCES ${CMAKE_SOURCE_DIR}/src/external/thread_mpi/src) - list(APPEND LIBGROMACS_SOURCES ${THREAD_MPI_SOURCES}) - --get_lmfit_properties(LMFIT_SOURCES LMFIT_LIBRARIES_TO_LINK LMFIT_INCLUDE_DIRECTORY LMFIT_INCLUDE_DIR_ORDER) --include_directories(${LMFIT_INCLUDE_DIR_ORDER} SYSTEM "${LMFIT_INCLUDE_DIRECTORY}") --list(APPEND LIBGROMACS_SOURCES ${LMFIT_SOURCES}) -- - configure_file(version.h.cmakein version.h) - gmx_install_headers( - analysisdata.h -@@ -260,6 +256,7 @@ - VERSION ${LIBRARY_VERSION} - COMPILE_FLAGS "${OpenMP_C_FLAGS}") - -+manage_lmfit() - gmx_write_installed_header_list() - - # Only install the library in mdrun-only mode if it is actually necessary -diff --git a/src/gromacs/correlationfunctions/expfit.cpp b/src/gromacs/correlationfunctions/expfit.cpp -index 4fc9fd4..d2cbd4b 100644 ---- a/src/gromacs/correlationfunctions/expfit.cpp -+++ b/src/gromacs/correlationfunctions/expfit.cpp -@@ -3,7 +3,7 @@ - * - * Copyright (c) 1991-2000, University of Groningen, The Netherlands. - * Copyright (c) 2001-2004, The GROMACS development team. -- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by -+ * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by - * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, - * and including many others, as listed in the AUTHORS file in the - * top-level source directory and at http://www.gromacs.org. -@@ -48,15 +48,10 @@ - - #include - --#include -- - #include -- --#include - - #include "gromacs/correlationfunctions/integrate.h" - #include "gromacs/fileio/xvgr.h" --#include "gromacs/math/functions.h" - #include "gromacs/math/vec.h" - #include "gromacs/utility/fatalerror.h" - #include "gromacs/utility/futil.h" -@@ -394,9 +389,6 @@ - } - } - --/*! \brief function type for passing to fitting routine */ --typedef double (*t_lmcurve)(double x, const double *a); -- - /*! \brief array of fitting functions corresponding to the pre-defined types */ - t_lmcurve lmcurves[effnNR+1] = { - lmc_exp_one_parm, lmc_exp_one_parm, lmc_exp_two_parm, -@@ -414,104 +406,6 @@ - return 0.0; - } - return lmcurves[eFitFn](x, parm); --} -- --/*! \brief lmfit_exp supports fitting of different functions -- * -- * This routine calls the Levenberg-Marquardt non-linear fitting -- * routine for fitting a data set with errors to a target function. -- * Fitting routines included in gromacs in src/external/lmfit. -- */ --static gmx_bool lmfit_exp(int nfit, -- const double x[], -- const double y[], -- const double dy[], -- double parm[], -- gmx_bool bVerbose, -- int eFitFn, -- int nfix) --{ -- double chisq, ochisq; -- gmx_bool bCont; -- int j; -- int maxiter = 100; -- lm_control_struct control; -- lm_status_struct *status; -- int nparam = effnNparams(eFitFn); -- int p2; -- gmx_bool bSkipLast; -- -- if ((eFitFn < 0) || (eFitFn >= effnNR)) -- { -- fprintf(stderr, "fitfn = %d, should be in the range 0..%d\n", -- eFitFn, effnNR-1); -- return FALSE; -- } -- /* Using default control structure for double precision fitting that -- * comes with the lmfit package (i.e. from the include file). -- */ -- control = lm_control_double; -- control.verbosity = (bVerbose ? 1 : 0); -- control.n_maxpri = 0; -- control.m_maxpri = 0; -- -- snew(status, 1); -- /* Initial params */ -- chisq = 1e12; -- j = 0; -- if (bVerbose) -- { -- printf("%4s %10s Parameters\n", "Step", "chi^2"); -- } -- /* Check whether we have to skip some params */ -- if (nfix > 0) -- { -- do -- { -- p2 = 1 << (nparam-1); -- bSkipLast = ((p2 & nfix) == p2); -- if (bSkipLast) -- { -- nparam--; -- nfix -= p2; -- } -- } -- while ((nparam > 0) && (bSkipLast)); -- if (bVerbose) -- { -- printf("Using %d out of %d parameters\n", nparam, effnNparams(eFitFn)); -- } -- } -- do -- { -- ochisq = chisq; -- gmx_lmcurve(nparam, parm, nfit, x, y, dy, -- lmcurves[eFitFn], &control, status); -- chisq = gmx::square(status->fnorm); -- if (bVerbose) -- { -- printf("status: fnorm = %g, nfev = %d, userbreak = %d\noutcome = %s\n", -- status->fnorm, status->nfev, status->userbreak, -- lm_infmsg[status->outcome]); -- } -- if (bVerbose) -- { -- int mmm; -- printf("%4d %8g", j, chisq); -- for (mmm = 0; (mmm < effnNparams(eFitFn)); mmm++) -- { -- printf(" %8g", parm[mmm]); -- } -- printf("\n"); -- } -- j++; -- bCont = (fabs(ochisq - chisq) > fabs(control.ftol*chisq)); -- } -- while (bCont && (j < maxiter)); -- -- sfree(status); -- -- return TRUE; - } - - /*! \brief Ensure the fitting parameters are well-behaved. -diff --git a/src/gromacs/correlationfunctions/gmx_lmcurve.cpp b/src/gromacs/correlationfunctions/gmx_lmcurve.cpp -index f3a103c..8b3870e 100644 ---- a/src/gromacs/correlationfunctions/gmx_lmcurve.cpp -+++ b/src/gromacs/correlationfunctions/gmx_lmcurve.cpp -@@ -1,7 +1,7 @@ - /* - * This file is part of the GROMACS molecular simulation package. - * -- * Copyright (c) 2016, by the GROMACS development team, led by -+ * Copyright (c) 2016,2018, by the GROMACS development team, led by - * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, - * and including many others, as listed in the AUTHORS file in the - * top-level source directory and at http://www.gromacs.org. -@@ -38,14 +38,30 @@ - * Defines a driver routine for lmfit, and a callback for it to use. - * - * \author David van der Spoel -+ * \author Mark Abraham - * \ingroup module_correlationfunctions - */ - #include "gmxpre.h" - - #include "gmx_lmcurve.h" - -+#include "config.h" -+ -+#include -+ -+#if HAVE_LMFIT - #include - #include -+#endif -+ -+#include "gromacs/correlationfunctions/expfit.h" -+#include "gromacs/math/functions.h" -+#include "gromacs/utility/fatalerror.h" -+#include "gromacs/utility/smalloc.h" -+ -+#if HAVE_LMFIT -+ -+extern t_lmcurve lmcurves[effnNR+1]; - - typedef struct { - const double* t; -@@ -73,7 +89,8 @@ - *info = 0; - } - --void gmx_lmcurve( -+//! Calls lmmin with the given data, with callback function \c f. -+static void gmx_lmcurve( - const int n_par, double* par, const int m_dat, - const double* t, const double* y, const double *dy, - double (*f)(double t, const double* par), -@@ -81,6 +98,114 @@ - { - lmcurve_data_struct data = { t, y, dy, f }; - -- lmmin(n_par, par, m_dat, (const void*)&data, lmcurve_evaluate, -+ lmmin(n_par, par, m_dat, nullptr, (const void*)&data, lmcurve_evaluate, - control, status); - } -+ -+#endif -+ -+bool lmfit_exp(int nfit, -+ const double x[], -+ const double y[], -+ const double dy[], -+ double parm[], -+ bool bVerbose, -+ int eFitFn, -+ int nfix) -+{ -+ if ((eFitFn < 0) || (eFitFn >= effnNR)) -+ { -+ fprintf(stderr, "fitfn = %d, should be in the range 0..%d\n", -+ eFitFn, effnNR-1); -+ return false; -+ } -+#if HAVE_LMFIT -+ double chisq, ochisq; -+ gmx_bool bCont; -+ int j; -+ int maxiter = 100; -+ lm_control_struct control; -+ lm_status_struct *status; -+ int nparam = effnNparams(eFitFn); -+ int p2; -+ gmx_bool bSkipLast; -+ -+ /* Using default control structure for double precision fitting that -+ * comes with the lmfit package (i.e. from the include file). -+ */ -+ control = lm_control_double; -+ control.verbosity = (bVerbose ? 1 : 0); -+ control.n_maxpri = 0; -+ control.m_maxpri = 0; -+ -+ snew(status, 1); -+ /* Initial params */ -+ chisq = 1e12; -+ j = 0; -+ if (bVerbose) -+ { -+ printf("%4s %10s Parameters\n", "Step", "chi^2"); -+ } -+ /* Check whether we have to skip some params */ -+ if (nfix > 0) -+ { -+ do -+ { -+ p2 = 1 << (nparam-1); -+ bSkipLast = ((p2 & nfix) == p2); -+ if (bSkipLast) -+ { -+ nparam--; -+ nfix -= p2; -+ } -+ } -+ while ((nparam > 0) && (bSkipLast)); -+ if (bVerbose) -+ { -+ printf("Using %d out of %d parameters\n", nparam, effnNparams(eFitFn)); -+ } -+ } -+ do -+ { -+ ochisq = chisq; -+ gmx_lmcurve(nparam, parm, nfit, x, y, dy, -+ lmcurves[eFitFn], &control, status); -+ chisq = gmx::square(status->fnorm); -+ if (bVerbose) -+ { -+ printf("status: fnorm = %g, nfev = %d, userbreak = %d\noutcome = %s\n", -+ status->fnorm, status->nfev, status->userbreak, -+ lm_infmsg[status->outcome]); -+ } -+ if (bVerbose) -+ { -+ int mmm; -+ printf("%4d %8g", j, chisq); -+ for (mmm = 0; (mmm < effnNparams(eFitFn)); mmm++) -+ { -+ printf(" %8g", parm[mmm]); -+ } -+ printf("\n"); -+ } -+ j++; -+ bCont = (fabs(ochisq - chisq) > fabs(control.ftol*chisq)); -+ } -+ while (bCont && (j < maxiter)); -+ -+ sfree(status); -+#else -+ gmx_fatal(FARGS, "This build of GROMACS was not configured with support " -+ "for lmfit, so the requested fitting cannot be performed. " -+ "See the install guide for instructions on how to build " -+ "GROMACS with lmfit supported."); -+ GMX_UNUSED_VALUE(nfit); -+ GMX_UNUSED_VALUE(x); -+ GMX_UNUSED_VALUE(y); -+ GMX_UNUSED_VALUE(dy); -+ GMX_UNUSED_VALUE(parm); -+ GMX_UNUSED_VALUE(bVerbose); -+ GMX_UNUSED_VALUE(eFitFn); -+ GMX_UNUSED_VALUE(nfix); -+#endif -+ return true; -+} -diff --git a/src/gromacs/correlationfunctions/gmx_lmcurve.h b/src/gromacs/correlationfunctions/gmx_lmcurve.h -index 0f6c957..fa77671 100644 ---- a/src/gromacs/correlationfunctions/gmx_lmcurve.h -+++ b/src/gromacs/correlationfunctions/gmx_lmcurve.h -@@ -1,7 +1,7 @@ - /* - * This file is part of the GROMACS molecular simulation package. - * -- * Copyright (c) 2016, by the GROMACS development team, led by -+ * Copyright (c) 2016,2018, by the GROMACS development team, led by - * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, - * and including many others, as listed in the AUTHORS file in the - * top-level source directory and at http://www.gromacs.org. -@@ -43,13 +43,22 @@ - #ifndef GMX_CORRELATION_FUNCTIONS_GMX_LMCURVE_H - #define GMX_CORRELATION_FUNCTIONS_GMX_LMCURVE_H - --#include -+/*! \brief function type for passing to fitting routine */ -+typedef double (*t_lmcurve)(double x, const double *a); - --//! Calls lmmin with the given data, with callback function \c f. --void gmx_lmcurve( const int n_par, double *par, const int m_dat, -- const double *t, const double *y, const double *dy, -- double (*f)(double t, const double *par ), -- const lm_control_struct *control, -- lm_status_struct *status ); -+/*! \brief lmfit_exp supports fitting of different functions -+ * -+ * This routine calls the Levenberg-Marquardt non-linear fitting -+ * routine for fitting a data set with errors to a target function. -+ * Fitting routines included in gromacs in src/external/lmfit. -+ */ -+bool lmfit_exp(int nfit, -+ const double x[], -+ const double y[], -+ const double dy[], -+ double parm[], -+ bool bVerbose, -+ int eFitFn, -+ int nfix); - - #endif -diff --git a/src/gromacs/correlationfunctions/tests/expfit.cpp b/src/gromacs/correlationfunctions/tests/expfit.cpp -index eb93463..5d5bd96 100644 ---- a/src/gromacs/correlationfunctions/tests/expfit.cpp -+++ b/src/gromacs/correlationfunctions/tests/expfit.cpp -@@ -1,7 +1,7 @@ - /* - * This file is part of the GROMACS molecular simulation package. - * -- * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by -+ * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by - * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, - * and including many others, as listed in the AUTHORS file in the - * top-level source directory and at http://www.gromacs.org. -@@ -43,6 +43,8 @@ - #include "gmxpre.h" - - #include "gromacs/correlationfunctions/expfit.h" -+ -+#include "config.h" - - #include - -@@ -152,6 +154,10 @@ - //static var - std::vector ExpfitTest::data_; - -+// TODO calling test() leads to a fatal error, which we could in -+// principle test for. -+#if HAVE_LMFIT -+ - TEST_F (ExpfitTest, EffnEXP1) { - double param[] = {25}; - test(effnEXP1, param, 1e-5, 0); -@@ -202,6 +208,8 @@ - test(effnPRES, param, 1e-4, 1); - } - -+#endif -+ - } - - } diff --git a/gromacs-2018.8.tar.gz b/gromacs-2025.3.tar.gz similarity index 61% rename from gromacs-2018.8.tar.gz rename to gromacs-2025.3.tar.gz index 88fbab0bb6df4f0ad0ccad15c86c49e503ee2aa1..9c5c10ac356cfeb23b2e5fac956abecfb3147fa3 100644 Binary files a/gromacs-2018.8.tar.gz and b/gromacs-2025.3.tar.gz differ diff --git a/gromacs-README.fedora b/gromacs-README.fedora deleted file mode 100644 index 7e345c4d31c5ce2dd4fef215957eafcb94fa297e..0000000000000000000000000000000000000000 --- a/gromacs-README.fedora +++ /dev/null @@ -1,22 +0,0 @@ -Wed Feb 24 2016 -Dominik Mierzejewski - -Some notes about the Fedora GROMACS package: - -- Per upstream change, since version 5.1, we're no longer shipping -any g_* binaries or symlinks. All functionality is now available -in the main gmx binary. For instance, g_anadock is replaced with -gmx anadock. - -- All binaries are available in single and dual precision. -The binaries with the _d suffix are double precision versions. -For instance, gmx is single precision and gmx_d is double -precision. - -- MPI enabled binaries are compiled for both MPICH and OpenMPI -and available in gromacs-mpich and gromacs-openmpi subpackages, -respectively. These, too, contain both single and double precision -versions. Single precision versions have _mpich (_openmpi) suffix, -while double precision versions have _mpich_d (_openmpi_d) suffix. -For instance g_mdrun_mpich (g_mdrun_openmpi) and g_mdrun_mpich_d -(g_mdrun_openmpi_d). diff --git a/gromacs-dssp-path.patch b/gromacs-dssp-path.patch deleted file mode 100644 index d3abfca57be61964f65ddf928e8aff0f31fb92ca..0000000000000000000000000000000000000000 --- a/gromacs-dssp-path.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git a/src/gromacs/gmxana/gmx_do_dssp.cpp b/src/gromacs/gmxana/gmx_do_dssp.cpp -index a8aab1bc2..184592b7e 100644 ---- a/src/gromacs/gmxana/gmx_do_dssp.cpp -+++ b/src/gromacs/gmxana/gmx_do_dssp.cpp -@@ -445,7 +445,7 @@ int gmx_do_dssp(int argc, char *argv[]) - "calling the dssp program. If you do not have the dssp program,", - "get it from http://swift.cmbi.ru.nl/gv/dssp. [THISMODULE] assumes ", - "that the dssp executable is located in ", -- "[TT]/usr/local/bin/dssp[tt]. If this is not the case, then you should", -+ "[TT]/usr/bin/mkdssp[tt]. If this is not the case, then you should", - "set an environment variable [TT]DSSP[tt] pointing to the dssp", - "executable, e.g.: [PAR]", - "[TT]setenv DSSP /opt/dssp/bin/dssp[tt][PAR]", -@@ -590,7 +590,7 @@ int gmx_do_dssp(int argc, char *argv[]) - - if ((dptr = getenv("DSSP")) == nullptr) - { -- dptr = "/usr/local/bin/dssp"; -+ dptr = "/usr/bin/mkdssp"; - } - if (!gmx_fexist(dptr)) - { diff --git a/gromacs-issue-2366.patch b/gromacs-issue-2366.patch deleted file mode 100644 index 7c080106ce2eebbfadafdcb0f2ea9b18a4233dac..0000000000000000000000000000000000000000 --- a/gromacs-issue-2366.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff --git a/src/gromacs/hardware/tests/hardwaretopology.cpp b/src/gromacs/hardware/tests/hardwaretopology.cpp -index ed7897b01..c31d4b9cd 100644 ---- a/src/gromacs/hardware/tests/hardwaretopology.cpp -+++ b/src/gromacs/hardware/tests/hardwaretopology.cpp -@@ -185,12 +185,14 @@ TEST(HardwareTopologyTest, NumaCacheSelfconsistency) - } - } - -+#ifndef __aarch64__ - // Check cache. The hwloc cache detection is fragile and can report - // 0 for line size or associativity (=unknown), so we just check the size. - for (auto &c : hwTop.machine().caches) - { - EXPECT_GT(c.size, 0); - } -+#endif - } - } - diff --git a/gromacs.spec b/gromacs.spec index 25a1fed1a0cf1201e73f5ccada58011f84bab36b..6584aa1f1bd74bf489817d7fdb48c3a59fc3dcf3 100644 --- a/gromacs.spec +++ b/gromacs.spec @@ -1,3 +1,7 @@ +%global __arch_install_post %{nil} +%global debug_package %{nil} +%global __debug_install_post %{nil} +%global __os_install_post %{nil} #global _rcname rc1 #global _rc -%%_rcname @@ -35,54 +39,13 @@ %endif Name: gromacs -Version: 2018.8 +Version: 2025.3 Release: 1%{?dist} Summary: Fast, Free and Flexible Molecular Dynamics License: GPLv2+ URL: http://www.gromacs.org - -Source0: ftp://ftp.gromacs.org/pub/gromacs/gromacs-%{version}%{?_rc}.tar.gz -Source1: ftp://ftp.gromacs.org/pub/manual/manual-%{version}%{?_rc}.pdf -# Too britle sind 2018.2 -Source2: http://gerrit.gromacs.org/download/regressiontests-%{version}%{?_rc}.tar.gz -Source3: gromacs-README.fedora -# fix path to packaged dssp -# https://bugzilla.redhat.com/show_bug.cgi?id=1203754 -Patch0: gromacs-dssp-path.patch -# add support for lmfit-7.0, can be dropped in gromacs-2019 -# https://redmine.gromacs.org/issues/2533 -Patch1: facb927.diff -# enable some test on aarch64 - https://redmine.gromacs.org/issues/2366 -# bug#1558206 -Patch2: gromacs-issue-2366.patch -BuildRequires: gcc-c++ -BuildRequires: cmake3 >= 3.4.3 -BuildRequires: openblas-devel -BuildRequires: fftw-devel -BuildRequires: gsl-devel -BuildRequires: hwloc -BuildRequires: hwloc-devel -BuildRequires: libX11-devel -BuildRequires: lmfit-devel >= 6.0 -BuildRequires: motif-devel -%if %{with_opencl} -BuildRequires: ocl-icd-devel -BuildRequires: opencl-headers -%if 0%{?fedora} -Recommends: gromacs-opencl = %{version}-%{release} -%endif -%endif -BuildRequires: tng-devel -BuildRequires: bash-completion -%define compdir %(pkg-config --variable=completionsdir bash-completion) -%if "%{compdir}" == "" -%define compdir "/etc/bash_completion.d" -%endif -Requires: gromacs-common = %{version}-%{release} -Requires: gromacs-libs = %{version}-%{release} -Obsoletes: gromacs-ngmx < 5.0.4-1 -Obsoletes: gromacs-csh < 2016.1-2 -Obsoletes: gromacs-zsh < 2016.1-2 +Source0: http://ftp.gromacs.org/gromacs/%{name}-%{version}.tar.gz +# Source0: gromacs-2025.3.tar.gz %description GROMACS is a versatile and extremely well optimized package to perform @@ -101,741 +64,108 @@ to install one of the MPI parallellized packages. N.B. All binaries have names starting with g_, for example mdrun has been renamed to g_mdrun. - -%package common -Summary: GROMACS shared data and documentation -BuildArch: noarch -Provides: gromacs-bash = %{version}-%{release} -Obsoletes: gromacs-bash < 5.0.4-1 - -%description common -GROMACS is a versatile and extremely well optimized package to perform -molecular dynamics computer simulations and subsequent trajectory analysis. -It is developed for bio-molecules like proteins, but the extremely high -performance means it is used also in several other field like polymer chemistry -and solid state physics. - -This package includes architecture independent data and HTML documentation. - - -%if %{with_opencl} -%package opencl -Summary: GROMACS OpenCL kernels -# suggest installing a GPU-based OpenCL implementation -%if 0%{?fedora} -Suggests: beignet -Suggests: mesa-libOpenCL -# or at least a CPU-based one -Suggests: pocl -%endif - -%description opencl -GROMACS is a versatile and extremely well optimized package to perform -molecular dynamics computer simulations and subsequent trajectory analysis. -It is developed for bio-molecules like proteins, but the extremely high -performance means it is used also in several other field like polymer chemistry -and solid state physics. - -This package includes the OpenCL kernels. -%endif - - -%package doc -Summary: GROMACS manual -BuildArch: noarch -Obsoletes: gromacs-common < 5.0.5-2 - -%description doc -GROMACS is a versatile and extremely well optimized package to perform -molecular dynamics computer simulations and subsequent trajectory analysis. -It is developed for bio-molecules like proteins, but the extremely high -performance means it is used also in several other field like polymer chemistry -and solid state physics. - -This package the manual in PDF format. - - -%package devel -Summary: GROMACS header files and development libraries -Requires: gromacs-libs = %{version}-%{release} -Obsoletes: gromacs-mpich-devel < 2016-0.1.20160318gitbec9c87 -Obsoletes: gromacs-openmpi-devel < 2016-0.1.20160318gitbec9c87 - -%description devel -GROMACS is a versatile and extremely well optimized package to perform -molecular dynamics computer simulations and subsequent trajectory analysis. -It is developed for bio-molecules like proteins, but the extremely high -performance means it is used also in several other field like polymer chemistry -and solid state physics. - -This package contains header files and development libraries for the GROMACS -molecular dynamics software. You need it if you want to write your own analysis -programs. - - -%package libs -Summary: GROMACS shared libraries - -%description libs -GROMACS is a versatile and extremely well optimized package to perform -molecular dynamics computer simulations and subsequent trajectory analysis. -It is developed for bio-molecules like proteins, but the extremely high -performance means it is used also in several other field like polymer chemistry -and solid state physics. - -This package contains libraries needed for operation of GROMACS. - - -%package openmpi -Summary: GROMACS Open MPI binaries and libraries -Requires: gromacs-common = %{version}-%{release} -%if %{with_opencl} -%if 0%{?fedora} -Recommends: gromacs-opencl = %{version}-%{release} -%endif -%endif -Obsoletes: gromacs-openmpi-libs < 2016-0.1.20160318gitbec9c87 -BuildRequires: openmpi-devel - -%description openmpi -GROMACS is a versatile and extremely well optimized package to perform -molecular dynamics computer simulations and subsequent trajectory analysis. -It is developed for bio-molecules like proteins, but the extremely high -performance means it is used also in several other field like polymer chemistry -and solid state physics. - -mdrun has been compiled with thread parallellization (for running on -a single node) and with Open MPI (for running on multiple nodes). -This package single and double precision binaries and libraries. - - -%package mpich -Summary: GROMACS MPICH binaries and libraries -Requires: gromacs-common = %{version}-%{release} -%if %{with_opencl} -%if 0%{?fedora} -Recommends: gromacs-opencl = %{version}-%{release} -%endif -%endif -Obsoletes: gromacs-mpich-libs < 2016-0.1.20160318gitbec9c87 -BuildRequires: mpich-devel - -%description mpich -GROMACS is a versatile and extremely well optimized package to perform -molecular dynamics computer simulations and subsequent trajectory analysis. -It is developed for bio-molecules like proteins, but the extremely high -performance means it is used also in several other field like polymer chemistry -and solid state physics. - -mdrun has been compiled with thread parallellization (for running on -a single node) and with MPICH (for running on multiple nodes). -This package single and double precision binaries and libraries. - - %prep -%setup -q %{?SOURCE2:-a 2} -n gromacs-%{version}%{?_rc} -%patch0 -p1 -%patch1 -p1 -%if 0%{?fedora} <= 29 -%patch2 -p1 -%endif -install -Dpm644 %{SOURCE1} ./serial/docs/manual/gromacs.pdf -# Delete bundled stuff so that it doesn't get used accidentally -# Don't remove tinyxml2 as gromacs needs an old version to build -# test, see: https://redmine.gromacs.org/issues/2389 -rm -r src/external/{fftpack,tng_io,lmfit} - -sed -i 's/set(_timeout [0-9]*)/set(_timeout 300)/' src/testutils/TestMacros.cmake +%setup -n %{name}-%{version} +# %setup -n gromacs-2025.3 %build -# Default options, used for all compilations -%global defopts \\\ - -DBUILD_TESTING:BOOL=ON \\\ - -DCMAKE_SKIP_RPATH:BOOL=ON \\\ - -DCMAKE_SKIP_BUILD_RPATH:BOOL=ON \\\ - -DGMX_BLAS_USER=openblas \\\ - -DGMX_BUILD_UNITTESTS:BOOL=ON \\\ - -DGMX_EXTERNAL_LMFIT:BOOL=ON \\\ - -DGMX_USE_LMFIT=external \\\ - -DGMX_EXTERNAL_TNG:BOOL=ON \\\ - -DGMX_EXTERNAL_TINYXML2:BOOL=OFF \\\ - -DGMX_LAPACK_USER=openblas \\\ - -DGMX_USE_RDTSCP=OFF \\\ - -DGMX_SIMD=%{simd} \\\ - -%if %{with_opencl} -# OpenCL is available for single precision only -%global single -DGMX_GPU:BOOL=ON -DGMX_USE_OPENCL:BOOL=ON -%endif -%global double -DGMX_DOUBLE:BOOL=ON -%global mpi -DGMX_BUILD_MDRUN_ONLY:BOOL=ON -DGMX_MPI:BOOL=ON -DGMX_THREAD_MPI:BOOL=OFF -DGMX_DEFAULT_SUFFIX:BOOL=OFF -DBUILD_SHARED_LIBS:BOOL=OFF - -. /etc/profile.d/modules.sh -for p in '' _d ; do - for mpi in '' mpich openmpi ; do - test -n "${mpi}" && module load mpi/${mpi}-%{_arch} - mkdir -p ${mpi:-serial}${p} - pushd ${mpi:-serial}${p} -# regression test broken on ppc64le, https://redmine.gromacs.org/issues/2734, tested 7.Nov.2018 -# and on i686 and ppc64 with gcc-8.0 (so f28, f27), https://redmine.gromacs.org/issues/2584, tested 7.Nov.2018 - test -z "${mpi}" && cp -al ../regressiontests* tests/ # use with -DREGRESSIONTEST_PATH=${PWD}/tests below - %{cmake3} %{defopts} \ - $(test -n "${mpi}" && echo %{mpi} -DGMX_BINARY_SUFFIX=${MPI_SUFFIX}${p} -DGMX_LIBS_SUFFIX=${MPI_SUFFIX}${p} -DCMAKE_INSTALL_BINDIR=${MPI_BIN}) \ -%if 0%{?fedora} >= 29 -%ifnarch ppc64le - $(test -z "${mpi}" && echo "-DREGRESSIONTEST_PATH=${PWD}/tests") \ -%endif -%else -%ifnarch ppc64le ppc64 i686 - $(test -z "${mpi}" && echo "-DREGRESSIONTEST_PATH=${PWD}/tests") \ -%endif -%endif - $(test -n "$p" && echo %{double} || echo %{?single}) \ - .. - %make_build - popd - test -n "${mpi}" && module unload mpi/${mpi}-%{_arch} - done -done +yum install -y libatomic +export hpckit_ver="25.1.0" +cd /root +wget https://mirrors.huaweicloud.com/kunpeng/archive/HPC/HPCKit/HPCKit_25.1.0_Linux-aarch64.tar.gz +tar xvf HPCKit_25.1.0_Linux-aarch64.tar.gz +cd HPCKit_25.1.0_Linux-aarch64 +sh install.sh -y --prefix=/root +file_path=/root/HPCKit/25.1.0/modulefiles/bisheng +# echo $file_path +export BISHENG_VERSION=`ls $file_path|grep compiler|awk -F "compiler" '{print $2}'` +export HMPI_VERSION=`ls $file_path|grep hmpi|awk -F "hmpi" '{print $2}'` +# echo $BISHENG_VERSION +# echo $HMPI_VERSION +cd /root/ +# yum list | grep kernel +# yum list installed | grep tcl.aarch64 +# yum list installed | grep environment-modules.aarch64 +yum install -y environment-modules +source /etc/profile.d/modules.sh +# yum list installed | grep environment-modules.aarch64 +cd /root/HPCKit/latest +module use modulefiles +module avail +module load bisheng/compiler4.2.0.2/bishengmodule bisheng/hmpi25.1.0/release +module load bisheng/kml25.1.0/kml +module avail +cd /root/ +export cmake_ver='3.28.2' +wget https://github.com/Kitware/CMake/releases/download/v${cmake_ver}/cmake-${cmake_ver}-linux-`arch`.tar.gz +mkdir -p /root/cmake/3.28.2 +tar -xzvf cmake-3.28.2-linux-aarch64.tar.gz -C /root/cmake/3.28.2 --strip-components=1 +ln -s /root/cmake/3.28.2/bin/cmake /usr/bin/cmake +# cmake --version + +cd /root/rpmbuild/BUILD/gromacs-2025.3 +mkdir -p build +cd build +export kp=neon +# ifsme=`lscpu|grep sme` +# ifsve=`lscpu|grep sve` +# ifneon=`lscpu|grep asimd` +kp=neon; +# echo ${kp} +export KML_LIB_PATH=/root/HPCKit/25.1.0/kml/bisheng/lib +cmake ../ -DCMAKE_INSTALL_PREFIX=/root/gromacs-2025.3 -DCMAKE_BUILD_TYPE=Release -DGMX_MPI=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DMPI_C_COMPILER=mpicc -DMPI_CXX_COMPILER=mpicxx -DGMX_INSTALL_LEGACY_API=ON -DGMX_HWLOC=ON -DGMX_EXTERNAL_LAPACK=ON -DGMX_LAPACK_USER=$KML_LIB_PATH/${kp}/libklapack_full.so -DGMX_EXTERNAL_BLAS=ON -DGMX_BLAS_USER=$KML_LIB_PATH/${kp}/kblas/multi/libkblas.so -DGMX_SIMD=ARM_NEON_ASIMD -DGMX_GPU=OFF -DGMX_OPENMP=ON -DGMX_FFT_LIBRARY=fftw3 -DFFTWF_LIBRARY=$KML_LIB_PATH/noarch/libfftw3f.so -DCMAKE_CXX_FLAGS="-L$KML_LIB_PATH/noarch -lkm" -DGMX_SIMD_ARM_SVE_LENGTH=256 +make -j +make install +# /root/gromacs-2025.3/bin/gmx_mpi --version +# export PATH=/root/gromacs-2025.3/bin:$PATH %install -. /etc/profile.d/modules.sh -for p in '' _d ; do - for mpi in '' mpich openmpi ; do - test -n "${mpi}" && module load mpi/${mpi}-%{_arch} - %make_install -C ${mpi:-serial}${p} - test -n "${mpi}" && module unload mpi/${mpi}-%{_arch} - done -done +mkdir -p %{buildroot}/usr/local/bin +mkdir -p %{buildroot}/usr/lib -mkdir -p %{buildroot}%{_docdir}/gromacs -install -pm 644 AUTHORS COPYING README %{buildroot}%{_docdir}/gromacs -# Install manual & packager's note -install -cpm 644 serial/docs/manual/gromacs.pdf %{buildroot}%{_docdir}/gromacs/manual.pdf -install -cpm 644 %{SOURCE3} %{buildroot}%{_docdir}/gromacs/README.fedora +cp -r %_builddir/%{name}-%{version}/build/bin/* %{buildroot}/usr/local/bin/ +cp -r %_builddir/%{name}-%{version}/build/lib/* %{buildroot}/usr/lib/ -pushd %{buildroot} -# rm GMXRC, not needed when installed in /usr -rm ./%{_bindir}/GMXRC* +# cp -r /root/HPCKit/25.1.0/compiler/gcc/lib64/* %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/kml/gcc/lib/noarch/* %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/kml/bisheng/lib/neon/kblas/multi/libkblas.so.25.1.0 %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/kml/bisheng/lib/neon/libklapack_full.so %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/kml/bisheng/lib/neon/libkfftf.* %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/kml/bisheng/lib/noarch/libfftw3f.so.1.0.0 %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/kml/bisheng/lib/noarch/libkm.so.25.1.0 %{buildroot}/usr/lib/ -for bin in demux.pl xplor2gmx.pl; do - mv ./%{_bindir}/$bin ./%{_bindir}/g_${bin} -done - -# Move completion files around -mkdir -p ./%{compdir} -for bin in gmx{,_d}; do - cat ./%{_bindir}/gmx-completion{,-$bin}.bash > ./%{compdir}/${bin} - rm ./%{_bindir}/gmx-completion-${bin}.bash -done -rm ./%{_bindir}/gmx-completion.bash ./%{_libdir}/*mpi*/bin/gmx-completion-*mpi*.bash - -%ldconfig_scriptlets libs - -%check -. /etc/profile.d/modules.sh -for p in '' _d ; do - for mpi in '' mpich openmpi ; do - # https://bugzilla.redhat.com/show_bug.cgi?id=1512229 (tested 6. Nov 2018) -%ifarch i686 armv7hl - test "${mpi}" = "openmpi" && continue -%endif - test -n "${mpi}" && module load mpi/${mpi}-%{_arch} - test -n "${mpi}" && xLD_LIBRARY_PATH=$LD_LIBRARY_PATH:%{buildroot}${MPI_LIB} || xLD_LIBRARY_PATH=%{buildroot}%{_libdir} - LD_LIBRARY_PATH="${xLD_LIBRARY_PATH}" make -C ${mpi:-serial}${p} VERBOSE=1 %{?_smp_mflags} check - test -n "${mpi}" && module unload mpi/${mpi}-%{_arch} - done -done - -%files -%{_bindir}/gmx* -%{_bindir}/g_* +# cp -r /root/HPCKit/25.1.0/hmpi/bisheng/release/hmpi/lib/libmpi* %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/hmpi/bisheng/release/hmpi/lib/libopen-rte* %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/hmpi/bisheng/release/hmpi/lib/libopen-pal* %{buildroot}/usr/lib/ -%files common -%{_docdir}/gromacs -%exclude %{_docdir}/gromacs/manual.pdf -%{compdir}/gmx* -%{_mandir}/man1/gmx*.1* -%{_datadir}/%{name} -%exclude %{_datadir}/%{name}/template -%if %{with_opencl} -%exclude %{_datadir}/%{name}/opencl +# cp -r /root/HPCKit/25.1.0/compiler/bisheng/lib/libomp.so %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/compiler/bisheng/lib/libc++.so.1 %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/compiler/bisheng/lib/libc++.so.1.0 %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/compiler/bisheng/lib/libc++abi.so.1 %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/compiler/bisheng/lib/libc++abi.so.1.0 %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/compiler/bisheng/lib/libflang.so %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/compiler/bisheng/lib/libflangrti.so %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/compiler/bisheng/lib/libbsmath.so %{buildroot}/usr/lib/ +# cp -r /root/HPCKit/25.1.0/compiler/bisheng/lib/libunwind.* %{buildroot}/usr/lib/ -%files opencl -%doc docs/OpenCLTODOList.txt -%{_datadir}/%{name}/opencl -%endif +# cp -r /root/HPCKit/25.1.0/compiler/bisheng/lib/libunwind.so.1 %{buildroot}/usr/lib/ -%files doc -%{_docdir}/gromacs/manual.pdf +# cp -rf /root/HPCKit/25.1.0/compiler/bisheng/lib/* %{buildroot}/usr/lib/ +# cp -rf /root/HPCKit/25.1.0/hmpi/bisheng/release/hmpi/lib/* %{buildroot}/usr/lib/ +# cp -rf /root/HPCKit/25.1.0/kml/bisheng/lib/* %{buildroot}/usr/lib/ +# cp -rf /root/HPCKit/25.1.0/kml/gcc/lib/* %{buildroot}/usr/lib/ -%files libs -%{_libdir}/libgromacs*.so.* -%files devel -%{_includedir}/%{name} -%{_libdir}/libgromacs*.so -%{_libdir}/pkgconfig/libgromacs*.pc -%{_datadir}/%{name}/template -%{_datadir}/cmake/gromacs* -%files openmpi -%{_libdir}/openmpi/bin/mdrun_openmpi* +# export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH +# export LD_LIBRARY_PATH=/root/HPCKit/25.1.0/compiler/gcc/lib64/:$LD_LIBRARY_PATH +# export LD_LIBRARY_PATH=/root/HPCKit/25.1.0/compiler/bisheng/lib/:$LD_LIBRARY_PATH -%files mpich -%{_libdir}/mpich/bin/mdrun_mpich* +%files +# /usr/local/bin/gmx_mpi +/usr/local/bin/* +/usr/lib/* %changelog -* Fri Oct 04 2019 Christoph Junghans - 2018.8-1 -- Version bump to 2018.8 - -* Fri Jun 07 2019 Christoph Junghans - 2018.7-1 -- Version bump to 2018.7 - -* Sun Feb 24 2019 Christoph Junghans - 2018.6-1 -- Version bump to 2018.6, 2019.1 cannot be build due to missing deps - -* Thu Feb 14 2019 Orion Poplawski - 2018.5-2 -- Rebuild for openmpi 3.1.3 - -* Fri Feb 01 2019 Christoph Junghans - 2018.5-1 -- Version bump to 2018.5 - -* Fri Feb 01 2019 Fedora Release Engineering - 2018.4-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - -* Mon Nov 12 2018 Christoph Junghans - 2018.4-1 -- Version bump to 2018.4 -- Re-added gromacs-issue-2366.patch for f28 and lower - -* Thu Nov 8 2018 Christoph Junghans - 2018.3-2 -- Enable OpenCL for some archs on epel7 -- Drop gromacs-issue-2366.patch (bug #1558206) - seems to be fixed - -* Fri Nov 2 2018 Christoph Junghans - 2018.3-1 -- Version bump to 2018.3 -- Major spec files clean up - -* Wed Jul 18 2018 Christoph Junghans - 2018.2-1 -- Version bump to 2018.2 (bug #1591052) -- Add support for lmfit-7 (patch will be part of v2019) -- Switch to OpenBlas (bug #1602822) -- Disable brittle regressiontests - -* Fri Jul 13 2018 Fedora Release Engineering - 2018.1-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild - -* Tue Mar 27 2018 Christoph Junghans - 2018.1-1 -- Bump to version 2018.1 (bug #1559202) - -* Sat Feb 24 2018 Christoph Junghans - 2018-1.2 -- add gcc-c++ as BuildRequires -- use bundled tinyml2 to build tests, system one is too new - -* Wed Feb 07 2018 Fedora Release Engineering - 2018-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - -* Fri Jan 19 2018 Christoph Junghans - 2018-1 -- Update to 2018 -- Drop 43a0002.diff, merged upstream - -* Sat Dec 30 2017 Christoph Junghans - 2018-0.2rc1 -- Update to 2018-rc1 for testing -- Update b7713bf.diff to 43a0002.diff - -* Mon Dec 25 2017 Christoph Junghans - 2018-0.1beta3 -- Update to 2018-beta3 for testing -- Disable HardwareTopologyTest.NumaCacheSelfconsistency test on aarch64 -- Run regressiontests for serial build (don't work for mpi build) -- Clean up - - Drop execstack as everything is intristic now - - No la .files anymore, so drop find -delete - - OpenMPI was ported to s390, so enable it everywhere - -* Fri Sep 15 2017 Christoph Junghans - 2016.4-1 -- Update to 2016.4 - -* Wed Aug 02 2017 Fedora Release Engineering - 2016.3-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild - -* Wed Jul 26 2017 Fedora Release Engineering - 2016.3-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild - -* Tue Mar 14 2017 Christoph Junghans - 2016.3-1 -- Update to 2016.3 - -* Tue Feb 07 2017 Christoph Junghans - 2016.2-1 -- Update to 2016.2 -- Drop boost dependency, not uses anymore -- Drop gromacs-tng.patch, made it upstream - -* Fri Jan 27 2017 Jonathan Wakely - 2016.1-3 -- Rebuilt for Boost 1.63 - -* Fri Dec 23 2016 Christoph Junghans - 2016.1-2 -- fixed wording description -- drop dangerous GMXRC* - not needed when installed in /usr - would prepent /usr/lib in LD_LIBRARY_PATH - -drop otherwise empty zsh/csh package as actual completion is done in 2016 - nothing left in package after removing GMXRC.* -- fix location of bash-completion -- added GMX_USE_RDTSCP=OFF for docker, which has not support of rdtscp yet - -* Thu Nov 03 2016 Christoph Junghans - 2016.1-1 -- Update to 2016.1 -- Drop gromacs-use-system-lmfit.patch, made it upstream -- Update gromacs-tng.patch, https://gerrit.gromacs.org/#/c/6319/ - -* Fri Oct 21 2016 Orion Poplawski -- Rebuild for openmpi 2.0 - -* Tue Aug 23 2016 Dominik 'Rathann' Mierzejewski - 2016-1 -- update to 2016 release -- drop upstreamed patches -- fix build with system lmfit -- fix build with bundled tng removed -- drop pocl from BuildRequires, it's not required to build -- enable OpenCL on all arches (except ppc64le, where it's still failing) - -* Sat May 21 2016 Dominik 'Rathann' Mierzejewski - 2016-0.5.20160510gitd44d7d6 -- unbundle tinyxml2 - -* Sun Apr 10 2016 Dominik 'Rathann' Mierzejewski - 2016-0.4.20160510gitd44d7d6 -- update from git master -- enable OpenCL on armv7hl and BR: pocl >= 0.13-4 (#1324438) -- drop libxml2 BR (upstream switched to bundled tinyxml2-3.0.0) -- add missing arches in arch-dependent sections - -* Wed Apr 06 2016 Dominik 'Rathann' Mierzejewski - 2016-0.3.20160403gitd6e35c9 -- re-enable OpenCL (pocl was fixed recently) - -* Mon Apr 04 2016 Dominik 'Rathann' Mierzejewski - 2016-0.2.20160403gitd6e35c9 -- update to git master branch -- drop obsolete patches -- enable NEON instructions on armv7hnl arch -- drop condition around execstack usage, it's available everywhere now - -* Fri Mar 18 2016 Dominik 'Rathann' Mierzejewski - 2016-0.1.20160318gitbec9c87 -- update to git master branch -- disable OpenCL for now (due to pocl FTBFS #1307869) -- use BOOL with all boolean cmake options -- enable hwloc support -- don't install OpenCL kernels by default (but recommend them) -- unbundle lmfit (F24+), tng -- don't build shared libs for MPI builds -- drop -libs and -devel MPI subpackages -- disable failing tests on arm and i686 - -* Wed Feb 03 2016 Fedora Release Engineering - 5.1.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild - -* Tue Nov 17 2015 Dominik 'Rathann' Mierzejewski - 5.1.1-1 -- update to 5.1.1 - -* Wed Sep 23 2015 Dominik 'Rathann' Mierzejewski - 5.1-6 -- don't remove -DNDEBUG from CFLAGS (makes HandlesPermuteModifier test fail - randomly) -- convert shell variables to rpm macros -- enable OpenCL support (x86 and single precision only) - -* Tue Sep 22 2015 Dominik 'Rathann' Mierzejewski - 5.1-5 -- disable HandlesPermuteModifier test which fails randomly on i686 - -* Tue Sep 15 2015 Orion Poplawski - 5.1-4 -- Rebuild for openmpi 1.10.0 - -* Thu Aug 27 2015 Jonathan Wakely - 5.1-3 -- Rebuilt for Boost 1.59 - -* Wed Aug 19 2015 Dominik 'Rathann' Mierzejewski - 5.1-2 -- enable NEON SIMD on aarch64 -- fix compilation of VSX code with double precision on ppc64le -- enable VSX on ppc64le only -- don't manually output testuite logs upon failure, ctest does that already - -* Sat Aug 15 2015 Dominik 'Rathann' Mierzejewski - 5.1-1 -- update to 5.1 -- drop ancient Obsoletes:/Provides: -- drop Group: tags -- build mdrun-only MPI binaries again -- simplify SIMD enablement handling -- enable SIMD on ppc64(le) -- no execstack on ppc64 or s390(x), either -- output testsuite logs upon failure - -* Sat Aug 15 2015 Zbigniew Jędrzejewski-Szmek - 5.0.6-6 -- Rebuild for MPI provides - -* Mon Aug 10 2015 Sandro Mani - 5.0.6-5 -- Rebuild for RPM MPI Requires Provides Change - -* Thu Aug 06 2015 Dominik 'Rathann' Mierzejewski - 5.0.6-4 -- fix up dependencies between subpackages - -* Thu Aug 06 2015 Jonathan Wakely 5.0.6-3 -- Rebuilt for Boost 1.58 - -* Wed Jul 29 2015 Fedora Release Engineering - 5.0.6-2 -- Rebuilt for https://fedoraproject.org/wiki/Changes/F23Boost159 - -* Sun Jul 26 2015 Dominik 'Rathann' Mierzejewski - 5.0.6-1 -- update to 5.0.6 - -* Wed Jul 22 2015 David Tardon - 5.0.5-4 -- rebuild for Boost 1.58 - -* Wed Jun 17 2015 Fedora Release Engineering - 5.0.5-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild - -* Mon Jun 15 2015 Dominik 'Rathann' Mierzejewski - 5.0.5-2 -- obsolete old -common subpackage in -doc so that users don't lose the manual - -* Sat Jun 13 2015 Dominik 'Rathann' Mierzejewski - 5.0.5-1 -- update to 5.0.5 -- fix path to packaged dssp -- drop upstreamed patch -- move the large manual into a separate -doc subpackage - -* Tue Apr 14 2015 Dominik 'Rathann' Mierzejewski - 5.0.4-1 -- update to 5.0.4 -- switch Motif library to original Motif (as it's in Fedora since long) -- link against new-style atlas library (atlas 3.10.1+) -- BR: boost-devel -- csh/zsh completion removed upstream -- move bash completion into main package -- separate ngmx and mdrun dropped upstream -- enable testsuite -- factorize a lot of build logic -- drop redundant comments -- skip double precision tests on i686 (http://redmine.gromacs.org/issues/1716) - -* Mon Apr 13 2015 Dominik Mierzejewski - 4.6.5-6 -- rebuilt for changed mpich libraries - -* Sat Aug 16 2014 Fedora Release Engineering - 4.6.5-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild - -* Fri Jun 13 2014 Peter Robinson 4.6.5-4 -- Fix builds on aarch64/ppc64le -- Modernise spec -- Remove ancient obsoletes - -* Sat Jun 07 2014 Fedora Release Engineering - 4.6.5-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild - -* Sat Feb 22 2014 Deji Akingunola - 4.6.5-2 -- Rebuild for mpich-3.1 - -* Tue Dec 03 2013 Susi Lehtola - 4.6.5-1 -- Update to 4.6.5. - -* Thu Nov 14 2013 Susi Lehtola - 4.6.4-1 -- Update to 4.6.4. - -* Sat Aug 03 2013 Fedora Release Engineering - 4.6.3-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild - -* Sat Jul 20 2013 Deji Akingunola - 4.6.3-2 -- Rename mpich2 sub-packages to mpich and rebuild for mpich-3.0 - -* Sat Jul 06 2013 Susi Lehtola - 4.6.3-1 -- Update to 4.6.3. - -* Tue Jun 04 2013 Susi Lehtola - 4.6.2-1 -- Update to 4.6.2. - -* Wed Mar 06 2013 Susi Lehtola - 4.6.1-1 -- Update to 4.6.1. - -* Thu Feb 14 2013 Fedora Release Engineering - 4.6-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild - -* Mon Jan 21 2013 Susi Lehtola - 4.6-1 -- Update to stable 4.6 release. - -* Mon Dec 31 2012 Dan Horák - 4.6-0.2.beta3 -- fix build on non-x86 arches - -* Mon Dec 24 2012 Susi Lehtola - 4.6-0.1.beta3 -- Update to 4.6 beta 3. - -* Fri Nov 02 2012 Jussi Lehtola - 4.5.5-3.1 -- Bump due to MPICH2 update. - -* Thu Jul 19 2012 Fedora Release Engineering - 4.5.5-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild - -* Fri Jan 13 2012 Fedora Release Engineering - 4.5.5-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild - -* Tue Sep 20 2011 Jussi Lehtola - 4.5.5-1 -- Update to 4.5.5. - -* Wed Mar 30 2011 Deji Akingunola - 4.5.4-2 -- Rebuild for mpich2 soname bump - -* Wed Mar 23 2011 Jussi Lehtola - 4.5.4-1 -- Update to 4.5.4. - -* Sun Feb 13 2011 Jussi Lehtola - 4.5.3-4 -- Get rid of executable stacks. - -* Mon Feb 07 2011 Dan Horák - 4.5.3-3 -- conditionalize OpenMPI support -- fix build on 64-bit platforms - -* Mon Dec 20 2010 Jussi Lehtola - 4.5.3-2 -- Fix rest of BZ #649338. - -* Thu Nov 18 2010 Jussi Lehtola - 4.5.3-1 -- Update to 4.5.3. - -* Fri Nov 05 2010 Jussi Lehtola - 4.5.2-3 -- Rebuild due to libxml2 soname bump. - -* Wed Nov 03 2010 Jussi Lehtola - 4.5.2-2 -- Make gromacs package obsolete older versions of gromacs package due to the - branching of libraries. - -* Mon Nov 01 2010 Jussi Lehtola - 4.5.2-1 -- Update to 4.5.2. - -* Wed Oct 27 2010 Jussi Lehtola - 4.5.1-2 -- Patch around #644950. -- Split libraries in own packages to avoid multilib problems. - -* Sat Oct 09 2010 Jussi Lehtola - 4.5.1-1 -- Update to 4.5.1. - -* Sun Dec 06 2009 Jussi Lehtola - 4.0.7-1 -- Update to 4.0.7. - -* Sun Dec 06 2009 Jussi Lehtola - 4.0.6-1 -- Update to 4.0.6. - -* Fri Dec 04 2009 Jussi Lehtola - 4.0.5-6 -- Fix file conflict. - -* Tue Dec 01 2009 Jussi Lehtola - 4.0.5-5 -- Put correct MPI devel package requires in place. - -* Tue Dec 01 2009 Jussi Lehtola - 4.0.5-4 -- Fix obsoletes. - -* Mon Nov 30 2009 Jussi Lehtola - 4.0.5-3 -- Combine libs with binaries and drop debug packages to avoid explosion of - number of packages. -- Adopt use of MPI guidelines. - -* Fri Jul 24 2009 Fedora Release Engineering - 4.0.5-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild - -* Fri May 22 2009 Jussi Lehtola - 4.0.5-1 -- Update to 4.0.5. -- Change spec %%defines to %%globals. -- Add debug subpackages to make debugging of GROMACS possible. - -* Tue Feb 17 2009 Jussi Lehtola - 4.0.4-1 -- Update to 4.0.4. - -* Mon Jan 19 2009 Jussi Lehtola - 4.0.3-4 -- Retry fixing gmxdemo. - -* Mon Jan 19 2009 Jussi Lehtola - 4.0.3-3 -- Fixed gmxdemo. - -* Mon Jan 19 2009 Jussi Lehtola - 4.0.3-2 -- Fix EPEL 4 build. - -* Mon Jan 19 2009 Jussi Lehtola - 4.0.3-1 -- Update to 4.0.3. - -* Wed Jan 14 2009 Jussi Lehtola - 4.0.2-7 -- Update manual to latest version. -- Removed Requires: blas and lapack. - -* Mon Nov 10 2008 Jussi Lehtola - 4.0.2-6 -- Update to 4.0.2. - -* Sun Nov 09 2008 Jussi Lehtola - 4.0.1-5 -- Add Requires: blas too. - -* Sun Nov 09 2008 Jussi Lehtola - 4.0.1-4 -- Update to 4.0.1. -- Add Requires: lapack and openmpi to prevent yum from pulling atlas and lam -instead. - -* Wed Oct 15 2008 Jussi Lehtola - 4.0-3 -- Rename also man pages. - -* Mon Oct 13 2008 Jussi Lehtola - 4.0-2 -- Added noreplace to bash completion file. -- Changed double precision mpi binary suffix to _mpi_d. - -* Sun Oct 12 2008 Jussi Lehtola - 4.0-1 -- Update to Gromacs 4.0. -- Remove module system and patch file names to begin with g_. - -* Wed Oct 08 2008 Jussi Lehtola - 4.0-0.15.rc3 -- Changed location of binaries. -- Removed conflict of module file, as the program is binary compatible with older versions. - -* Wed Oct 08 2008 Jussi Lehtola - 4.0-0.14.rc3 -- The gromacs module is loaded automatically and it conflicts with gromacs3. - -* Tue Oct 07 2008 Jussi Lehtola - 4.0-0.13.rc3 -- Renamed module files from %%{name}-%%{version} to %%{name}. - -* Mon Oct 06 2008 Jussi Lehtola - 4.0-0.12.rc3 -- Fix BR to get GROMACS to build in mock for epel-4. - -* Sat Oct 04 2008 Jussi Lehtola - 4.0-0.11.rc3 -- Fix to get GROMACS to build in mock for epel-5. - -* Sat Oct 04 2008 Jussi Lehtola - 4.0-0.10.rc3 -- Implement module system & remove binary renaming. -- No need for autoreconf anymore. -- Update to rc3. - -* Sat Oct 04 2008 Jussi Lehtola - 4.0-0.9.rc2 -- Fall back to autoreconf due to binary renaming. - -* Fri Oct 03 2008 Jussi Lehtola - 4.0-0.8.rc2 -- Modified install commands to preserve timestamps. - -* Fri Oct 03 2008 Jussi Lehtola - 4.0-0.7.rc2 -- Even more review fixes. -- Binaries renamed: - highway -> g_highway - luck -> g_luck - sigeps -> g_sigeps - wheel -> g_wheel - -* Thu Oct 02 2008 Jussi Lehtola - 4.0-0.6.rc2 -- Final review fixes. - -* Wed Oct 01 2008 Jussi Lehtola - 4.0-0.5.rc2 -- Strip down requires by branching tutor to its own package. - -* Tue Sep 30 2008 Jussi Lehtola - 4.0-0.4.rc2 -- Extensive package review fixes. -- Unclear licenses on some files, filed upstream bug 217. - http://bugzilla.gromacs.org/show_bug.cgi?id=217 - -* Mon Sep 29 2008 Jussi Lehtola - 4.0-0.3.rc2 -- Move .so files to -devel package. -- Remove .la files. - -* Mon Sep 29 2008 Jussi Lehtola - 4.0-0.2.rc2 -- Implement out-of-tree-builds. -- Add --noexecstack to CFLAGS. -- Remove execstack procedure and prelink from buildreqs. -- Filed upstream bug 215 to add .note.GNU-stack . -- Fix incorrect file permission on src/tools/gmx_xpm2ps.c . - -* Mon Sep 29 2008 Jussi Lehtola - 4.0-0.1.rc2 -- Alphabetized buildrequires. -- Changed gromacs-share to gromacs-common. - -* Fri Sep 26 2008 Jussi Lehtola - 4.0-0.0.rc2 -- Initial build. +* Tue Feb 03 2026 yanghanchi - 2025.3-1 +- 新增gromacs-2025.3在openEuler-22.03-LTS-SP4环境上的rpm包 \ No newline at end of file diff --git a/manual-2018.8.pdf b/manual-2018.8.pdf deleted file mode 100644 index 3ef4eecc3d410788d61979825ab2f263a773916f..0000000000000000000000000000000000000000 Binary files a/manual-2018.8.pdf and /dev/null differ diff --git a/regressiontests-2018.8.tar.gz b/regressiontests-2018.8.tar.gz deleted file mode 100644 index 28c5537128df5ed512cd3f8c48e4c9258fb2faf8..0000000000000000000000000000000000000000 Binary files a/regressiontests-2018.8.tar.gz and /dev/null differ