Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only exit SLSQP successfully if solution is feasible #465

Merged
merged 1 commit into from
Jul 28, 2022

Conversation

jcmonnin
Copy link
Contributor

Previously, it could stop on ftol or xtol termination criteria, even if some constraints are still blatantly violated. This fixes #368.

Previously, it could stop on ftol or xtol termination criteria, even if some constraints are still blatantly violated. This fixes stevengj#368.
@stevengj
Copy link
Owner

looks good to me

@jonmaddock
Copy link

Hi @stevengj , thanks for this excellent library which I value greatly! I've been experiencing this exact problem too with SLSQP, but I notice the fix hasn't been released yet on PyPI. Is it possible another release could be generated to incorporate this? Many thanks.

edwintorok added a commit to edwintorok/nlopt that referenced this pull request Jun 4, 2023
SLSQP was giving the wrong answer on the tutorial in 't_python.py':
```
optimum at  [0.50777849 4.76252907]
minimum value =  2.182321944309753
```
instead of:
```
optimum at  [0.33333333 0.29629629]
minimum value =  0.5443310523133087
```

Slightly tweaking the function (e.g. to use repeated multiplication
instead of pow), or increasing xtol_rel to 1e-9 made it find the answer.
But the bogus optimum and real optimum are different by more than
xtol_rel.

Printing the function evaluations show that it reaches xtol_rel at an
infeasible point, and then returns the last feasible point:
```
f(0.337085195789626, 0.287031459045266)=0.535753169888211
c(0.337085195789626, 0.287031459045266)=0.019382838080164
c(0.337085195789626, 0.287031459045266)=0.004290454106768
f(0.337085195789626, 0.287031459045266)=0.535753169888211
c(0.337085195789626, 0.287031459045266)=0.019382838080164
c(0.337085195789626, 0.287031459045266)=0.004290454106768
optimum at  [0.50777849 4.76252907]
minimum value =  2.182321944309753
result code =  4
nevals =  22
```

Fix this by checking xtol_rel on mode==-1 only if the current point is
feasible, not when any previous point was feasible
(which matches how the original SLSQP's stopping condition was, and how
the other xtol_rel check is done in this same function).

Now the search continues and finds the correct answer:

```
f(0.337085195789626, 0.287031459045266)=0.535753169888211
c(0.337085195789626, 0.287031459045266)=0.019382838080164
c(0.337085195789626, 0.287031459045266)=0.004290454106768
f(0.298264335607084, 0.000001000000000)=0.001000000000000
c(0.298264335607084, 0.000001000000000)=0.212271613303731
c(0.298264335607084, 0.000001000000000)=0.345556758201188
[...]
f(0.333333334001826, 0.296296294513450)=0.544331052314168
c(0.333333334001826, 0.296296294513450)=0.000000003565495
c(0.333333334001826, 0.296296294513450)=0.000000000891522
optimum at  [0.33333333 0.29629629]
minimum value =  0.5443310523133087
result code =  4
nevals =  48
```

Fixes: 42c43f3 ("Only exit SLSQP successfully if solution is feasible (stevengj#465)")

Signed-off-by: Edwin Török <edwin@etorok.net>
kkofler pushed a commit to kkofler/nlopt that referenced this pull request Oct 22, 2024
SLSQP was giving the wrong answer on the tutorial in 't_python.py':
```
optimum at  [0.50777849 4.76252907]
minimum value =  2.182321944309753
```
instead of:
```
optimum at  [0.33333333 0.29629629]
minimum value =  0.5443310523133087
```

Slightly tweaking the function (e.g. to use repeated multiplication
instead of pow), or increasing xtol_rel to 1e-9 made it find the answer.
But the bogus optimum and real optimum are different by more than
xtol_rel.

Printing the function evaluations show that it reaches xtol_rel at an
infeasible point, and then returns the last feasible point:
```
f(0.337085195789626, 0.287031459045266)=0.535753169888211
c(0.337085195789626, 0.287031459045266)=0.019382838080164
c(0.337085195789626, 0.287031459045266)=0.004290454106768
f(0.337085195789626, 0.287031459045266)=0.535753169888211
c(0.337085195789626, 0.287031459045266)=0.019382838080164
c(0.337085195789626, 0.287031459045266)=0.004290454106768
optimum at  [0.50777849 4.76252907]
minimum value =  2.182321944309753
result code =  4
nevals =  22
```

Fix this by checking xtol_rel on mode==-1 only if the current point is
feasible, not when any previous point was feasible
(which matches how the original SLSQP's stopping condition was, and how
the other xtol_rel check is done in this same function).

Now the search continues and finds the correct answer:

```
f(0.337085195789626, 0.287031459045266)=0.535753169888211
c(0.337085195789626, 0.287031459045266)=0.019382838080164
c(0.337085195789626, 0.287031459045266)=0.004290454106768
f(0.298264335607084, 0.000001000000000)=0.001000000000000
c(0.298264335607084, 0.000001000000000)=0.212271613303731
c(0.298264335607084, 0.000001000000000)=0.345556758201188
[...]
f(0.333333334001826, 0.296296294513450)=0.544331052314168
c(0.333333334001826, 0.296296294513450)=0.000000003565495
c(0.333333334001826, 0.296296294513450)=0.000000000891522
optimum at  [0.33333333 0.29629629]
minimum value =  0.5443310523133087
result code =  4
nevals =  48
```

Fixes: 42c43f3 ("Only exit SLSQP successfully if solution is feasible (stevengj#465)")

Signed-off-by: Edwin Török <edwin@etorok.net>
jschueller pushed a commit to jschueller/nlopt that referenced this pull request Oct 25, 2024
SLSQP was giving the wrong answer on the tutorial in 't_python.py':
```
optimum at  [0.50777849 4.76252907]
minimum value =  2.182321944309753
```
instead of:
```
optimum at  [0.33333333 0.29629629]
minimum value =  0.5443310523133087
```

Slightly tweaking the function (e.g. to use repeated multiplication
instead of pow), or increasing xtol_rel to 1e-9 made it find the answer.
But the bogus optimum and real optimum are different by more than
xtol_rel.

Printing the function evaluations show that it reaches xtol_rel at an
infeasible point, and then returns the last feasible point:
```
f(0.337085195789626, 0.287031459045266)=0.535753169888211
c(0.337085195789626, 0.287031459045266)=0.019382838080164
c(0.337085195789626, 0.287031459045266)=0.004290454106768
f(0.337085195789626, 0.287031459045266)=0.535753169888211
c(0.337085195789626, 0.287031459045266)=0.019382838080164
c(0.337085195789626, 0.287031459045266)=0.004290454106768
optimum at  [0.50777849 4.76252907]
minimum value =  2.182321944309753
result code =  4
nevals =  22
```

Fix this by checking xtol_rel on mode==-1 only if the current point is
feasible, not when any previous point was feasible
(which matches how the original SLSQP's stopping condition was, and how
the other xtol_rel check is done in this same function).

Now the search continues and finds the correct answer:

```
f(0.337085195789626, 0.287031459045266)=0.535753169888211
c(0.337085195789626, 0.287031459045266)=0.019382838080164
c(0.337085195789626, 0.287031459045266)=0.004290454106768
f(0.298264335607084, 0.000001000000000)=0.001000000000000
c(0.298264335607084, 0.000001000000000)=0.212271613303731
c(0.298264335607084, 0.000001000000000)=0.345556758201188
[...]
f(0.333333334001826, 0.296296294513450)=0.544331052314168
c(0.333333334001826, 0.296296294513450)=0.000000003565495
c(0.333333334001826, 0.296296294513450)=0.000000000891522
optimum at  [0.33333333 0.29629629]
minimum value =  0.5443310523133087
result code =  4
nevals =  48
```

Fixes: 42c43f3 ("Only exit SLSQP successfully if solution is feasible (stevengj#465)")

Signed-off-by: Edwin Török <edwin@etorok.net>
jschueller pushed a commit that referenced this pull request Oct 25, 2024
SLSQP was giving the wrong answer on the tutorial in 't_python.py':
```
optimum at  [0.50777849 4.76252907]
minimum value =  2.182321944309753
```
instead of:
```
optimum at  [0.33333333 0.29629629]
minimum value =  0.5443310523133087
```

Slightly tweaking the function (e.g. to use repeated multiplication
instead of pow), or increasing xtol_rel to 1e-9 made it find the answer.
But the bogus optimum and real optimum are different by more than
xtol_rel.

Printing the function evaluations show that it reaches xtol_rel at an
infeasible point, and then returns the last feasible point:
```
f(0.337085195789626, 0.287031459045266)=0.535753169888211
c(0.337085195789626, 0.287031459045266)=0.019382838080164
c(0.337085195789626, 0.287031459045266)=0.004290454106768
f(0.337085195789626, 0.287031459045266)=0.535753169888211
c(0.337085195789626, 0.287031459045266)=0.019382838080164
c(0.337085195789626, 0.287031459045266)=0.004290454106768
optimum at  [0.50777849 4.76252907]
minimum value =  2.182321944309753
result code =  4
nevals =  22
```

Fix this by checking xtol_rel on mode==-1 only if the current point is
feasible, not when any previous point was feasible
(which matches how the original SLSQP's stopping condition was, and how
the other xtol_rel check is done in this same function).

Now the search continues and finds the correct answer:

```
f(0.337085195789626, 0.287031459045266)=0.535753169888211
c(0.337085195789626, 0.287031459045266)=0.019382838080164
c(0.337085195789626, 0.287031459045266)=0.004290454106768
f(0.298264335607084, 0.000001000000000)=0.001000000000000
c(0.298264335607084, 0.000001000000000)=0.212271613303731
c(0.298264335607084, 0.000001000000000)=0.345556758201188
[...]
f(0.333333334001826, 0.296296294513450)=0.544331052314168
c(0.333333334001826, 0.296296294513450)=0.000000003565495
c(0.333333334001826, 0.296296294513450)=0.000000000891522
optimum at  [0.33333333 0.29629629]
minimum value =  0.5443310523133087
result code =  4
nevals =  48
```

Fixes: 42c43f3 ("Only exit SLSQP successfully if solution is feasible (#465)")

Signed-off-by: Edwin Török <edwin@etorok.net>
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.

nloptr SLSQP returning successful flag despite constraints being unmet
3 participants