From a1b7f1910da4e0e04d19721baed57b8f39b11ddd Mon Sep 17 00:00:00 2001 From: zaikunzhang Date: Tue, 30 Apr 2024 17:42:47 +0800 Subject: [PATCH] 240430.174247.HKT try `prima_internal.h` --- c/include/prima/prima_internal.h | 38 ++++++++++++++++++++++ c/prima.c | 56 ++++++++++++-------------------- c/tests/stress.c | 10 +++--- 3 files changed, 64 insertions(+), 40 deletions(-) create mode 100644 c/include/prima/prima_internal.h diff --git a/c/include/prima/prima_internal.h b/c/include/prima/prima_internal.h new file mode 100644 index 0000000000..c577ada223 --- /dev/null +++ b/c/include/prima/prima_internal.h @@ -0,0 +1,38 @@ +#ifndef PRIMA_INTERNAL_H +#define PRIMA_INTERNAL_H + +#include "prima/prima.h" + +unsigned int get_random_seed(void); + +// Function to check whether the problem matches the algorithm +prima_rc_t prima_check_problem(const prima_problem_t problem, const prima_algorithm_t algorithm); + +// Function to initialize the result +prima_rc_t prima_init_result(prima_result_t *const result, const prima_problem_t problem); + +// Functions implemented in Fortran (*_c.f90) +int cobyla_c(const int m_nlcon, const prima_objcon_t calcfc, const void *data, const int n, double x[], double *const f, double *const cstrv, double nlconstr[], + const int m_ineq, const double Aineq[], const double bineq[], + const int m_eq, const double Aeq[], const double beq[], + const double xl[], const double xu[], + const double f0, const double nlconstr0[], + int *const nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int iprint, const double ctol, + const prima_callback_t callback, int *const info); + +int bobyqa_c(prima_obj_t calfun, const void *data, const int n, double x[], double *const f, const double xl[], const double xu[], + int *const nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int npt, const int iprint, const prima_callback_t callback, int *const info); + +int newuoa_c(prima_obj_t calfun, const void *data, const int n, double x[], double *const f, + int *const nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int npt, const int iprint, const prima_callback_t callback, int *const info); + +int uobyqa_c(prima_obj_t calfun, const void *data, const int n, double x[], double *const f, + int *const nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int iprint, const prima_callback_t callback, int *const info); + +int lincoa_c(prima_obj_t calfun, const void *data, const int n, double x[], double *const f, + double *const cstrv, const int m_ineq, const double Aineq[], const double bineq[], + const int m_eq, const double Aeq[], const double beq[], const double xl[], const double xu[], + int *const nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int npt, const int iprint, const double ctol, + const prima_callback_t callback, int *const info); + +#endif diff --git a/c/prima.c b/c/prima.c index 5d380971c1..188abe91e5 100644 --- a/c/prima.c +++ b/c/prima.c @@ -1,8 +1,8 @@ // Dedicated to the late Professor M. J. D. Powell FRS (1936--2015). -#include "prima/prima.h" -#include +#include "prima/prima_internal.h" +#include #include #include #include @@ -65,6 +65,16 @@ prima_rc_t prima_init_options(prima_options_t *const options) // Function to check whether the problem matches the algorithm prima_rc_t prima_check_problem(const prima_problem_t problem, const prima_algorithm_t algorithm) { + if (algorithm != PRIMA_COBYLA && (problem.calcfc || problem.nlconstr0 || problem.m_nlcon > 0)) + return PRIMA_PROBLEM_SOLVER_MISMATCH_NONLINEAR_CONSTRAINTS; + + if ((algorithm != PRIMA_COBYLA && algorithm != PRIMA_LINCOA) && + (problem.m_ineq > 0 || problem.m_eq > 0 || problem.Aineq || problem.bineq || problem.Aeq || problem.beq)) + return PRIMA_PROBLEM_SOLVER_MISMATCH_LINEAR_CONSTRAINTS; + + if ((algorithm != PRIMA_COBYLA && algorithm != PRIMA_LINCOA && algorithm != PRIMA_BOBYQA) && (problem.xl || problem.xu)) + return PRIMA_PROBLEM_SOLVER_MISMATCH_BOUNDS; + if (!problem.x0) return PRIMA_NULL_X0; @@ -90,10 +100,10 @@ prima_rc_t prima_init_result(prima_result_t *const result, const prima_problem_t result->cstrv = NAN; // nf: number of function evaluations - result->nf = 0; + result->nf = INT_MIN; // status: return code - result->status = PRIMA_RESULT_INITIALIZED; + result->status = INT_MIN; // message: exit message result->message = NULL; @@ -182,37 +192,17 @@ const char *prima_get_rc_string(const prima_rc_t rc) return "NULL result"; case PRIMA_NULL_FUNCTION: return "NULL function"; + case PRIMA_PROBLEM_SOLVER_MISMATCH_NONLINEAR_CONSTRAINTS: + return "Nonlinear constraints were provided for an algorithm that cannot handle them"; + case PRIMA_PROBLEM_SOLVER_MISMATCH_LINEAR_CONSTRAINTS: + return "Linear constraints were provided for an algorithm that cannot handle them"; + case PRIMA_PROBLEM_SOLVER_MISMATCH_BOUNDS: + return "Bounds were provided for an algorithm that cannot handle them"; default: return "Invalid return code"; } } - -// Functions implemented in Fortran (*_c.f90) -int cobyla_c(const int m_nlcon, const prima_objcon_t calcfc, const void *data, const int n, double x[], double *const f, double *const cstrv, double nlconstr[], - const int m_ineq, const double Aineq[], const double bineq[], - const int m_eq, const double Aeq[], const double beq[], - const double xl[], const double xu[], - const double f0, const double nlconstr0[], - int *const nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int iprint, const double ctol, - const prima_callback_t callback, int *const info); - -int bobyqa_c(prima_obj_t calfun, const void *data, const int n, double x[], double *const f, const double xl[], const double xu[], - int *const nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int npt, const int iprint, const prima_callback_t callback, int *const info); - -int newuoa_c(prima_obj_t calfun, const void *data, const int n, double x[], double *const f, - int *const nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int npt, const int iprint, const prima_callback_t callback, int *const info); - -int uobyqa_c(prima_obj_t calfun, const void *data, const int n, double x[], double *const f, - int *const nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int iprint, const prima_callback_t callback, int *const info); - -int lincoa_c(prima_obj_t calfun, const void *data, const int n, double x[], double *const f, - double *const cstrv, const int m_ineq, const double Aineq[], const double bineq[], - const int m_eq, const double Aeq[], const double beq[], const double xl[], const double xu[], - int *const nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int npt, const int iprint, const double ctol, - const prima_callback_t callback, int *const info); - - // The function that does the minimization using a PRIMA solver prima_rc_t prima_minimize(const prima_algorithm_t algorithm, const prima_problem_t problem, const prima_options_t options, prima_result_t *const result) { @@ -267,9 +257,3 @@ prima_rc_t prima_minimize(const prima_algorithm_t algorithm, const prima_problem return info; } - -bool prima_is_success(const prima_result_t result) -{ - return (result.status == PRIMA_SMALL_TR_RADIUS || - result.status == PRIMA_FTARGET_ACHIEVED) && (result.cstrv <= sqrt(DBL_EPSILON)); -} diff --git a/c/tests/stress.c b/c/tests/stress.c index d66d685046..332fcaf687 100644 --- a/c/tests/stress.c +++ b/c/tests/stress.c @@ -61,12 +61,14 @@ static void fun_con(const double x[], double *const f, double constr[], const vo } // A function generating a seed that alters weekly -unsigned int get_random_seed(void) { +unsigned int get_random_seed(void) +{ // Set the random seed to year/week char buf[10] = {0}; time_t t = time(NULL); - struct tm *tmp = localtime(&t); - int rc = strftime(buf, 10, "%y%W", tmp); + struct tm timeinfo; + localtime_s(&timeinfo, &t); + int rc = strftime(buf, 10, "%y%W", &timeinfo); if (!rc) return 42; else @@ -87,7 +89,7 @@ int main(int argc, char * argv[]) printf("Debug = %d\n", debug); unsigned int seed = get_random_seed(); - printf("Random seed = %d\n", seed); + printf("Random seed = %u\n", seed); srand(seed); // Set up the options