From 6e93e4858c26bc27350ca0a3d175707ea00f5b9d Mon Sep 17 00:00:00 2001 From: Nickolai Belakovski Date: Fri, 12 Apr 2024 16:52:21 -0400 Subject: [PATCH 1/4] Change return types to prima_rc_t This should help users figure out how and where to look up any error codes they might receive while trying to use PRIMA. --- c/include/prima/prima.h | 8 ++++---- c/prima.c | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/c/include/prima/prima.h b/c/include/prima/prima.h index d8dac7fd26..9bd6532bb3 100644 --- a/c/include/prima/prima.h +++ b/c/include/prima/prima.h @@ -188,7 +188,7 @@ typedef struct { // Function to initialize the problem PRIMAC_API -int prima_init_problem(prima_problem_t *const problem, const int n); +prima_rc_t prima_init_problem(prima_problem_t *const problem, const int n); // Structure to hold the options @@ -246,7 +246,7 @@ typedef struct { // Function to initialize the options PRIMAC_API -int prima_init_options(prima_options_t *const options); +prima_rc_t prima_init_options(prima_options_t *const options); // Structure to hold the result @@ -281,7 +281,7 @@ typedef struct { // Function to free the result PRIMAC_API -int prima_free_result(prima_result_t *const result); +prima_rc_t prima_free_result(prima_result_t *const result); /* @@ -296,7 +296,7 @@ int prima_free_result(prima_result_t *const result); * return : see prima_rc_t enum for return codes */ PRIMAC_API -int prima_minimize(const prima_algorithm_t algorithm, const prima_problem_t problem, const prima_options_t options, prima_result_t *const result); +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); #ifdef __cplusplus diff --git a/c/prima.c b/c/prima.c index 69f07da051..7847a9dd23 100644 --- a/c/prima.c +++ b/c/prima.c @@ -34,7 +34,7 @@ // Function to initialize the problem -int prima_init_problem(prima_problem_t *const problem, const int n) +prima_rc_t prima_init_problem(prima_problem_t *const problem, const int n) { if (!problem) return PRIMA_NULL_PROBLEM; @@ -47,7 +47,7 @@ int prima_init_problem(prima_problem_t *const problem, const int n) // Function to initialize the options -int prima_init_options(prima_options_t *const options) +prima_rc_t prima_init_options(prima_options_t *const options) { if (!options) return PRIMA_NULL_OPTIONS; @@ -63,7 +63,7 @@ int prima_init_options(prima_options_t *const options) // Function to check whether the problem matches the algorithm -int prima_check_problem(const prima_problem_t problem, const prima_algorithm_t 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; @@ -86,7 +86,7 @@ int prima_check_problem(const prima_problem_t problem, const prima_algorithm_t a // Function to initialize the result -int prima_init_result(prima_result_t *const result, const prima_problem_t problem) +prima_rc_t prima_init_result(prima_result_t *const result, const prima_problem_t problem) { if (!result) return PRIMA_NULL_RESULT; @@ -129,7 +129,7 @@ int prima_init_result(prima_result_t *const result, const prima_problem_t proble // Function to free the result -int prima_free_result(prima_result_t *const result) +prima_rc_t prima_free_result(prima_result_t *const result) { if (!result) return PRIMA_NULL_RESULT; @@ -230,9 +230,9 @@ int lincoa_c(prima_obj_t calfun, const void *data, const int n, double x[], doub // The function that does the minimization using a PRIMA solver -int prima_minimize(const prima_algorithm_t algorithm, const prima_problem_t problem, const prima_options_t options, prima_result_t *const result) +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) { - int info = prima_init_result(result, problem); + prima_rc_t info = prima_init_result(result, problem); if (info == 0) info = prima_check_problem(problem, algorithm); From 271c72c2a6fdb4100191ea99c2db909360fa5980 Mon Sep 17 00:00:00 2001 From: Nickolai Belakovski Date: Sat, 13 Apr 2024 09:43:50 -0400 Subject: [PATCH 2/4] Add PRIMA_RC_DFT and modify everything to use prima_rc_t --- c/examples/bobyqa/bobyqa_example.c | 2 +- c/examples/cobyla/cobyla_example.c | 2 +- c/examples/lincoa/lincoa_example.c | 2 +- c/examples/newuoa/newuoa_example.c | 2 +- c/examples/uobyqa/uobyqa_example.c | 2 +- c/include/prima/prima.h | 1 + c/prima.c | 14 +++++++------- c/tests/data.c | 2 +- c/tests/stress.c | 4 ++-- 9 files changed, 16 insertions(+), 15 deletions(-) diff --git a/c/examples/bobyqa/bobyqa_example.c b/c/examples/bobyqa/bobyqa_example.c index 89226d0d5a..b73b1dc4df 100644 --- a/c/examples/bobyqa/bobyqa_example.c +++ b/c/examples/bobyqa/bobyqa_example.c @@ -57,7 +57,7 @@ int main(int argc, char * argv[]) // Call the solver prima_result_t result; - const int rc = prima_minimize(PRIMA_BOBYQA, problem, options, &result); + const prima_rc_t 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); diff --git a/c/examples/cobyla/cobyla_example.c b/c/examples/cobyla/cobyla_example.c index f381abb92f..f0dd1b36b5 100644 --- a/c/examples/cobyla/cobyla_example.c +++ b/c/examples/cobyla/cobyla_example.c @@ -66,7 +66,7 @@ int main(int argc, char * argv[]) // Call the solver prima_result_t result; - const int rc = prima_minimize(PRIMA_COBYLA, problem, options, &result); + const prima_rc_t 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); diff --git a/c/examples/lincoa/lincoa_example.c b/c/examples/lincoa/lincoa_example.c index 1018c71c27..f341dce591 100644 --- a/c/examples/lincoa/lincoa_example.c +++ b/c/examples/lincoa/lincoa_example.c @@ -58,7 +58,7 @@ int main(int argc, char * argv[]) // Call the solver prima_result_t result; - const int rc = prima_minimize(PRIMA_LINCOA, problem, options, &result); + const prima_rc_t 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); diff --git a/c/examples/newuoa/newuoa_example.c b/c/examples/newuoa/newuoa_example.c index 86d4c90bcb..21356d1a2d 100644 --- a/c/examples/newuoa/newuoa_example.c +++ b/c/examples/newuoa/newuoa_example.c @@ -52,7 +52,7 @@ int main(int argc, char * argv[]) // Call the solver prima_result_t result; - const int rc = prima_minimize(PRIMA_NEWUOA, problem, options, &result); + const prima_rc_t 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); diff --git a/c/examples/uobyqa/uobyqa_example.c b/c/examples/uobyqa/uobyqa_example.c index 220eab8a79..79c18c39b2 100644 --- a/c/examples/uobyqa/uobyqa_example.c +++ b/c/examples/uobyqa/uobyqa_example.c @@ -52,7 +52,7 @@ int main(int argc, char * argv[]) // Run the solver prima_result_t result; - const int rc = prima_minimize(PRIMA_UOBYQA, problem, options, &result); + const prima_rc_t 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); diff --git a/c/include/prima/prima.h b/c/include/prima/prima.h index 9bd6532bb3..2eee11adc2 100644 --- a/c/include/prima/prima.h +++ b/c/include/prima/prima.h @@ -47,6 +47,7 @@ typedef enum { // Possible return values typedef enum { + PRIMA_RC_DFT = 0, PRIMA_SMALL_TR_RADIUS = 0, PRIMA_FTARGET_ACHIEVED = 1, PRIMA_TRSUBP_FAILED = 2, diff --git a/c/prima.c b/c/prima.c index 7847a9dd23..bfa45e02d7 100644 --- a/c/prima.c +++ b/c/prima.c @@ -42,7 +42,7 @@ prima_rc_t prima_init_problem(prima_problem_t *const problem, const int n) memset(problem, 0, sizeof(prima_problem_t)); problem->n = n; problem->f0 = NAN; - return 0; + return PRIMA_RC_DFT; } @@ -58,7 +58,7 @@ prima_rc_t prima_init_options(prima_options_t *const options) options->iprint = PRIMA_MSG_NONE; options->ftarget = -INFINITY; options->ctol = NAN; // Will be interpreted by Fortran as not present - return 0; + return PRIMA_RC_DFT; } @@ -81,7 +81,7 @@ prima_rc_t prima_check_problem(const prima_problem_t problem, const prima_algori if ((algorithm == PRIMA_COBYLA && !problem.calcfc) || (algorithm != PRIMA_COBYLA && !problem.calfun)) return PRIMA_NULL_FUNCTION; - return 0; + return PRIMA_RC_DFT; } @@ -124,7 +124,7 @@ prima_rc_t prima_init_result(prima_result_t *const result, const prima_problem_t for (int i = 0; i < problem.m_nlcon; i++) result->nlconstr[i] = NAN; - return 0; + return PRIMA_RC_DFT; } @@ -142,7 +142,7 @@ prima_rc_t prima_free_result(prima_result_t *const result) free(result->x); result->x = NULL; } - return 0; + return PRIMA_RC_DFT; } @@ -234,10 +234,10 @@ prima_rc_t prima_minimize(const prima_algorithm_t algorithm, const prima_problem { prima_rc_t info = prima_init_result(result, problem); - if (info == 0) + if (info == PRIMA_RC_DFT) info = prima_check_problem(problem, algorithm); - if (info == 0) { + if (info == PRIMA_RC_DFT) { // We copy x0 into result->x only after prima_check_problem has succeeded, // so that if prima_check_problem failed, result->x will not contained a // seemingly valid value. diff --git a/c/tests/data.c b/c/tests/data.c index 82f0b5bb26..401a1ea5fe 100644 --- a/c/tests/data.c +++ b/c/tests/data.c @@ -144,7 +144,7 @@ int main(int argc, char * argv[]) // Call the solver prima_result_t result; - int rc = prima_minimize(algorithm, problem, options, &result); + const prima_rc_t rc = prima_minimize(algorithm, problem, options, &result); // Print the result printf("f* = %g, cstrv = %g, nlconstr = {%g}, rc = %d, msg = '%s', evals = %d\n", result.f, result.cstrv, result.nlconstr ? result.nlconstr[0] : 0.0, rc, result.message, result.nf); diff --git a/c/tests/stress.c b/c/tests/stress.c index be3323727f..66159a3764 100644 --- a/c/tests/stress.c +++ b/c/tests/stress.c @@ -168,10 +168,10 @@ int main(int argc, char * argv[]) // Call the solver prima_result_t result; - rc = prima_minimize(algorithm, problem, options, &result); + const prima_rc_t rc2 = prima_minimize(algorithm, problem, options, &result); // Print the result - printf("f* = %g, cstrv = %g, nlconstr = {%g}, rc = %d, msg = '%s', evals = %d\n", result.f, result.cstrv, result.nlconstr ? result.nlconstr[0] : 0.0, rc, result.message, result.nf); + printf("f* = %g, cstrv = %g, nlconstr = {%g}, rc = %d, msg = '%s', evals = %d\n", result.f, result.cstrv, result.nlconstr ? result.nlconstr[0] : 0.0, rc2, result.message, result.nf); // Free the result prima_free_result(&result); From bd89906ae8e0682c10188028b120cce83e48e584 Mon Sep 17 00:00:00 2001 From: Nickolai Belakovski Date: Thu, 18 Apr 2024 22:38:26 -0400 Subject: [PATCH 3/4] Refactor seed into separate function --- c/tests/stress.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/c/tests/stress.c b/c/tests/stress.c index 66159a3764..0dff144713 100644 --- a/c/tests/stress.c +++ b/c/tests/stress.c @@ -62,6 +62,18 @@ static void fun_con(const double x[], double *const f, double constr[], const vo (void)data; } +unsigned int get_random_seed() { + // 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); + if (!rc) + return 42; + else + return atoi(buf); +} + // Main function int main(int argc, char * argv[]) { @@ -75,15 +87,7 @@ int main(int argc, char * argv[]) debug = (strcmp(argv[2], "debug") == 0); printf("Debug = %d\n", debug); - // Set the random seed to year/week - // FIXME: Implement this as a function - char buf[10] = {0}; - time_t t = time(NULL); - struct tm *tmp = localtime(&t); - int rc = strftime(buf, 10, "%y%W", tmp); - if (!rc) - return 1; - unsigned seed = atoi(buf); + unsigned int seed = get_random_seed(); printf("Random seed = %d\n", seed); srand(seed); @@ -168,10 +172,10 @@ int main(int argc, char * argv[]) // Call the solver prima_result_t result; - const prima_rc_t rc2 = prima_minimize(algorithm, problem, options, &result); + const prima_rc_t rc = prima_minimize(algorithm, problem, options, &result); // Print the result - printf("f* = %g, cstrv = %g, nlconstr = {%g}, rc = %d, msg = '%s', evals = %d\n", result.f, result.cstrv, result.nlconstr ? result.nlconstr[0] : 0.0, rc2, result.message, result.nf); + printf("f* = %g, cstrv = %g, nlconstr = {%g}, rc = %d, msg = '%s', evals = %d\n", result.f, result.cstrv, result.nlconstr ? result.nlconstr[0] : 0.0, rc, result.message, result.nf); // Free the result prima_free_result(&result); From b5ad6798dafb4dc23e4e04a98507db63f1514ef1 Mon Sep 17 00:00:00 2001 From: Zaikun ZHANG Date: Fri, 19 Apr 2024 21:23:01 +0800 Subject: [PATCH 4/4] Update stress.c to resolve https://github.com/libprima/prima/pull/192/checks?check_run_id=24006379701, which complains that "a function declaration without a prototype is deprecated in all versions of C [-Werror,-Wstrict-prototypes] unsigned int get_random_seed()" --- c/tests/stress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/tests/stress.c b/c/tests/stress.c index 0dff144713..a73f141c0a 100644 --- a/c/tests/stress.c +++ b/c/tests/stress.c @@ -62,7 +62,7 @@ static void fun_con(const double x[], double *const f, double constr[], const vo (void)data; } -unsigned int get_random_seed() { +unsigned int get_random_seed(void) { // Set the random seed to year/week char buf[10] = {0}; time_t t = time(NULL);