Skip to content

Commit

Permalink
Add prima_problem
Browse files Browse the repository at this point in the history
  • Loading branch information
jschueller committed Oct 25, 2023
1 parent 35c3c73 commit bd02006
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 163 deletions.
18 changes: 10 additions & 8 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
# New C API

The solver and problem definition options moved to a new `prima_options` struct
that must be initialized before use with `prima_init_options`,
and the results move to `prima_results`:
The solver options and problem definition options moved to a new structs
that must be initialized before use and the results moved also:
```
prima_problem problem;
prima_init_problem(&problem, n);
problem.x0 = x0;
prima_options options;
prima_init_options(&options);
options.iprint = PRIMA_MSG_EXIT;
options.rhoend= 1e-3;
options.maxfun = 200*n;
prima_results results;
const int rc = prima_bobyqa(&fun, n, x, &options, &results);
prima_free_options(&options);
prima_free_results(&results);
prima_result result;
const int rc = prima_bobyqa(&fun, &problem, &options, &result);
prima_free_problem(&problem);
prima_free_result(&result);
```
Both should be freed after use with their dedicated free function.
Problem and result structs should be freed after use with their dedicated free function.
14 changes: 8 additions & 6 deletions c/examples/bobyqa/bobyqa_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,19 @@ int main(int argc, char * argv[])
(void)argc;
(void)argv;
const int n = 2;
double x[2] = {0.0, 0.0};
double x0[2] = {0.0, 0.0};
prima_problem problem;
prima_init_problem(&problem, n);
problem.x0 = x0;
prima_options options;
prima_init_options(&options);
options.iprint = PRIMA_MSG_EXIT;
options.rhoend= 1e-3;
options.maxfun = 200*n;
prima_result result;
const int rc = prima_bobyqa(&fun, n, x, &options, &result);
const char *msg = prima_get_rc_string(rc);
printf("x*={%g, %g} rc=%d msg='%s' evals=%d\n", x[0], x[1], rc, msg, result.nf);
prima_free_options(&options);
const int rc = prima_bobyqa(&fun, &problem, &options, &result);
printf("x*={%g, %g} rc=%d msg='%s' evals=%d\n", result.x[0], result.x[1], rc, result.message, result.nf);
prima_free_problem(&problem);
prima_free_result(&result);
return (fabs(x[0]-3)>2e-2 || fabs(x[1]-2)>2e-2);
return (fabs(result.x[0]-3)>2e-2 || fabs(result.x[1]-2)>2e-2);
}
26 changes: 14 additions & 12 deletions c/examples/cobyla/cobyla_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,34 @@ int main(int argc, char * argv[])
(void)argv;
const int m_nlcon = 1;
const int n = 2;
double x[2] = {0.0, 0.0};
double x0[2] = {0.0, 0.0};
prima_problem problem;
prima_init_problem(&problem, n);
problem.x0 = x0;
prima_options options;
prima_init_options(&options);
options.iprint = PRIMA_MSG_EXIT;
options.rhoend= 1e-3;
options.maxfun = 200*n;
options.m_nlcon = m_nlcon;
problem.m_nlcon = m_nlcon;
// x1<=4, x2<=3, x1+x2<=10
options.m_ineq = 3;
problem.m_ineq = 3;
double Aineq[3*2] = {1.0, 0.0,
0.0, 1.0,
1.0, 1.0};
double bineq[3] = {4.0,
3.0,
10.0};
options.Aineq = Aineq;
options.bineq = bineq;
problem.Aineq = Aineq;
problem.bineq = bineq;
double xl[2] = {-6.0, -6.0};
double xu[2] = {6.0, 6.0};
options.xl = xl;
options.xu = xu;
problem.xl = xl;
problem.xu = xu;
prima_result result;
const int rc = prima_cobyla(&fun, n, x, &options, &result);
const char *msg = prima_get_rc_string(rc);
printf("x*={%g, %g} f*=%g cstrv=%g nlconstr=%g rc=%d msg='%s' evals=%d\n", x[0], x[1], result.f, result.cstrv, result.nlconstr[0], rc, msg, result.nf);
prima_free_options(&options);
const int rc = prima_cobyla(&fun, &problem, &options, &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);
prima_free_problem(&problem);
prima_free_result(&result);
return (fabs(x[0]-3)>2e-2 || fabs(x[1]-2)>2e-2);
return (fabs(result.x[0]-3)>2e-2 || fabs(result.x[1]-2)>2e-2);
}
24 changes: 13 additions & 11 deletions c/examples/lincoa/lincoa_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,33 @@ int main(int argc, char * argv[])
(void)argc;
(void)argv;
const int n = 2;
double x[2] = {0.0, 0.0};
double x0[2] = {0.0, 0.0};
prima_problem problem;
prima_init_problem(&problem, n);
problem.x0 = x0;
prima_options options;
prima_init_options(&options);
options.iprint = PRIMA_MSG_EXIT;
options.rhoend= 1e-3;
options.maxfun = 200*n;
// x1<=4, x2<=3, x1+x2<=10
options.m_ineq = 3;
problem.m_ineq = 3;
double Aineq[3*2] = {1.0, 0.0,
0.0, 1.0,
1.0, 1.0};
double bineq[3] = {4.0,
3.0,
10.0};
options.Aineq = Aineq;
options.bineq = bineq;
problem.Aineq = Aineq;
problem.bineq = bineq;
double xl[2] = {-6.0, -6.0};
double xu[2] = {6.0, 6.0};
options.xl = xl;
options.xu = xu;
problem.xl = xl;
problem.xu = xu;
prima_result result;
const int rc = prima_lincoa(&fun, n, x, &options, &result);
const char *msg = prima_get_rc_string(rc);
printf("x*={%g, %g} f*=%g cstrv=%g rc=%d msg='%s' evals=%d\n", x[0], x[1], result.f, result.cstrv, rc, msg, result.nf);
prima_free_options(&options);
const int rc = prima_lincoa(&fun, &problem, &options, &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);
prima_free_problem(&problem);
prima_free_result(&result);
return (fabs(x[0]-3)>2e-2 || fabs(x[1]-2)>2e-2);
return (fabs(result.x[0]-3)>2e-2 || fabs(result.x[1]-2)>2e-2);
}
14 changes: 8 additions & 6 deletions c/examples/newuoa/newuoa_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,19 @@ int main(int argc, char * argv[])
(void)argc;
(void)argv;
const int n = 2;
double x[2] = {0.0, 0.0};
double x0[2] = {0.0, 0.0};
prima_problem problem;
prima_init_problem(&problem, n);
problem.x0 = x0;
prima_options options;
prima_init_options(&options);
options.iprint = PRIMA_MSG_EXIT;
options.rhoend= 1e-3;
options.maxfun = 200*n;
prima_result result;
const int rc = prima_newuoa(&fun, n, x, &options, &result);
const char *msg = prima_get_rc_string(rc);
printf("x*={%g, %g} rc=%d msg='%s' evals=%d\n", x[0], x[1], rc, msg, result.nf);
prima_free_options(&options);
const int rc = prima_newuoa(&fun, &problem, &options, &result);
printf("x*={%g, %g} rc=%d msg='%s' evals=%d\n", result.x[0], result.x[1], rc, result.message, result.nf);
prima_free_problem(&problem);
prima_free_result(&result);
return (fabs(x[0]-3)>2e-2 || fabs(x[1]-2)>2e-2);
return (fabs(result.x[0]-3)>2e-2 || fabs(result.x[1]-2)>2e-2);
}
14 changes: 8 additions & 6 deletions c/examples/uobyqa/uobyqa_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,19 @@ int main(int argc, char * argv[])
(void)argc;
(void)argv;
const int n = 2;
double x[2] = {0.0, 0.0};
double x0[2] = {0.0, 0.0};
prima_problem problem;
prima_init_problem(&problem, n);
problem.x0 = x0;
prima_options options;
prima_init_options(&options);
options.iprint = PRIMA_MSG_EXIT;
options.rhoend= 1e-3;
options.maxfun = 200*n;
prima_result result;
const int rc = prima_uobyqa(&fun, n, x, &options, &result);
const char *msg = prima_get_rc_string(rc);
printf("x*={%g, %g} rc=%d msg='%s' evals=%d\n", x[0], x[1], rc, msg, result.nf);
prima_free_options(&options);
const int rc = prima_uobyqa(&fun, &problem, &options, &result);
printf("x*={%g, %g} rc=%d msg='%s' evals=%d\n", result.x[0], result.x[1], rc, result.message, result.nf);
prima_free_problem(&problem);
prima_free_result(&result);
return (fabs(x[0]-3)>2e-2 || fabs(x[1]-2)>2e-2);
return (fabs(result.x[0]-3)>2e-2 || fabs(result.x[1]-2)>2e-2);
}
47 changes: 37 additions & 10 deletions c/include/prima/prima.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ typedef enum
PRIMA_VALIDATION_FAILS = 102,
PRIMA_MEMORY_ALLOCATION_FAILS = 103,
PRIMA_NULL_OPTIONS = 110,
PRIMA_NULL_RESULT = 111,
PRIMA_NULL_PROBLEM = 111,
PRIMA_NULL_X0 = 112,
PRIMA_NULL_RESULT = 113,
} prima_rc;

/*
Expand Down Expand Up @@ -102,6 +104,20 @@ typedef struct {
// user-data, will be passed through the objective function callback
void *data;

} prima_options;

/* Initialize problem */
PRIMAC_API
int prima_init_options(prima_options *options);

typedef struct {

// dimension of the problem
int n;

// starting point
double *x0;

// bound constraints, ignored for newuoa & uobyqa
double *xl;
double *xu;
Expand Down Expand Up @@ -134,17 +150,22 @@ typedef struct {
// whether prima had to allocate nlconstr0 (private, do not use)
int _allocated_nlconstr0;

} prima_options;
} prima_problem;


/* Initialize/free option data */
/* Initialize/free problem */
PRIMAC_API
int prima_init_options(prima_options * options);
int prima_init_problem(prima_problem *problem, int n);

PRIMAC_API
int prima_free_options(prima_options * opt);
int prima_free_problem(prima_problem *problem);


typedef struct {

// final point
double *x;

// objective value
double f;

Expand All @@ -160,6 +181,12 @@ typedef struct {
// size of nlconstr (private, do not use)
int _m_nlcon;

// exit code
int status;

// error message
const char *message;

} prima_result;


Expand All @@ -179,19 +206,19 @@ int prima_free_result(prima_result * result);
*/

PRIMAC_API
int prima_bobyqa(const prima_obj calfun, const int n, double x[], prima_options *options, prima_result *result);
int prima_bobyqa(const prima_obj calfun, prima_problem *problem, prima_options *options, prima_result *result);

PRIMAC_API
int prima_newuoa(const prima_obj calfun, const int n, double x[], prima_options *options, prima_result *result);
int prima_newuoa(const prima_obj calfun, prima_problem *problem, prima_options *options, prima_result *result);

PRIMAC_API
int prima_uobyqa(const prima_obj calfun, const int n, double x[], prima_options *options, prima_result *result);
int prima_uobyqa(const prima_obj calfun, prima_problem *problem, prima_options *options, prima_result *result);

PRIMAC_API
int prima_cobyla(const prima_objcon calcfc, const int n, double x[], prima_options *options, prima_result *result);
int prima_cobyla(const prima_objcon calcfc, prima_problem *problem, prima_options *options, prima_result *result);

PRIMAC_API
int prima_lincoa(const prima_obj calfun, const int n, double x[], prima_options *options, prima_result *result);
int prima_lincoa(const prima_obj calfun, prima_problem *problem, prima_options *options, prima_result *result);

#ifdef __cplusplus
}
Expand Down
Loading

0 comments on commit bd02006

Please sign in to comment.