I am doing an optimization where the parameters need to be estimated are variance-covariance matrix. And I am using differential_evolution from scipy for the optimation.
def likelihood(params):
p = params[0] # this parameter is not related to var-covar matrix
dev = np.diag(params[8:15])
X = np.eye(dev.shape[0])
X[0, 1:7] = params[15:21]
X[1, 2:7] = params[21:26]
X[2, 3:7] = params[26:30]
X[3, 4:7] = params[30:33]
X[4, 5:7] = params[33:35]
X[5, 6:7] = params[35:36]
X = X + X.T - np.diag(np.diag(X))
cov = dev.dot(X).dot(dev)
L = np.linalg.cholesky(cov)
# only for reproduce.
arg1 = -0.2 * np.sqrt(0.5 * (params[0] ** 2 + params[1] ** 2))
arg2 = 0.5 * (np.cos(2. * np.pi * params[0]) + np.cos(2. * np.pi * params[1]))
return -20. * np.exp(arg1) - np.exp(arg2) + 20. + np.e + params.sum()
def constrain(params):
dev = np.diag(params[8:15])
X = np.eye(dev.shape[0])
X[0, 1:7] = params[15:21]
X[1, 2:7] = params[21:26]
X[2, 3:7] = params[26:30]
X[3, 4:7] = params[30:33]
X[4, 5:7] = params[33:35]
X[5, 6:7] = params[35:36]
X = X + X.T - np.diag(np.diag(X))
cov = dev.dot(X).dot(dev)
try:
np.linalg.cholesky(cov)
return 0
except np.linalg.LinAlgError:
return 1
def print_de(x, convergence):
print(x,"convergence: ",convergence)
bounds = (((0.0, 1.0),) * 8 + ((0.0, 1.0),) + ((0.0, 0.5),) * 6 + ((-1.0,1.0),)*21)
differential_evolution(likelihood, bounds=bounds, disp=True,
callback=print_de,
constraints=NonlinearConstraint(constrain, 0, 0)
)
For the first 100 steps from the callback, f(x)=inf, and it progresses very fast.
I tried to verify one x, and it does not meet the constraint. So I believe all these first 100 steps are ruling out x that do not meet the constraint.
However, it seems that this causes problem of non-convergence. See here.
So my question is how to verify var-covariance matrix without affecting convergence?
Edit:
I added an optimization problem from the documentation for reproduce only. In this example, it shows the first couple steps have f(x)=inf, but it does give convergence>0 which is different from my actual problem, where I am only getting convergence=0.0 so far (at the step 458).
Taking a series of wild guesses about the nature of your data, you don't actually need differential evolution. Use plain-old
minimize, and as I said in the comments, don't attempt acholeskyin the constraint - instead, use a continuous proxy metric that implies positive definiteness when the bounds are met. This runs without problem: