From c159aede8f893974fdae0f0addb2cf0bbd7fa700 Mon Sep 17 00:00:00 2001 From: zaikunzhang Date: Thu, 1 Feb 2024 00:53:00 +0800 Subject: [PATCH] 240201.005300.HKT C: change the indentation from 2 spaces to 4 spaces --- c/examples/bobyqa/bobyqa_example.c | 82 +++---- c/examples/cobyla/cobyla_example.c | 82 +++---- c/examples/lincoa/lincoa_example.c | 84 +++---- c/examples/newuoa/newuoa_example.c | 72 +++--- c/examples/uobyqa/uobyqa_example.c | 72 +++--- c/include/prima/prima.h | 279 +++++++++++----------- c/prima.c | 370 +++++++++++++++-------------- 7 files changed, 521 insertions(+), 520 deletions(-) diff --git a/c/examples/bobyqa/bobyqa_example.c b/c/examples/bobyqa/bobyqa_example.c index 20ced1d014..e116299f65 100644 --- a/c/examples/bobyqa/bobyqa_example.c +++ b/c/examples/bobyqa/bobyqa_example.c @@ -9,62 +9,62 @@ // Objective function static void fun(const double x[], double *f, const void *data) { - const double x1 = x[0]; - const double x2 = x[1]; - *f = pow(x1-5, 2) + pow(x2-4, 2); - (void)data; + const double x1 = x[0]; + const double x2 = x[1]; + *f = pow(x1-5, 2) + pow(x2-4, 2); + (void)data; } // Callback function static void callback(int n, const double x[], double f, int nf, int tr, double cstrv, const int m_nlcon, const double nlconstr[], bool *terminate) { - (void)n; - (void)cstrv; - (void)m_nlcon; - (void)nlconstr; - printf("Best point so far: x = {%g, %g}, f = %g, nf = %d, tr = %d\n", x[0], x[1], f, nf, tr); - *terminate = 0; + (void)n; + (void)cstrv; + (void)m_nlcon; + (void)nlconstr; + printf("Best point so far: x = {%g, %g}, f = %g, nf = %d, tr = %d\n", x[0], x[1], f, nf, tr); + *terminate = 0; } // Main function int main(int argc, char * argv[]) { - (void)argc; - (void)argv; - const int n = 2; - double x0[2] = {0.0, 0.0}; + (void)argc; + (void)argv; + const int n = 2; + double x0[2] = {0.0, 0.0}; - // Set up the problem - prima_problem_t problem; - prima_init_problem(&problem, n); - problem.x0 = x0; - problem.calfun = &fun; - // We define an upper bound that will be active in order to demonstrate the usage. - double xl[] = {-1.0, -1.0}; - double xu[] = {4.5, 4.5}; - problem.xl = xl; - problem.xu = xu; + // Set up the problem + prima_problem_t problem; + prima_init_problem(&problem, n); + problem.x0 = x0; + problem.calfun = &fun; + // We define an upper bound that will be active in order to demonstrate the usage. + double xl[] = {-1.0, -1.0}; + double xu[] = {4.5, 4.5}; + problem.xl = xl; + problem.xu = xu; - // Set up the options - prima_options_t options; - prima_init_options(&options); - options.iprint = PRIMA_MSG_EXIT; - options.rhoend= 1e-3; - options.maxfun = 200*n; - options.callback = &callback; + // Set up the options + prima_options_t options; + prima_init_options(&options); + options.iprint = PRIMA_MSG_EXIT; + options.rhoend= 1e-3; + options.maxfun = 200*n; + options.callback = &callback; - // Call the solver - prima_result_t result; - const int rc = prima_minimize(PRIMA_BOBYQA, &problem, &options, &result); + // Call the solver + prima_result_t result; + const int rc = prima_minimize(PRIMA_BOBYQA, &problem, &options, &result); - // Print the result - printf("x* = {%g, %g}, rc = %d, msg = '%s', evals = %d\n", result.x[0], result.x[1], rc, result.message, result.nf); + // Print the result + printf("x* = {%g, %g}, rc = %d, msg = '%s', evals = %d\n", result.x[0], result.x[1], rc, result.message, result.nf); - // Check the result - int success = (fabs(result.x[0] - 4.5) > 2e-2 || fabs(result.x[1] - 4) > 2e-2); + // Check the result + int success = (fabs(result.x[0] - 4.5) > 2e-2 || fabs(result.x[1] - 4) > 2e-2); - // Free the result - prima_free_result(&result); + // Free the result + prima_free_result(&result); - return success; + return success; } diff --git a/c/examples/cobyla/cobyla_example.c b/c/examples/cobyla/cobyla_example.c index 82fab5f9b7..f02cf2f52f 100644 --- a/c/examples/cobyla/cobyla_example.c +++ b/c/examples/cobyla/cobyla_example.c @@ -13,64 +13,64 @@ // Objective & constraint function static void fun(const double x[], double *f, double constr[], const void *data) { - const double x1 = x[0]; - const double x2 = x[1]; - *f = pow(x1-5, 2) + pow(x2-4, 2); - constr[0] = pow(x1, 2) - 9; // Constraint: x1^2 - 9 <= 0 - (void)data; + const double x1 = x[0]; + const double x2 = x[1]; + *f = pow(x1-5, 2) + pow(x2-4, 2); + constr[0] = pow(x1, 2) - 9; // Constraint: x1^2 - 9 <= 0 + (void)data; } // Callback function static void callback(const int n, const double x[], const double f, const int nf, const int tr, const double cstrv, const int m_nlcon, const double nlconstr[], bool *terminate) { - (void)n; - (void)m_nlcon; - printf("Best point so far: x = {%g, %g}, f = %g, cstrv = %g, nlconstr = {%g}, nf = %d, tr = %d\n", x[0], x[1], f, cstrv, nlconstr[0], nf, tr); - *terminate = 0; + (void)n; + (void)m_nlcon; + printf("Best point so far: x = {%g, %g}, f = %g, cstrv = %g, nlconstr = {%g}, nf = %d, tr = %d\n", x[0], x[1], f, cstrv, nlconstr[0], nf, tr); + *terminate = 0; } // Main function int main(int argc, char * argv[]) { - (void)argc; - (void)argv; - const int n = 2; - double x0[2] = {0.0, 0.0}; + (void)argc; + (void)argv; + const int n = 2; + double x0[2] = {0.0, 0.0}; - // Set up the problem - prima_problem_t problem; - prima_init_problem(&problem, n); - problem.x0 = x0; - problem.m_nlcon = M_NLCON; - problem.calcfc = &fun; - // Provide the initial values of the objective function and the nonlinear constraints. - // This is OPTIONAL, and end users should NOT do it in general. Here, we do it for testing. + // Set up the problem + prima_problem_t problem; + prima_init_problem(&problem, n); + problem.x0 = x0; + problem.m_nlcon = M_NLCON; + problem.calcfc = &fun; + // Provide the initial values of the objective function and the nonlinear constraints. + // This is OPTIONAL, and end users should NOT do it in general. Here, we do it for testing. #if PROVIDE_INITIAL_F_AND_NLCONSTR - double nlconstr0[M_NLCON] = {0}; - fun(x0, &(problem.f0), nlconstr0, NULL); - problem.nlconstr0 = nlconstr0; + double nlconstr0[M_NLCON] = {0}; + fun(x0, &(problem.f0), nlconstr0, NULL); + problem.nlconstr0 = nlconstr0; #endif - // Set up the options - prima_options_t options; - prima_init_options(&options); - options.iprint = PRIMA_MSG_EXIT; - options.rhoend= 1e-3; - options.maxfun = 200*n; - options.callback = &callback; + // Set up the options + prima_options_t options; + prima_init_options(&options); + options.iprint = PRIMA_MSG_EXIT; + options.rhoend= 1e-3; + options.maxfun = 200*n; + options.callback = &callback; - // Call the solver - prima_result_t result; - const int rc = prima_minimize(PRIMA_COBYLA, &problem, &options, &result); + // Call the solver + prima_result_t result; + const int rc = prima_minimize(PRIMA_COBYLA, &problem, &options, &result); - // Print the result - printf("x* = {%g, %g}, f* = %g, cstrv = %g, nlconstr = {%g}, rc = %d, msg = '%s', evals = %d\n", result.x[0], result.x[1], result.f, result.cstrv, result.nlconstr[0], rc, result.message, result.nf); + // Print the result + printf("x* = {%g, %g}, f* = %g, cstrv = %g, nlconstr = {%g}, rc = %d, msg = '%s', evals = %d\n", result.x[0], result.x[1], result.f, result.cstrv, result.nlconstr[0], rc, result.message, result.nf); - // Check the result - int success = (fabs(result.x[0] - 3) > 2e-2 || fabs(result.x[1] - 4) > 2e-2); + // Check the result + int success = (fabs(result.x[0] - 3) > 2e-2 || fabs(result.x[1] - 4) > 2e-2); - // Free the result - prima_free_result(&result); + // Free the result + prima_free_result(&result); - return success; + return success; } diff --git a/c/examples/lincoa/lincoa_example.c b/c/examples/lincoa/lincoa_example.c index c15e165889..08d3223db4 100644 --- a/c/examples/lincoa/lincoa_example.c +++ b/c/examples/lincoa/lincoa_example.c @@ -9,63 +9,63 @@ // Objective function static void fun(const double x[], double *f, const void *data) { - const double x1 = x[0]; - const double x2 = x[1]; - *f = pow(x1-5, 2) + pow(x2-4, 2); - (void)data; + const double x1 = x[0]; + const double x2 = x[1]; + *f = pow(x1-5, 2) + pow(x2-4, 2); + (void)data; } // Callback function static void callback(int n, const double x[], double f, int nf, int tr, double cstrv, int m_nlcon, const double nlconstr[], bool *terminate) { - (void)n; - (void)m_nlcon; - (void)nlconstr; - printf("Best point so far: x = {%g, %g}, f = %g, cstrv = %g, nf = %d, tr = %d\n", x[0], x[1], f, cstrv, nf, tr); - *terminate = 0; + (void)n; + (void)m_nlcon; + (void)nlconstr; + printf("Best point so far: x = {%g, %g}, f = %g, cstrv = %g, nf = %d, tr = %d\n", x[0], x[1], f, cstrv, nf, tr); + *terminate = 0; } // Main function int main(int argc, char * argv[]) { - (void)argc; - (void)argv; - const int n = 2; - double x0[2] = {0.0, 0.0}; + (void)argc; + (void)argv; + const int n = 2; + double x0[2] = {0.0, 0.0}; - // Set up the problem - prima_problem_t problem; - prima_init_problem(&problem, n); - problem.calfun = &fun; - problem.x0 = x0; - // We define linear constraints that will be active in order to demonstrate the usage. - // The constraint is x1 + x2 <= 8. - problem.m_ineq = 1; - double Aineq[1*2] = {1.0, 1.0}; - double bineq[1] = {8.0}; - problem.Aineq = Aineq; - problem.bineq = bineq; + // Set up the problem + prima_problem_t problem; + prima_init_problem(&problem, n); + problem.calfun = &fun; + problem.x0 = x0; + // We define linear constraints that will be active in order to demonstrate the usage. + // The constraint is x1 + x2 <= 8. + problem.m_ineq = 1; + double Aineq[1*2] = {1.0, 1.0}; + double bineq[1] = {8.0}; + problem.Aineq = Aineq; + problem.bineq = bineq; - // Set up the options - prima_options_t options; - prima_init_options(&options); - options.iprint = PRIMA_MSG_EXIT; - options.rhoend= 1e-3; - options.maxfun = 200*n; - options.callback = &callback; + // Set up the options + prima_options_t options; + prima_init_options(&options); + options.iprint = PRIMA_MSG_EXIT; + options.rhoend= 1e-3; + options.maxfun = 200*n; + options.callback = &callback; - // Call the solver - prima_result_t result; - const int rc = prima_minimize(PRIMA_LINCOA, &problem, &options, &result); + // Call the solver + prima_result_t result; + const int rc = prima_minimize(PRIMA_LINCOA, &problem, &options, &result); - // Print the result - printf("x* = {%g, %g}, f* = %g, cstrv = %g, rc = %d, msg = '%s', evals = %d\n", result.x[0], result.x[1], result.f, result.cstrv, rc, result.message, result.nf); + // Print the result + printf("x* = {%g, %g}, f* = %g, cstrv = %g, rc = %d, msg = '%s', evals = %d\n", result.x[0], result.x[1], result.f, result.cstrv, rc, result.message, result.nf); - // Check the result - int success = (fabs(result.x[0] - 4.5) > 2e-2 || fabs(result.x[1] - 3.5) > 2e-2); + // Check the result + int success = (fabs(result.x[0] - 4.5) > 2e-2 || fabs(result.x[1] - 3.5) > 2e-2); - // Free the result - prima_free_result(&result); + // Free the result + prima_free_result(&result); - return success; + return success; } diff --git a/c/examples/newuoa/newuoa_example.c b/c/examples/newuoa/newuoa_example.c index 99707e2caa..05635fa44b 100644 --- a/c/examples/newuoa/newuoa_example.c +++ b/c/examples/newuoa/newuoa_example.c @@ -9,57 +9,57 @@ // Objective function static void fun(const double x[], double *f, const void *data) { - const double x1 = x[0]; - const double x2 = x[1]; - *f = pow(x1-5, 2) + pow(x2-4, 2); - (void)data; + const double x1 = x[0]; + const double x2 = x[1]; + *f = pow(x1-5, 2) + pow(x2-4, 2); + (void)data; } // Callback function static void callback(int n, const double x[], double f, int nf, int tr, double cstrv, int m_nlcon, const double nlconstr[], bool *terminate) { - (void)n; - (void)cstrv; - (void)m_nlcon; - (void)nlconstr; - printf("Best point so far: x = {%g, %g}, f = %g, nf = %d, tr = %d\n", x[0], x[1], f, nf, tr); - *terminate = 0; + (void)n; + (void)cstrv; + (void)m_nlcon; + (void)nlconstr; + printf("Best point so far: x = {%g, %g}, f = %g, nf = %d, tr = %d\n", x[0], x[1], f, nf, tr); + *terminate = 0; } // Main function int main(int argc, char * argv[]) { - (void)argc; - (void)argv; - const int n = 2; - double x0[2] = {0.0, 0.0}; + (void)argc; + (void)argv; + const int n = 2; + double x0[2] = {0.0, 0.0}; - // Set up the problem - prima_problem_t problem; - prima_init_problem(&problem, n); - problem.calfun = &fun; - problem.x0 = x0; + // Set up the problem + prima_problem_t problem; + prima_init_problem(&problem, n); + problem.calfun = &fun; + problem.x0 = x0; - // Set up the options - prima_options_t options; - prima_init_options(&options); - options.iprint = PRIMA_MSG_EXIT; - options.rhoend= 1e-3; - options.maxfun = 200*n; - options.callback = &callback; + // Set up the options + prima_options_t options; + prima_init_options(&options); + options.iprint = PRIMA_MSG_EXIT; + options.rhoend= 1e-3; + options.maxfun = 200*n; + options.callback = &callback; - // Call the solver - prima_result_t result; - const int rc = prima_minimize(PRIMA_NEWUOA, &problem, &options, &result); + // Call the solver + prima_result_t result; + const int rc = prima_minimize(PRIMA_NEWUOA, &problem, &options, &result); - // Print the result - printf("x* = {%g, %g}, rc = %d, msg = '%s', evals = %d\n", result.x[0], result.x[1], rc, result.message, result.nf); + // Print the result + printf("x* = {%g, %g}, rc = %d, msg = '%s', evals = %d\n", result.x[0], result.x[1], rc, result.message, result.nf); - // Check the result - int success = (fabs(result.x[0] - 5) > 2e-2 || fabs(result.x[1] - 4) > 2e-2); + // Check the result + int success = (fabs(result.x[0] - 5) > 2e-2 || fabs(result.x[1] - 4) > 2e-2); - // Free the result - prima_free_result(&result); + // Free the result + prima_free_result(&result); - return success; + return success; } diff --git a/c/examples/uobyqa/uobyqa_example.c b/c/examples/uobyqa/uobyqa_example.c index 822862f4f0..a2d116d292 100644 --- a/c/examples/uobyqa/uobyqa_example.c +++ b/c/examples/uobyqa/uobyqa_example.c @@ -9,57 +9,57 @@ // Objective function static void fun(const double x[], double *f, const void *data) { - const double x1 = x[0]; - const double x2 = x[1]; - *f = pow(x1-5, 2) + pow(x2-4, 2); - (void)data; + const double x1 = x[0]; + const double x2 = x[1]; + *f = pow(x1-5, 2) + pow(x2-4, 2); + (void)data; } // Callback function static void callback(int n, const double x[], double f, int nf, int tr, double cstrv, const int m_nlcon, const double nlconstr[], bool *terminate) { - (void)n; - (void)cstrv; - (void)m_nlcon; - (void)nlconstr; - printf("Best point so far: x = {%g, %g}, f = %g, nf = %d, tr = %d\n", x[0], x[1], f, nf, tr); - *terminate = 0; + (void)n; + (void)cstrv; + (void)m_nlcon; + (void)nlconstr; + printf("Best point so far: x = {%g, %g}, f = %g, nf = %d, tr = %d\n", x[0], x[1], f, nf, tr); + *terminate = 0; } // Main function int main(int argc, char * argv[]) { - (void)argc; - (void)argv; - const int n = 2; - double x0[2] = {0.0, 0.0}; + (void)argc; + (void)argv; + const int n = 2; + double x0[2] = {0.0, 0.0}; - // Set up the problem - prima_problem_t problem; - prima_init_problem(&problem, n); - problem.calfun = &fun; - problem.x0 = x0; + // Set up the problem + prima_problem_t problem; + prima_init_problem(&problem, n); + problem.calfun = &fun; + problem.x0 = x0; - // Set up the options - prima_options_t options; - prima_init_options(&options); - options.iprint = PRIMA_MSG_EXIT; - options.rhoend= 1e-3; - options.maxfun = 200*n; - options.callback = &callback; + // Set up the options + prima_options_t options; + prima_init_options(&options); + options.iprint = PRIMA_MSG_EXIT; + options.rhoend= 1e-3; + options.maxfun = 200*n; + options.callback = &callback; - // Run the solver - prima_result_t result; - const int rc = prima_minimize(PRIMA_UOBYQA, &problem, &options, &result); + // Run the solver + prima_result_t result; + const int rc = prima_minimize(PRIMA_UOBYQA, &problem, &options, &result); - // Print the result - printf("x* = {%g, %g}, rc = %d, msg = '%s', evals = %d\n", result.x[0], result.x[1], rc, result.message, result.nf); + // Print the result + printf("x* = {%g, %g}, rc = %d, msg = '%s', evals = %d\n", result.x[0], result.x[1], rc, result.message, result.nf); - // Check the result - int success = (fabs(result.x[0] - 5) > 2e-2 || fabs(result.x[1] - 4) > 2e-2); + // Check the result + int success = (fabs(result.x[0] - 5) > 2e-2 || fabs(result.x[1] - 4) > 2e-2); - // Free the result - prima_free_result(&result); + // Free the result + prima_free_result(&result); - return success; + return success; } diff --git a/c/include/prima/prima.h b/c/include/prima/prima.h index 350b218dc1..44da74f914 100644 --- a/c/include/prima/prima.h +++ b/c/include/prima/prima.h @@ -27,52 +27,50 @@ extern "C" { // Possible algorithms -typedef enum -{ - PRIMA_UOBYQA, // Unconstrained - PRIMA_NEWUOA, // Unconstrained - PRIMA_BOBYQA, // Bound-constrained - PRIMA_LINCOA, // Linearly constrained - PRIMA_COBYLA // Nonlinearly constrained +typedef enum { + PRIMA_UOBYQA, // Unconstrained + PRIMA_NEWUOA, // Unconstrained + PRIMA_BOBYQA, // Bound-constrained + PRIMA_LINCOA, // Linearly constrained + PRIMA_COBYLA // Nonlinearly constrained } prima_algorithm_t; // Verbosity level typedef enum { - PRIMA_MSG_NONE = 0, // Do not print any message - PRIMA_MSG_EXIT = 1, // Print a message at exit - PRIMA_MSG_RHO = 2, // Print a message when rho changes - PRIMA_MSG_FEVL = 3, // Print a message when the object/constraint functions get evaluated + PRIMA_MSG_NONE = 0, // Do not print any message + PRIMA_MSG_EXIT = 1, // Print a message at exit + PRIMA_MSG_RHO = 2, // Print a message when rho changes + PRIMA_MSG_FEVL = 3, // Print a message when the object/constraint functions get evaluated } prima_message_t; // Possible return values -typedef enum -{ - PRIMA_SMALL_TR_RADIUS = 0, - PRIMA_FTARGET_ACHIEVED = 1, - PRIMA_TRSUBP_FAILED = 2, - PRIMA_MAXFUN_REACHED = 3, - PRIMA_MAXTR_REACHED = 20, - PRIMA_NAN_INF_X = -1, - PRIMA_NAN_INF_F = -2, - PRIMA_NAN_INF_MODEL = -3, - PRIMA_NO_SPACE_BETWEEN_BOUNDS = 6, - PRIMA_DAMAGING_ROUNDING = 7, - PRIMA_ZERO_LINEAR_CONSTRAINT = 8, - PRIMA_CALLBACK_TERMINATE = 30, - PRIMA_INVALID_INPUT = 100, - PRIMA_ASSERTION_FAILS = 101, - PRIMA_VALIDATION_FAILS = 102, - PRIMA_MEMORY_ALLOCATION_FAILS = 103, - PRIMA_NULL_OPTIONS = 110, - PRIMA_NULL_PROBLEM = 111, - PRIMA_NULL_X0 = 112, - PRIMA_NULL_RESULT = 113, - PRIMA_NULL_FUNCTION = 114, - PRIMA_PROBLEM_SOLVER_MISMATCH_NONLINEAR_CONSTRAINTS = 115, - PRIMA_PROBLEM_SOLVER_MISMATCH_LINEAR_CONSTRAINTS = 116, - PRIMA_PROBLEM_SOLVER_MISMATCH_BOUNDS = 117, +typedef enum { + PRIMA_SMALL_TR_RADIUS = 0, + PRIMA_FTARGET_ACHIEVED = 1, + PRIMA_TRSUBP_FAILED = 2, + PRIMA_MAXFUN_REACHED = 3, + PRIMA_MAXTR_REACHED = 20, + PRIMA_NAN_INF_X = -1, + PRIMA_NAN_INF_F = -2, + PRIMA_NAN_INF_MODEL = -3, + PRIMA_NO_SPACE_BETWEEN_BOUNDS = 6, + PRIMA_DAMAGING_ROUNDING = 7, + PRIMA_ZERO_LINEAR_CONSTRAINT = 8, + PRIMA_CALLBACK_TERMINATE = 30, + PRIMA_INVALID_INPUT = 100, + PRIMA_ASSERTION_FAILS = 101, + PRIMA_VALIDATION_FAILS = 102, + PRIMA_MEMORY_ALLOCATION_FAILS = 103, + PRIMA_NULL_OPTIONS = 110, + PRIMA_NULL_PROBLEM = 111, + PRIMA_NULL_X0 = 112, + PRIMA_NULL_RESULT = 113, + PRIMA_NULL_FUNCTION = 114, + PRIMA_PROBLEM_SOLVER_MISMATCH_NONLINEAR_CONSTRAINTS = 115, + PRIMA_PROBLEM_SOLVER_MISMATCH_LINEAR_CONSTRAINTS = 116, + PRIMA_PROBLEM_SOLVER_MISMATCH_BOUNDS = 117, } prima_rc_t; @@ -87,7 +85,7 @@ const char *prima_get_rc_string(const prima_rc_t rc); * f : on output, the value of the function * a NaN value can be passed to signal an evaluation error * data : user data -*/ + */ typedef void (*prima_obj_t)(const double x[], double *f, const void *data); @@ -100,7 +98,7 @@ typedef void (*prima_obj_t)(const double x[], double *f, const void *data); * with the constraints being constr <= 0 * NaN values can be passed to signal evaluation errors * data : user data -*/ + */ typedef void (*prima_objcon_t)(const double x[], double *f, double constr[], const void *data); @@ -115,70 +113,70 @@ typedef void (*prima_objcon_t)(const double x[], double *f, double constr[], con * m_nlcon : number of nonlinear constraints (COBYLA only) * nlconstr : nonlinear constraint values of the current best point (COBYLA only) * terminate : a boolean to ask for termination -*/ + */ typedef void (*prima_callback_t)(const int n, const double x[], const double f, int nf, int tr, - const double cstrv, int m_nlcon, const double nlconstr[], bool *terminate); + const double cstrv, int m_nlcon, const double nlconstr[], bool *terminate); // Structure to hold the problem // In the following, "Default" refers to the value set by `prima_init_problem`. typedef struct { - // n: number of variables, n >= 1 - // Default: 0 - int n; - - // calfun: pointer to the objective function to minimize - // Should not be NULL for UOBYQA, NEWUOA, BOBYQA, and LINCOA; should be NULL for COBYLA - // Default: NULL - prima_obj_t calfun; - - // calcfc: pointer to the objective & constraint function to minimize - // Should not be NULL for COBYLA; should be NULL for UOBYQA, NEWUOA, BOBYQA, and LINCOA - // Default: NULL - prima_objcon_t calcfc; - - // starting point - // Should not be NULL - // Default: NULL - double *x0; - - // Bound constraints: xl <= x <= xu - // Should be NULL for UOBYQA and NEWUOA - // Default: xl = NULL and xu = NULL - double *xl; - double *xu; - - // Linear inequality constraints: Aineq*x <= bineq - // Aineq is an m_ineq-by-n matrix stored in row-major order (row by row) - // bineq is of size m_ineq - // Should be m_ineq = 0, Aineq = NULL, and bineq = NULL for UOBYQA, NEWUOA, and BOBYQA - // Default: m_ineq = 0, Aineq = NULL, and bineq = NULL - int m_ineq; - double *Aineq; - double *bineq; - - // Linear equality constraints: Aeq*x = beq - // Aeq is an m_eq-by-n matrix stored in row-major order (row by row) - // beq is of size m_eq - // Should be m_eq = 0, Aeq = NULL, and beq = NULL for UOBYQA, NEWUOA, and BOBYQA - // Default: m_eq = 0, Aeq = NULL, and beq = NULL - int m_eq; - double *Aeq; - double *beq; - - // m_nlcon: number of nonlinear constraints - // Should be 0 for UOBYQA, NEWUOA, BOBYQA, and LINCOA - // Default: 0 - int m_nlcon; - - // f0, nlconstr0: initial objective function value and constraint values (COBYLA only) - // Should ONLY be used when interfacing with MATLAB/Python/Julia/R, where we need to evaluate - // the constraints at the initial point to get m_nlcon - // C end users should leave them as the default, i.e., f0 = NAN and nlconstr0 = NULL. - // Default: f0 = NAN and nlconstr0 = NULL - double f0; - double *nlconstr0; + // n: number of variables, n >= 1 + // Default: 0 + int n; + + // calfun: pointer to the objective function to minimize + // Should not be NULL for UOBYQA, NEWUOA, BOBYQA, and LINCOA; should be NULL for COBYLA + // Default: NULL + prima_obj_t calfun; + + // calcfc: pointer to the objective & constraint function to minimize + // Should not be NULL for COBYLA; should be NULL for UOBYQA, NEWUOA, BOBYQA, and LINCOA + // Default: NULL + prima_objcon_t calcfc; + + // starting point + // Should not be NULL + // Default: NULL + double *x0; + + // Bound constraints: xl <= x <= xu + // Should be NULL for UOBYQA and NEWUOA + // Default: xl = NULL and xu = NULL + double *xl; + double *xu; + + // Linear inequality constraints: Aineq*x <= bineq + // Aineq is an m_ineq-by-n matrix stored in row-major order (row by row) + // bineq is of size m_ineq + // Should be m_ineq = 0, Aineq = NULL, and bineq = NULL for UOBYQA, NEWUOA, and BOBYQA + // Default: m_ineq = 0, Aineq = NULL, and bineq = NULL + int m_ineq; + double *Aineq; + double *bineq; + + // Linear equality constraints: Aeq*x = beq + // Aeq is an m_eq-by-n matrix stored in row-major order (row by row) + // beq is of size m_eq + // Should be m_eq = 0, Aeq = NULL, and beq = NULL for UOBYQA, NEWUOA, and BOBYQA + // Default: m_eq = 0, Aeq = NULL, and beq = NULL + int m_eq; + double *Aeq; + double *beq; + + // m_nlcon: number of nonlinear constraints + // Should be 0 for UOBYQA, NEWUOA, BOBYQA, and LINCOA + // Default: 0 + int m_nlcon; + + // f0, nlconstr0: initial objective function value and constraint values (COBYLA only) + // Should ONLY be used when interfacing with MATLAB/Python/Julia/R, where we need to evaluate + // the constraints at the initial point to get m_nlcon + // C end users should leave them as the default, i.e., f0 = NAN and nlconstr0 = NULL. + // Default: f0 = NAN and nlconstr0 = NULL + double f0; + double *nlconstr0; } prima_problem_t; @@ -192,43 +190,43 @@ int prima_init_problem(prima_problem_t *problem, int n); // In the following, "Default" refers to the value set by `prima_init_options`. typedef struct { - // rhobeg: a reasonable initial change to the variables - // Default: NaN, which will be interpreted in Fortran as not present, in which case a default - // value will be used - double rhobeg; + // rhobeg: a reasonable initial change to the variables + // Default: NaN, which will be interpreted in Fortran as not present, in which case a default + // value will be used + double rhobeg; - // rhoend: required accuracy for the variables - // Default: NaN, which will be interpreted in Fortran as not present, in which case a default - // value will be used - double rhoend; + // rhoend: required accuracy for the variables + // Default: NaN, which will be interpreted in Fortran as not present, in which case a default + // value will be used + double rhoend; - // maxfun: maximum number of function evaluations - // Default: 0, which will be interpreted in Fortran as not present, in which case a default value - // will be used - int maxfun; + // maxfun: maximum number of function evaluations + // Default: 0, which will be interpreted in Fortran as not present, in which case a default value + // will be used + int maxfun; - // iprint: verbosity level (see the prima_message_t enum) - // Default: PRIMA_MSG_NONE, which means that no message will be printed - int iprint; + // iprint: verbosity level (see the prima_message_t enum) + // Default: PRIMA_MSG_NONE, which means that no message will be printed + int iprint; - // ftarget: target function value; solver stops when f <= ftarget for a feasible point - // Default: -Inf - double ftarget; + // ftarget: target function value; solver stops when f <= ftarget for a feasible point + // Default: -Inf + double ftarget; - // npt: number of points in the interpolation set for NEWUOA, BOBYQA, and LINCOA - // Should satisfy n+2 <= npt <= (n+1)(n+2)/2 - // It will be ignored by UOBYQA or COBYLA if provided - // Default: 0, which will be interpreted by Fortran as not present, in which case a default value - // based on the algorithm that will be used - int npt; + // npt: number of points in the interpolation set for NEWUOA, BOBYQA, and LINCOA + // Should satisfy n+2 <= npt <= (n+1)(n+2)/2 + // It will be ignored by UOBYQA or COBYLA if provided + // Default: 0, which will be interpreted by Fortran as not present, in which case a default value + // based on the algorithm that will be used + int npt; - // data: user data, will be passed through the objective function callback - // Default: NULL - void *data; + // data: user data, will be passed through the objective function callback + // Default: NULL + void *data; - // callback: pointer to the callback function to report algorithm progress - // Default: NULL, which means that no callback will be called - prima_callback_t callback; + // callback: pointer to the callback function to report algorithm progress + // Default: NULL, which means that no callback will be called + prima_callback_t callback; } prima_options_t; @@ -241,26 +239,26 @@ int prima_init_options(prima_options_t *options); // Structure to hold the result typedef struct { - // x: returned point - double *x; + // x: returned point + double *x; - // f: objective function value at the returned point - double f; + // f: objective function value at the returned point + double f; - // nf: number of objective function evaluations - int nf; + // nf: number of objective function evaluations + int nf; - // cstrv: constraint violation at the returned point (COBYLA and LINCOA only) - double cstrv; + // cstrv: constraint violation at the returned point (COBYLA and LINCOA only) + double cstrv; - // nlconstr: nonlinear constraint values at the returned point, of size m_nlcon (COBYLA only) - double *nlconstr; + // nlconstr: nonlinear constraint values at the returned point, of size m_nlcon (COBYLA only) + double *nlconstr; - // status: return code - int status; + // status: return code + int status; - // message: exit message - const char *message; + // message: exit message + const char *message; } prima_result_t; @@ -281,6 +279,7 @@ int prima_free_result(prima_result_t *result); PRIMAC_API int prima_minimize(const prima_algorithm_t algorithm, prima_problem_t *problem, prima_options_t *options, prima_result_t *result); + #ifdef __cplusplus } #endif diff --git a/c/prima.c b/c/prima.c index bb85add8c6..83e9e1f497 100644 --- a/c/prima.c +++ b/c/prima.c @@ -7,6 +7,7 @@ #include "prima/prima.h" + /* * A NOTE ON DEFAULT VALUES IN OPTIONS AND PROBLEM STRUCTURES * @@ -28,64 +29,65 @@ * If variables are added to options/problems that are optional, the algorithm_c.f90 files must * be updated to treat the default values appropriately. For examples see rhobeg/rhoend(double), * maxfun/npt(int), and xl/xu (array/pointer). -*/ + */ // Function to initialize the problem int prima_init_problem(prima_problem_t *problem, int n) { - if (problem) - { - memset(problem, 0, sizeof(prima_problem_t)); - problem->n = n; - problem->f0 = NAN; - return 0; - } - else - return PRIMA_NULL_PROBLEM; + if (problem) { + memset(problem, 0, sizeof(prima_problem_t)); + problem->n = n; + problem->f0 = NAN; + return 0; + } + else + return PRIMA_NULL_PROBLEM; } // Function to initialize the options int prima_init_options(prima_options_t *options) { - if (options) - { - memset(options, 0, sizeof(prima_options_t)); - options->rhobeg = NAN; // will be interpreted by Fortran as not present - options->rhoend = NAN; // will be interpreted by Fortran as not present - options->iprint = PRIMA_MSG_NONE; - options->ftarget = -INFINITY; - return 0; - } - else - return PRIMA_NULL_OPTIONS; + if (options) { + memset(options, 0, sizeof(prima_options_t)); + options->rhobeg = NAN; // Will be interpreted by Fortran as not present + options->rhoend = NAN; // Will be interpreted by Fortran as not present + options->iprint = PRIMA_MSG_NONE; + options->ftarget = -INFINITY; + return 0; + } + else + return PRIMA_NULL_OPTIONS; } // Function to check whether the problem matches the algorithm int prima_check_problem(prima_problem_t *problem, prima_options_t *options, const int use_constr, const prima_algorithm_t algorithm) { - if (!problem) - return PRIMA_NULL_PROBLEM; - - // check if the user provided information inconsistent with the 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 (!options) - return PRIMA_NULL_OPTIONS; - if (!problem->x0) - return PRIMA_NULL_X0; - if ((use_constr && !problem->calcfc) || (!use_constr && !problem->calfun)) - return PRIMA_NULL_FUNCTION; - return 0; + if (!problem) + return PRIMA_NULL_PROBLEM; + + 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 (!options) + return PRIMA_NULL_OPTIONS; + + if (!problem->x0) + return PRIMA_NULL_X0; + + if ((use_constr && !problem->calcfc) || (!use_constr && !problem->calfun)) + return PRIMA_NULL_FUNCTION; + + return 0; } @@ -93,175 +95,175 @@ int prima_check_problem(prima_problem_t *problem, prima_options_t *options, cons // FIXME: The initialization seems not appropriate. Why should we set f and cstrv to 0, and x to x0? int prima_init_result(prima_result_t *result, prima_problem_t *problem) { - if (result) - { - memset(result, 0, sizeof(prima_result_t)); - result->f = 0.0; - result->cstrv = 0.0; - if (!problem) - return PRIMA_NULL_PROBLEM; - if (!problem->x0) - return PRIMA_NULL_X0; - result->x = (double*)malloc(problem->n * sizeof(double)); - if (!result->x) - return PRIMA_MEMORY_ALLOCATION_FAILS; - // We copy problem->x0 into result->x so that problem->x0 does not get overwritten by the solver. - memcpy(result->x, problem->x0, problem->n * sizeof(double)); - if (problem->m_nlcon > 0) { - result->nlconstr = (double*)calloc(problem->m_nlcon, sizeof(double)); - if (!result->nlconstr) - return PRIMA_MEMORY_ALLOCATION_FAILS; + if (result) { + memset(result, 0, sizeof(prima_result_t)); + result->f = 0.0; + result->cstrv = 0.0; + + if (!problem) + return PRIMA_NULL_PROBLEM; + + if (!problem->x0) + return PRIMA_NULL_X0; + + result->x = (double*)malloc(problem->n * sizeof(double)); + if (!result->x) + return PRIMA_MEMORY_ALLOCATION_FAILS; + + // We copy problem->x0 into result->x so that problem->x0 does not get overwritten by the solver. + memcpy(result->x, problem->x0, problem->n * sizeof(double)); + + if (problem->m_nlcon > 0) { + result->nlconstr = (double*)calloc(problem->m_nlcon, sizeof(double)); + if (!result->nlconstr) + return PRIMA_MEMORY_ALLOCATION_FAILS; + } + return 0; } - return 0; - } - else - return PRIMA_NULL_RESULT; + else + return PRIMA_NULL_RESULT; } // Function to free the result int prima_free_result(prima_result_t *result) { - if (result) - { - if (result->nlconstr) - { - free(result->nlconstr); - result->nlconstr = NULL; + if (result) { + if (result->nlconstr) { + free(result->nlconstr); + result->nlconstr = NULL; + } + if (result->x) { + free(result->x); + result->x = NULL; + } + return 0; } - if (result->x) - { - free(result->x); - result->x = NULL; - } - return 0; - } - else - return PRIMA_NULL_RESULT; + else + return PRIMA_NULL_RESULT; } // Function to get the string corresponding to the return code const char *prima_get_rc_string(const prima_rc_t rc) { - switch (rc) - { - case PRIMA_SMALL_TR_RADIUS: - return "Trust region radius reaches its lower bound"; - case PRIMA_FTARGET_ACHIEVED: - return "The target function value is reached"; - case PRIMA_TRSUBP_FAILED: - return "A trust region step failed to reduce the model"; - case PRIMA_MAXFUN_REACHED: - return "Maximum number of function evaluations reached"; - case PRIMA_MAXTR_REACHED: - return "Maximum number of trust region iterations reached"; - case PRIMA_NAN_INF_X: - return "The input X contains NaN of Inf"; - case PRIMA_NAN_INF_F: - return "The objective or constraint functions return NaN or +Inf"; - case PRIMA_NAN_INF_MODEL: - return "NaN or Inf occurs in the model"; - case PRIMA_NO_SPACE_BETWEEN_BOUNDS: - return "No space between bounds"; - case PRIMA_DAMAGING_ROUNDING: - return "Rounding errors are becoming damaging"; - case PRIMA_ZERO_LINEAR_CONSTRAINT: - return "One of the linear constraints has a zero gradient"; - case PRIMA_CALLBACK_TERMINATE: - return "Callback function requested termination of optimization"; - case PRIMA_INVALID_INPUT: - return "Invalid input"; - case PRIMA_ASSERTION_FAILS: - return "Assertion fails"; - case PRIMA_VALIDATION_FAILS: - return "Validation fails"; - case PRIMA_MEMORY_ALLOCATION_FAILS: - return "Memory allocation fails"; - case PRIMA_NULL_OPTIONS: - return "NULL options"; - case PRIMA_NULL_PROBLEM: - return "NULL problem"; - case PRIMA_NULL_X0: - return "NULL x0"; - case PRIMA_NULL_RESULT: - 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"; - } + switch (rc) { + case PRIMA_SMALL_TR_RADIUS: + return "Trust region radius reaches its lower bound"; + case PRIMA_FTARGET_ACHIEVED: + return "The target function value is reached"; + case PRIMA_TRSUBP_FAILED: + return "A trust region step failed to reduce the model"; + case PRIMA_MAXFUN_REACHED: + return "Maximum number of function evaluations reached"; + case PRIMA_MAXTR_REACHED: + return "Maximum number of trust region iterations reached"; + case PRIMA_NAN_INF_X: + return "The input X contains NaN of Inf"; + case PRIMA_NAN_INF_F: + return "The objective or constraint functions return NaN or +Inf"; + case PRIMA_NAN_INF_MODEL: + return "NaN or Inf occurs in the model"; + case PRIMA_NO_SPACE_BETWEEN_BOUNDS: + return "No space between bounds"; + case PRIMA_DAMAGING_ROUNDING: + return "Rounding errors are becoming damaging"; + case PRIMA_ZERO_LINEAR_CONSTRAINT: + return "One of the linear constraints has a zero gradient"; + case PRIMA_CALLBACK_TERMINATE: + return "Callback function requested termination of optimization"; + case PRIMA_INVALID_INPUT: + return "Invalid input"; + case PRIMA_ASSERTION_FAILS: + return "Assertion fails"; + case PRIMA_VALIDATION_FAILS: + return "Validation fails"; + case PRIMA_MEMORY_ALLOCATION_FAILS: + return "Memory allocation fails"; + case PRIMA_NULL_OPTIONS: + return "NULL options"; + case PRIMA_NULL_PROBLEM: + return "NULL problem"; + case PRIMA_NULL_X0: + return "NULL x0"; + case PRIMA_NULL_RESULT: + 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 *f, double *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 *nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int iprint, const prima_callback_t callback, int *info); + 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 *nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int iprint, const prima_callback_t callback, int *info); int bobyqa_c(prima_obj_t calfun, const void *data, const int n, double x[], double *f, const double xl[], const double xu[], - int *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 *info); + int *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 *info); int newuoa_c(prima_obj_t calfun, const void *data, const int n, double x[], double *f, - int *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 *info); + int *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 *info); int uobyqa_c(prima_obj_t calfun, const void *data, const int n, double x[], double *f, - int *nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int iprint, const prima_callback_t callback, int *info); + int *nf, const double rhobeg, const double rhoend, const double ftarget, const int maxfun, const int iprint, const prima_callback_t callback, int *info); int lincoa_c(prima_obj_t calfun, const void *data, const int n, double x[], double *f, - double *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 *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 *info); + double *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 *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 *info); // The function that does the minimization using a PRIMA solver int prima_minimize(const prima_algorithm_t algorithm, prima_problem_t *problem, prima_options_t *options, prima_result_t *result) { - int use_constr = (algorithm == PRIMA_COBYLA); - - int info = prima_check_problem(problem, options, use_constr, algorithm); - if (info == 0) - info = prima_init_result(result, problem); - - if (info == 0) - { - switch (algorithm) - { - case PRIMA_BOBYQA: - bobyqa_c(problem->calfun, options->data, problem->n, result->x, &(result->f), problem->xl, problem->xu, &(result->nf), options->rhobeg, options->rhoend, options->ftarget, options->maxfun, options->npt, options->iprint, options->callback, &info); - break; - - case PRIMA_COBYLA: - cobyla_c(problem->m_nlcon, problem->calcfc, options->data, problem->n, result->x, &(result->f), &(result->cstrv), result->nlconstr, - problem->m_ineq, problem->Aineq, problem->bineq, problem->m_eq, problem->Aeq, problem->beq, - problem->xl, problem->xu, problem->f0, problem->nlconstr0, &(result->nf), options->rhobeg, options->rhoend, options->ftarget, options->maxfun, options->iprint, options->callback, &info); - break; - - case PRIMA_LINCOA: - lincoa_c(problem->calfun, options->data, problem->n, result->x, &(result->f), &(result->cstrv), - problem->m_ineq, problem->Aineq, problem->bineq, problem->m_eq, problem->Aeq, problem->beq, - problem->xl, problem->xu, &(result->nf), options->rhobeg, options->rhoend, options->ftarget, options->maxfun, options->npt, options->iprint, options->callback, &info); - break; - - case PRIMA_NEWUOA: - newuoa_c(problem->calfun, options->data, problem->n, result->x, &(result->f), &(result->nf), options->rhobeg, options->rhoend, options->ftarget, options->maxfun, options->npt, options->iprint, options->callback, &info); - break; - - case PRIMA_UOBYQA: - uobyqa_c(problem->calfun, options->data, problem->n, result->x, &(result->f), &(result->nf), options->rhobeg, options->rhoend, options->ftarget, options->maxfun, options->iprint, options->callback, &info); - break; - - default: - return PRIMA_INVALID_INPUT; + int use_constr = (algorithm == PRIMA_COBYLA); + + int info = prima_check_problem(problem, options, use_constr, algorithm); + if (info == 0) + info = prima_init_result(result, problem); + + if (info == 0) { + switch (algorithm) { + case PRIMA_BOBYQA: + bobyqa_c(problem->calfun, options->data, problem->n, result->x, &(result->f), problem->xl, problem->xu, &(result->nf), options->rhobeg, options->rhoend, options->ftarget, options->maxfun, options->npt, options->iprint, options->callback, &info); + break; + + case PRIMA_COBYLA: + cobyla_c(problem->m_nlcon, problem->calcfc, options->data, problem->n, result->x, &(result->f), &(result->cstrv), result->nlconstr, + problem->m_ineq, problem->Aineq, problem->bineq, problem->m_eq, problem->Aeq, problem->beq, + problem->xl, problem->xu, problem->f0, problem->nlconstr0, &(result->nf), options->rhobeg, options->rhoend, options->ftarget, options->maxfun, options->iprint, options->callback, &info); + break; + + case PRIMA_LINCOA: + lincoa_c(problem->calfun, options->data, problem->n, result->x, &(result->f), &(result->cstrv), + problem->m_ineq, problem->Aineq, problem->bineq, problem->m_eq, problem->Aeq, problem->beq, + problem->xl, problem->xu, &(result->nf), options->rhobeg, options->rhoend, options->ftarget, options->maxfun, options->npt, options->iprint, options->callback, &info); + break; + + case PRIMA_NEWUOA: + newuoa_c(problem->calfun, options->data, problem->n, result->x, &(result->f), &(result->nf), options->rhobeg, options->rhoend, options->ftarget, options->maxfun, options->npt, options->iprint, options->callback, &info); + break; + + case PRIMA_UOBYQA: + uobyqa_c(problem->calfun, options->data, problem->n, result->x, &(result->f), &(result->nf), options->rhobeg, options->rhoend, options->ftarget, options->maxfun, options->iprint, options->callback, &info); + break; + + default: + return PRIMA_INVALID_INPUT; + } + + result->status = info; + result->message = prima_get_rc_string(info); } - result->status = info; - result->message = prima_get_rc_string(info); - } - return info; + + return info; }