I'm trying to use scipy.optimize.minimize with method trust-constr to optimize a function of 8 variables. Unfortunately, the function is too complicated to post in full here; it involves around 1000 terms, each of which involves an integral. But here is an excerpt that I think already shows it doesn't work as expected.
def objective(variables):
starts_neg=variables[0]
starts_neu=variables[1]
etc
return _____
(these are the two variables that cause the problem)
Having defined the objective function, I then need to define the constraints. There are 12 constraints involving the 8 variables; but I'll just show the ones involving the offending variables.
constraint_matrix=[[0 for j in range(8)] for i in range(12)]
constraint_matrix[0][0]=1
constraint_matrix[1][1]=1
constraint_matrix[2][0]=1
constraint_matrix[2][1]=1
etc
lower_bounds=[10**(-12) for i in range(12)]
upper_bounds=[1 for i in range(12)]
prob_constraints=LinearConstraint(constraint_matrix,lower_bounds,upper_bounds,keep_feasible=True)
My intent here is to say 0 < starts_neg < 1, 0 < starts_neu < 1, 0 < start_neg + starts_neu < 1. The lower bounds are changed from 0 to 10^-12 to avoid nan errors, since the objective function involves taking the logs of the variables.
I then give scipy an initial estimate x0=[estimate,estimate,etc.]
Lastly, call optimize as follows:
result=minimize(objective,x0,method='trust-constr',constraints=[prob_constraints],options={'xtol':10**(-9)}).x
Unfortunately, this yielded a nan error. So I tried inserting the following in the objective function and running again:
if starts_neg<=0 or starts_neg>=1 or starts_neu<=0 or starts_neu>=1 or starts_neu+starts_neg>=1:
print(starts_neg,starts_neu)
This outputs -0.02436406136453448 0.7588112085953852
before the nan error & traceback, which seems too large a constraint violation to be explained by rounding error. And no, this was not the initial estimate x0; I checked for that too.
So clearly scipy disobeyed one of my constraints, despite my setting keep_feasible=True
. Did I set up something wrong? Sorry the function is too long to include in full.