Skip to content

Commit

Permalink
Always initialize the result.
Browse files Browse the repository at this point in the history
This resolves #149.
  • Loading branch information
nbelakovski committed Mar 25, 2024
1 parent 890d46d commit aefb7c9
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 11 deletions.
16 changes: 11 additions & 5 deletions c/include/prima/prima.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ int prima_init_options(prima_options_t *const options);


// Structure to hold the result
// prima_minimize will allocate the memory for x and nlconstr (if needed),
// and as such the user is expected to free the memory using prima_free_result
// once they are done using the contents of the result (or have saved the contents).
typedef struct {

// x: returned point
Expand Down Expand Up @@ -277,11 +280,14 @@ int prima_free_result(prima_result_t *const result);


/*
* The function that does the minimization using a PRIMA solver
* algorithm : optimization algorithm (see prima_algorithm)
* problem : optimization problem (see prima_problem)
* options : optimization options (see prima_options)
* result : optimization result (see prima_result)
* The function that does the minimization using a PRIMA solver.
* After using (or saving) the result, the user is expected to call
* prima_free_result, regardless of the return value of prima_minimize,
* in order to avoid memory leaks.
* algorithm : optimization algorithm (see prima_algorithm_t)
* problem : optimization problem (see prima_problem_t)
* options : optimization options (see prima_options_t)
* result : optimization result (see prima_result_t)
* return : see prima_rc_t enum for return codes
*/
PRIMAC_API
Expand Down
19 changes: 13 additions & 6 deletions c/prima.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ int prima_init_result(prima_result_t *const result, const prima_problem_t proble
if (!result->x)
return PRIMA_MEMORY_ALLOCATION_FAILS;
for (int i = 0; i < problem.n; i++)
result->x[i] = problem.x0[i];
result->x[i] = NAN;

// f: objective function value at the returned point
result->f = NAN;
Expand Down Expand Up @@ -238,12 +238,19 @@ int prima_minimize(const prima_algorithm_t algorithm, const prima_problem_t prob
{
int use_constr = (algorithm == PRIMA_COBYLA);

int info = prima_check_problem(problem, use_constr, algorithm);
int info = prima_init_result(result, problem);

if (info == 0)
info = prima_init_result(result, problem);
info = prima_check_problem(problem, use_constr, algorithm);

if (info == 0) {
// 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.
for (int i = 0; i < problem.n; i++) {
result->x[i] = problem.x0[i];
}

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);
Expand Down Expand Up @@ -275,10 +282,10 @@ int prima_minimize(const prima_algorithm_t algorithm, const prima_problem_t prob
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;
}

0 comments on commit aefb7c9

Please sign in to comment.