diff --git a/doc/docs/NLopt_Reference.md b/doc/docs/NLopt_Reference.md index e59a09c6e8f2162ae964ab6ffad694bb05c4d740..6102bf72536b7671c4859ae79cd0a744d1aab65a 100644 --- a/doc/docs/NLopt_Reference.md +++ b/doc/docs/NLopt_Reference.md @@ -118,11 +118,14 @@ It is permitted to set `lb[i]` `==` `ub[i]` in one or more dimensions; this is e Note, however, that some of the algorithms in NLopt, in particular most of the global-optimization algorithms, do not support unconstrained optimization and will return an error in `nlopt_optimize` if you do not supply finite lower and upper bounds. -For convenience, the following two functions are supplied in order to set the lower/upper bounds for all optimization parameters to a single constant (so that you don’t have to fill an array with a constant value): +For convenience, the functions `nlopt_set_*_bounds1` are supplied in order to set the lower/upper bounds for all optimization parameters to a single constant (so that you don’t have to fill an array with a constant value), along with `nlopt_set_*_bound` to set the bound for +a single variable `x[i]`: ``` nlopt_result nlopt_set_lower_bounds1(nlopt_opt opt, double lb); nlopt_result nlopt_set_upper_bounds1(nlopt_opt opt, double ub); +nlopt_result nlopt_set_lower_bound(nlopt_opt opt, int i, double lb); +nlopt_result nlopt_set_upper_bound(nlopt_opt opt, int i, double ub); ``` diff --git a/src/api/nlopt.h b/src/api/nlopt.h index 4bda368f9b8bfb98cf7ed57c8f75b75ceb5ea575..062fd2cf192d3686976ec1eebe2095c6645c926b 100644 --- a/src/api/nlopt.h +++ b/src/api/nlopt.h @@ -211,9 +211,11 @@ NLOPT_EXTERN(const char *) nlopt_get_errmsg(nlopt_opt opt); NLOPT_EXTERN(nlopt_result) nlopt_set_lower_bounds(nlopt_opt opt, const double *lb); NLOPT_EXTERN(nlopt_result) nlopt_set_lower_bounds1(nlopt_opt opt, double lb); +NLOPT_EXTERN(nlopt_result) nlopt_set_lower_bound(nlopt_opt opt, int i, double lb); NLOPT_EXTERN(nlopt_result) nlopt_get_lower_bounds(const nlopt_opt opt, double *lb); NLOPT_EXTERN(nlopt_result) nlopt_set_upper_bounds(nlopt_opt opt, const double *ub); NLOPT_EXTERN(nlopt_result) nlopt_set_upper_bounds1(nlopt_opt opt, double ub); +NLOPT_EXTERN(nlopt_result) nlopt_set_upper_bound(nlopt_opt opt, int i, double ub); NLOPT_EXTERN(nlopt_result) nlopt_get_upper_bounds(const nlopt_opt opt, double *ub); NLOPT_EXTERN(nlopt_result) nlopt_remove_inequality_constraints(nlopt_opt opt); diff --git a/src/api/options.c b/src/api/options.c index 0f9c2ac324a8ceeec38115702e150381dba7890d..d263c7bfd2deb67e3a47df46666cdea77300efe1 100644 --- a/src/api/options.c +++ b/src/api/options.c @@ -7,17 +7,17 @@ * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include @@ -308,6 +308,20 @@ nlopt_result NLOPT_STDCALL nlopt_set_lower_bounds1(nlopt_opt opt, double lb) return NLOPT_INVALID_ARGS; } +nlopt_result NLOPT_STDCALL nlopt_set_lower_bound(nlopt_opt opt, int i, double lb) +{ + nlopt_unset_errmsg(opt); + if (opt) { + if (i < 0 || i >= opt->n) + return ERR(NLOPT_INVALID_ARGS, opt, "invalid bound index"); + opt->lb[i] = lb; + if (opt->lb[i] < opt->ub[i] && nlopt_istiny(opt->ub[i] - opt->lb[i])) + opt->lb[i] = opt->ub[i]; + return NLOPT_SUCCESS; + } + return NLOPT_INVALID_ARGS; +} + nlopt_result NLOPT_STDCALL nlopt_get_lower_bounds(const nlopt_opt opt, double *lb) { nlopt_unset_errmsg(opt); @@ -348,6 +362,20 @@ nlopt_result NLOPT_STDCALL nlopt_set_upper_bounds1(nlopt_opt opt, double ub) return NLOPT_INVALID_ARGS; } +nlopt_result NLOPT_STDCALL nlopt_set_upper_bound(nlopt_opt opt, int i, double ub) +{ + nlopt_unset_errmsg(opt); + if (opt) { + if (i < 0 || i >= opt->n) + return ERR(NLOPT_INVALID_ARGS, opt, "invalid bound index"); + opt->ub[i] = ub; + if (opt->lb[i] < opt->ub[i] && nlopt_istiny(opt->ub[i] - opt->lb[i])) + opt->ub[i] = opt->lb[i]; + return NLOPT_SUCCESS; + } + return NLOPT_INVALID_ARGS; +} + nlopt_result NLOPT_STDCALL nlopt_get_upper_bounds(const nlopt_opt opt, double *ub) { nlopt_unset_errmsg(opt); @@ -410,7 +438,7 @@ static nlopt_result add_constraint(nlopt_opt opt, *m += 1; if (*m > *m_alloc) { - /* allocate by repeated doubling so that + /* allocate by repeated doubling so that we end up with O(log m) mallocs rather than O(m). */ *m_alloc = 2 * (*m); *c = (nlopt_constraint *) realloc(*c, sizeof(nlopt_constraint)