SLSQP constrained minimization error in 1.5.2
See original GitHub issueSLSQP minimization fails to correctly solve a constrained minimization problem in v1.5.2, which it is able to solve in v1.1.0.
Sample code with the problem explanation, followed by outputs with the two scipy versions
Code
#
# find (Nx1) w that minimizes w'Qw, subject to:
# - non-negative elements in w
# - third element of w = 0.2
# - elements of w sum to one
# - w'r = 0.05862
# correct answer is w = [0, 0, 0.2, 0, 0.8]
import numpy as np
import scipy as sc
from scipy.optimize import minimize
from scipy.optimize import Bounds
Q = np.array([[0.00463, 0.00407, 0.00102, 0.00212, 0.00272],
[0.00407, 0.00412, 0.00079, 0.00185, 0.00289],
[0.00102, 0.00079, 0.00039, 0.00061, 0.00054],
[0.00212, 0.00185, 0.00061, 0.00134, 0.00129],
[0.00272, 0.00289, 0.00054, 0.00129, 0.00214]])
r = np.array([0.12964, 0.11086, 0.03439, 0.11594, 0.06468])
wInit = np.ones((5,1)) * 0.2
bounds = Bounds([0,0,0.2,0,0],
[1,1,0.2,1,1])
objective = lambda w: np.sqrt(w.dot(Q).dot(w.T))
constraints = ({'type': 'eq', 'fun': lambda w: w.sum() - 1},
{'type': 'eq', 'fun': lambda w: w.dot(r.T) - 0.05862})
res = minimize(objective, wInit, method='SLSQP', bounds=bounds,
constraints=constraints)`
print ("Scipy version " + sc.__version__)
print ("Condition number of Q is %.1f" % np.linalg.cond(Q))
print (res)
Output with v1.1.0
Scipy version 1.1.0
Condition number of Q is 373.2
fun: 0.039471508711981115
jac: array([0.0603 , 0.06258, 0.01292, 0.02924, 0.04611])
message: 'Optimization terminated successfully.'
nfev: 300
nit: 23
njev: 19
status: 0
success: True
x: array([3.34781e-17, 1.54010e-16, 2.00000e-01, 9.75493e-17, 8.00000e-01])
Output with v1.5.2
Scipy version 1.5.2
Condition number of Q is 373.2
fun: 0.0440090899701414
jac: array([0.06616815, 0.06235076, nan, 0.03276596, 0.04353646])
message: 'Inequality constraints incompatible'
nfev: 6
nit: 1
njev: 1
status: 4
success: False
x: array([0.2, 0.2, 0.2, 0.2, 0.2])
C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_numdiff.py:519: RuntimeWarning: invalid value encountered in true_divide
J_transposed[i] = df / dx
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:5 (3 by maintainers)
Top Results From Across the Web
constrained SLSQP minimization fails with ub=lb bounds with ...
We are minimizing function f subject to one ineq constraint: sum(x) >= 40. Each element of x is bound to 0 <= x...
Read more >scipy.optimize.minimize — SciPy v1.9.3 Manual
Minimization of scalar function of one or more variables. Parameters. funcallable ... Constraints for COBYLA, SLSQP are defined as a list of dictionaries....
Read more >Scipy.optimize Constrained Minimization Error - Stack Overflow
I am trying to maximize a three variable function, func(x,y,z), under the constraint that two other three variable functions are equal to zero....
Read more >2.7. Mathematical optimization: finding minima of functions
In such situation, even if the objective function is not noisy, a gradient-based optimization may be a noisy optimization. 2.7.1.4. Constraints¶. Optimizations ...
Read more >General Efficient Frontier — PyPortfolioOpt 1.5.2 documentation
While EfficientSemivariance allows for additional constraints/objectives in principle, you are much more likely to run into solver errors.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

I think this is a duplicate of issue #12502, and would be fixed by PR #12889 (with a better description in #12539). The main issue here is that the numerical differentiation now strictly obeys bounds, and it cannot deal with an upper bound that is equal to a lower bound. The proposed fix identifies those parameter entries and sets the gradient to 0 for that entry. With #12502 applied the output for your example comes to:
Should be fixed with #13096