Skip to content

get_initial_step: explain the error when no step was set and no x is given - #651

Merged
stevengj merged 3 commits into
stevengj:masterfrom
inayatku:initial-step-getters
Oct 17, 2026
Merged

stevengj merged 3 commits into
stevengj:masterfrom
inayatku:initial-step-getters

Conversation

@inayatku

@inayatku inayatku commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #545.

get_initial_step(std::vector<double> &v) and get_initial_step() (from NLOPT_GETSET_VEC(initial_step)) call nlopt_get_initial_step with x = NULL. If a step was set with set_initial_step, they return it. If no step was set, the default step depends on x, so nlopt_set_default_initial_step(opt, NULL) returns NLOPT_INVALID_ARGS without a message, and the C++ getters throw std::invalid_argument("nlopt invalid argument"), which does not say why.

After the review, this PR keeps the getters (the first version removed them) and only makes the failure clear:

  • src/api/options.c: when no step was set and x is NULL, nlopt_get_initial_step sets the error message "no initial step was set, and the default initial step depends on x". The C++ wrapper passes it on in std::invalid_argument.
  • test/t_initial_step.cxx: the default step from get_initial_step(x, dx) and get_initial_step_(x), the message of get_initial_step() when no step was set, get_initial_step() and get_initial_step(v) after both setters, and the dimension check of the setter. On master only the message check fails.

The C++ interface and the bindings are unchanged. ctest with MSVC 2022 on Windows: 78 of 78 tests pass.

NLOPT_GETSET_VEC(initial_step) defined get_initial_step(v) and
get_initial_step(), which called nlopt_get_initial_step with x = NULL.
Unless a step had been set, nlopt_get_initial_step needs x to compute
the default step, so these getters threw std::invalid_argument (stevengj#545).
Define only the two setters, and remove the global
nlopt_get_initial_step(opt, dx) overload that existed for these getters.
get_initial_step(x, dx) and get_initial_step_(x) are unchanged; SWIG
already ignored the removed getters.

Add a test of the initial-step setters and getters.
@stevengj

Copy link
Copy Markdown
Owner

Unless a step has been set

Yes that's the point. If a step has been set, there should be a way to get it, no?

As discussed in review, a step that was set should stay readable, so
restore the getters of NLOPT_GETSET_VEC(initial_step). They already
return a step set with set_initial_step; they failed only when no step
was set, with "nlopt invalid argument".

nlopt_get_initial_step now sets the error message "no initial step was
set, and the default initial step depends on x" when x is NULL and no
step was set; the C++ getter passes it on in std::invalid_argument.

The test now checks that the getters return a set step and that the
message explains the failure.
@inayatku inayatku changed the title C++: remove the initial_step getters that do not take x get_initial_step: explain the error when no step was set and no x is given Oct 17, 2026
@inayatku

Copy link
Copy Markdown
Contributor Author

Yes, agreed. The getters already return a step that was set; they only fail when no step was set, and then with just "nlopt invalid argument". In 2280a63 I restored them, and nlopt_get_initial_step now sets the message "no initial step was set, and the default initial step depends on x" when x is NULL and no step was set, so the C++ getter throws std::invalid_argument with that text. The test checks the getters after both setters and the message. I updated the title and description.

@stevengj
stevengj merged commit 5531d35 into stevengj:master Oct 17, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nlopt::get_initial_step overloads always throw std::invalid_argument

2 participants