/* given opt, create a new opt with equal-constraint dimensions eliminated */ static nlopt_opt elimdim_create(nlopt_opt opt) { nlopt_opt opt0 = nlopt_copy(opt); double *x, *grad = NULL; unsigned i; if (!opt0) return NULL; x = (double *) malloc(sizeof(double) * opt->n); if (opt->n && !x) { nlopt_destroy(opt0); return NULL; } if (opt->algorithm == NLOPT_GD_STOGO || opt->algorithm == NLOPT_GD_STOGO_RAND) { grad = (double *) malloc(sizeof(double) * opt->n); if (opt->n && !grad) goto bad; } opt0->n = elimdim_dimension(opt->n, opt->lb, opt->ub); elimdim_shrink(opt->n, opt0->lb, opt->lb, opt->ub); elimdim_shrink(opt->n, opt0->ub, opt->lb, opt->ub); elimdim_shrink(opt->n, opt0->xtol_abs, opt->lb, opt->ub); elimdim_shrink(opt->n, opt0->dx, opt->lb, opt->ub); opt0->munge_on_destroy = opt0->munge_on_copy = NULL; opt0->f = elimdim_func; opt0->f_data = elimdim_makedata(opt->f, NULL, opt->f_data, opt->n, x, opt->lb, opt->ub, grad); if (!opt0->f_data) goto bad; for (i = 0; i < opt->m; ++i) { opt0->fc[i].f = elimdim_func; opt0->fc[i].mf = elimdim_mfunc; opt0->fc[i].f_data = elimdim_makedata(opt->fc[i].f, opt->fc[i].mf, opt->fc[i].f_data, opt->n, x, opt->lb, opt->ub, NULL); if (!opt0->fc[i].f_data) goto bad; } for (i = 0; i < opt->p; ++i) { opt0->h[i].f = elimdim_func; opt0->h[i].mf = elimdim_mfunc; opt0->h[i].f_data = elimdim_makedata(opt->h[i].f, opt->h[i].mf, opt->h[i].f_data, opt->n, x, opt->lb, opt->ub, NULL); if (!opt0->h[i].f_data) goto bad; } return opt0; bad: free(grad); free(x); nlopt_destroy(opt0); return NULL; }
nlopt_result NLOPT_STDCALL nlopt_set_local_optimizer(nlopt_opt opt, const nlopt_opt local_opt) { if (opt) { if (local_opt && local_opt->n != opt->n) return NLOPT_INVALID_ARGS; nlopt_destroy(opt->local_opt); opt->local_opt = nlopt_copy(local_opt); if (local_opt) { if (!opt->local_opt) return NLOPT_OUT_OF_MEMORY; nlopt_set_lower_bounds(opt->local_opt, opt->lb); nlopt_set_upper_bounds(opt->local_opt, opt->ub); nlopt_remove_inequality_constraints(opt->local_opt); nlopt_remove_equality_constraints(opt->local_opt); nlopt_set_min_objective(opt->local_opt, NULL, NULL); nlopt_set_munge(opt->local_opt, NULL, NULL); opt->local_opt->force_stop = 0; } return NLOPT_SUCCESS; } return NLOPT_INVALID_ARGS; }
nlopt_opt NLOPT_STDCALL nlopt_copy(const nlopt_opt opt) { nlopt_opt nopt = NULL; unsigned i; if (opt) { nlopt_munge munge; nopt = (nlopt_opt) malloc(sizeof(struct nlopt_opt_s)); *nopt = *opt; nopt->lb = nopt->ub = nopt->xtol_abs = NULL; nopt->fc = nopt->h = NULL; nopt->m_alloc = nopt->p_alloc = 0; nopt->local_opt = NULL; nopt->dx = NULL; nopt->work = NULL; opt->force_stop_child = NULL; munge = nopt->munge_on_copy; if (munge && nopt->f_data) if (!(nopt->f_data = munge(nopt->f_data))) goto oom; if (opt->n > 0) { nopt->lb = (double *) malloc(sizeof(double) * (opt->n)); if (!opt->lb) goto oom; 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; 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->m) { nopt->m_alloc = opt->m; nopt->fc = (nlopt_constraint *) malloc(sizeof(nlopt_constraint) * (opt->m)); if (!nopt->fc) goto oom; memcpy(nopt->fc, opt->fc, sizeof(nlopt_constraint) * (opt->m)); for (i = 0; i < opt->m; ++i) nopt->fc[i].tol = NULL; if (munge) for (i = 0; i < opt->m; ++i) if (nopt->fc[i].f_data && !(nopt->fc[i].f_data = munge(nopt->fc[i].f_data))) goto oom; for (i = 0; i < opt->m; ++i) if (opt->fc[i].tol) { nopt->fc[i].tol = (double *) malloc(sizeof(double) * nopt->fc[i].m); if (!nopt->fc[i].tol) goto oom; memcpy(nopt->fc[i].tol, opt->fc[i].tol, sizeof(double) * nopt->fc[i].m); } } if (opt->p) { nopt->p_alloc = opt->p; nopt->h = (nlopt_constraint *) malloc(sizeof(nlopt_constraint) * (opt->p)); if (!nopt->h) goto oom; memcpy(nopt->h, opt->h, sizeof(nlopt_constraint) * (opt->p)); for (i = 0; i < opt->p; ++i) nopt->h[i].tol = NULL; if (munge) for (i = 0; i < opt->p; ++i) if (nopt->h[i].f_data && !(nopt->h[i].f_data = munge(nopt->h[i].f_data))) goto oom; for (i = 0; i < opt->p; ++i) if (opt->h[i].tol) { nopt->h[i].tol = (double *) malloc(sizeof(double) * nopt->h[i].m); if (!nopt->h[i].tol) goto oom; memcpy(nopt->h[i].tol, opt->h[i].tol, sizeof(double) * nopt->h[i].m); } } if (opt->local_opt) { nopt->local_opt = nlopt_copy(opt->local_opt); if (!nopt->local_opt) goto oom; } if (opt->dx) { nopt->dx = (double *) malloc(sizeof(double) * (opt->n)); if (!nopt->dx) goto oom; memcpy(nopt->dx, opt->dx, sizeof(double) * (opt->n)); } } return nopt; oom: nopt->munge_on_destroy = NULL; // better to leak mem than crash nlopt_destroy(nopt); return NULL; }