I don't really understand what SLSQP is doing when I run this, the denominator of the objective function is always nan (as seen in the callback). When I plug in x0 into the denominator, I get an actual number so I don't understand why its nan in the callback right off the bat?
from scipy.optimize import minimize
import numpy as np
n = 250
x0 = np.ones(n) / n
pred = np.random.normal(loc=0.07, scale=0.2, size=(n))
c = ((np.random.random(size = (n, n)))-0.5) *0.1
def objective(weights):
if np.sum(weights) == 0:
return 10
else:
return -np.dot(weights, pred)/(np.sqrt(np.dot(weights, np.dot(c, weights)))) # /
def custom_callback(xk):
print(np.dot(xk, pred) , (np.sqrt(np.dot(xk, np.dot(c, xk)))))
constraints = (
{'type': 'ineq', 'fun': lambda weights: np.abs(np.sum(weights)) - 0.03},
{'type': 'ineq', 'fun': lambda weights: 1.03 - np.sum(np.abs(weights))},
{'type': 'ineq', 'fun': lambda weights: np.sum(np.abs(weights))-0.97},
)
bounds = tuple((-0.02, 0.02) for asset in range(len(x0)))
result = minimize(objective, x0, method='SLSQP', bounds=bounds, constraints=constraints, options={'disp': 2, 'maxiter' : 100}, callback=custom_callback)
denominator with x0 plugged in:
np.sqrt(np.dot(x0, np.dot(c, x0)))
x0.cis usually positive definite.absis non-differentiable and violates the smoothness assumptions of SQLSQP.