Skip to content

Commit

Permalink
do not allocate xtol_abs unless needed
Browse files Browse the repository at this point in the history
As discussed in stevengj#183, it is benefitical to avoid allocating potentially
huge buffers of size `n` unless `x`-tolerance criteria are used.
  • Loading branch information
aitap committed Apr 26, 2019
1 parent 2f1fa1c commit e1e83eb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
32 changes: 23 additions & 9 deletions src/api/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,8 @@ nlopt_opt NLOPT_STDCALL nlopt_create(nlopt_algorithm algorithm, unsigned n)
opt->ub = (double *) calloc(n, sizeof(double));
if (!opt->ub)
goto oom;
opt->xtol_abs = (double *) calloc(n, sizeof(double));
if (!opt->xtol_abs)
goto oom;
nlopt_set_lower_bounds1(opt, -HUGE_VAL);
nlopt_set_upper_bounds1(opt, +HUGE_VAL);
nlopt_set_xtol_abs1(opt, 0.0);
}
}

Expand Down Expand Up @@ -156,9 +152,11 @@ nlopt_opt NLOPT_STDCALL nlopt_copy(const nlopt_opt opt)
nopt->ub = (double *) malloc(sizeof(double) * (opt->n));
if (!opt->ub)
goto oom;
nopt->xtol_abs = (double *) malloc(sizeof(double) * (opt->n));
if (!opt->xtol_abs)
goto oom;
if (opt->xtol_abs) {
nopt->xtol_abs = (double *) malloc(sizeof(double) * (opt->n));
if (!opt->xtol_abs)
goto oom;
}
if (opt->x_weights) {
nopt->x_weights = (double *) malloc(sizeof(double) * (opt->n));
if (!opt->x_weights)
Expand All @@ -168,7 +166,9 @@ nlopt_opt NLOPT_STDCALL nlopt_copy(const nlopt_opt opt)

memcpy(nopt->lb, opt->lb, sizeof(double) * (opt->n));
memcpy(nopt->ub, opt->ub, sizeof(double) * (opt->n));
memcpy(nopt->xtol_abs, opt->xtol_abs, sizeof(double) * (opt->n));
if (opt->xtol_abs) {
memcpy(nopt->xtol_abs, opt->xtol_abs, sizeof(double) * (opt->n));
}
}

if (opt->m) {
Expand Down Expand Up @@ -612,6 +612,10 @@ GETSET(ftol_rel, double, ftol_rel) GETSET(ftol_abs, double, ftol_abs) GETSET(xto
{
if (opt) {
nlopt_unset_errmsg(opt);
if (!opt->xtol_abs && opt->n > 0) {
opt->xtol_abs = (double *) calloc(opt->n, sizeof(double));
if (!opt->xtol_abs) return NLOPT_OUT_OF_MEMORY;
}
memcpy(opt->xtol_abs, xtol_abs, opt->n * sizeof(double));
return NLOPT_SUCCESS;
}
Expand All @@ -623,6 +627,10 @@ nlopt_result NLOPT_STDCALL nlopt_set_xtol_abs1(nlopt_opt opt, double xtol_abs)
if (opt) {
unsigned i;
nlopt_unset_errmsg(opt);
if (!opt->xtol_abs && opt->n > 0) {
opt->xtol_abs = (double *) calloc(opt->n, sizeof(double));
if (!opt->xtol_abs) return NLOPT_OUT_OF_MEMORY;
}
for (i = 0; i < opt->n; ++i)
opt->xtol_abs[i] = xtol_abs;
return NLOPT_SUCCESS;
Expand All @@ -634,7 +642,13 @@ nlopt_result NLOPT_STDCALL nlopt_get_xtol_abs(const nlopt_opt opt, double *xtol_
{
nlopt_unset_errmsg(opt);
if (opt && (opt->n == 0 || xtol_abs)) {
memcpy(xtol_abs, opt->xtol_abs, opt->n * sizeof(double));
if (opt->xtol_abs) {
memcpy(xtol_abs, opt->xtol_abs, sizeof(double) * (opt->n));
} else {
unsigned i;
for (i = 0; i < opt->n; ++i)
xtol_abs[i] = 0;
}
return NLOPT_SUCCESS;
}
return NLOPT_INVALID_ARGS;
Expand Down
3 changes: 3 additions & 0 deletions src/util/stop.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ int nlopt_stop_x(const nlopt_stopping * s, const double *x, const double *oldx)
unsigned i;
if (diff_norm(s->n, x, oldx, s->x_weights, NULL, NULL) <= s->xtol_rel * vector_norm(s->n, x, s->x_weights, NULL, NULL))
return 1;
if (!s->xtol_abs) return 0;
for (i = 0; i < s->n; ++i)
if (fabs(x[i] - oldx[i]) > s->xtol_abs[i])
return 0;
Expand All @@ -111,6 +112,7 @@ int nlopt_stop_dx(const nlopt_stopping * s, const double *x, const double *dx)
unsigned i;
if (vector_norm(s->n, dx, s->x_weights, NULL, NULL) <= s->xtol_rel * vector_norm(s->n, x, s->x_weights, NULL, NULL))
return 1;
if (!s->xtol_abs) return 0;
for (i = 0; i < s->n; ++i)
if (fabs(dx[i]) > s->xtol_abs[i])
return 0;
Expand All @@ -124,6 +126,7 @@ int nlopt_stop_xs(const nlopt_stopping * s, const double *xs, const double *oldx
unsigned i;
if (diff_norm(s->n, xs, oldxs, s->x_weights, scale_min, scale_max) <= s->xtol_rel * vector_norm(s->n, xs, s->x_weights, scale_min, scale_max))
return 1;
if (!s->xtol_abs) return 0;
for (i = 0; i < s->n; ++i)
if (fabs(sc(xs[i], scale_min[i], scale_max[i]) - sc(oldxs[i], scale_min[i], scale_max[i])) > s->xtol_abs[i])
return 0;
Expand Down

0 comments on commit e1e83eb

Please sign in to comment.