-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
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
BUG: Corruption/segfault in scipy.optimize.minimize with constraints #14915
Comments
Update I've located the issue, I think. |
Hi @i404788, I believe the constraints need to return a scalar value. I don't think there is an issue here. |
It shouldn't crash python though. |
This yes 👍 I am not sure if we can do proper input validation of the constraints before it goes to compiled code. |
Probably |
Yeah I kept it open so we can prevent it from crashing python (even if it's user error). I looked into it out of interest, there is already some input validation in place: Line 468 in 62eb424
It seems like the function is also wrapped depending on if it has a jacobian defined: Line 310 in 62eb424
And it's used a few more times with different contexts, so maybe it's easiest to add another wrapper for input validation. For example: def add_input_validation(f):
def _f(*args, **kwargs):
v = f(*args,**kwargs)
v = atleast1d(v)
assert np.prod(v.shape) == 1, "Constraints need to return a single scalar"
return v
return _f |
For future reference, the constraints functions can return multiple values. For example: import numpy as np
from scipy.optimize import minimize, rosen, NonlinearConstraint
from scipy.optimize._constraints import new_constraint_to_old
N = 4
rng = np.random.default_rng(1)
x0 = rng.uniform(size=N) * 10
bounds = [(0, 10)] * N
def con(x):
# there are 3 inequality constraints here, and one equality
return x[0] + x[1], x[2] + x[3], np.sum(x), x[0] - x[1]
nlc = NonlinearConstraint(con, [0.4, 2, 4, 0], [0.6, 7, 8, 0])
# warning: this is a private function and is subject to change
old_constraint = new_constraint_to_old(nlc, x0)
for c in old_constraint:
cev = c['fun'](x0)
print(len(cev), cev)
res0 = minimize(rosen, x0, bounds=bounds, constraints=nlc)
res1 = minimize(rosen, x0, bounds=bounds, constraints=old_constraint)
assert res0.success
assert res1.success
np.testing.assert_allclose(res0.x, res1.x) gives
|
This is not True, constraint functions can return multiple values. The original example is poor:
Having said all that, it still causes a crash, and that shouldn't happen. |
Hey @andyfaff, |
Describe your issue.
When minimizing with
scipy.optimize.minimize
it crashes python (kernel), with a corruption error.This only happens when constraints are active with
SLSQP
.I also tried scipy 1.7-1.6, but it has the same issue. Also found this issue which might be related: #14159
Reproducing Code Example
Error message
corrupted size vs. prev_size OR corrupted double-linked list OR double free or corruption (!prev)
SciPy/NumPy/Python version information
1.7.1 1.21.3 sys.version_info(major=3, minor=9, micro=2, releaselevel='final', serial=0)
The text was updated successfully, but these errors were encountered: