I am mostly new to Python and StackOverflow so please point out if I am doing anything wrong/need to include more detail e.t.c. My question revolves around minimizing a function, en_sum, which depends on an array of variables en. This optimisation must be subjected to a constraint nlc: the minimum eigenvalue of a matrix which depends on variables en as well as another set of variables, x2, must be positive.
What I would like to do is essentially provide some guess values of en and x2, optimise en_sum subject to nlc and have it produce the resulting optimised en and x2 values.
The minimal code I have written is as follows:
import numpy as np
from scipy import optimize as spo
from scipy.optimize import NonlinearConstraint
def en_min(varia):
#en_min is a function that (aims to) return the optimised values of en and x2.
m = 2
n = 2
s = 2
en = varia[0:m]
x2 = varia[m:len(varia)]
# use_mat(a,b) defines the matrix which depends on en and x2 variables.
def use_mat(a, b):
mat = np.empty([m * s, n * s])
for i in range(0, m * s):
for j in range(0, m * s):
mat[i, j] = (b[j] * a[i - s]) ** 2 + a[j - s] ** 2 + (b[j] + b[i]) ** 2
return mat
# Defining the optimisation function.
def en_sum(q):
return sum(q[iii] ** 2 for iii in range(len(q)))
# This function provides the minimal eigenvalue of a given matrix.
def min_eigenvalue(a):
y = np.linalg.eigvals(a)
return np.amin(y)
# My attempt at setting the constraint (which is that the eigenvalues of the matrix
# defined through use_mat(a,b) are non-negative) is nlc
nlc = NonlinearConstraint(min_eigenvalue(use_mat(en, x2)), 0, np.inf)
# The guess values in opt_res2 are just for the en variables, as en_sum must
# only be a function of those (not x2). However, I do not know how to properly give guess
# values to x2 in the constraint, so I am quite sure this is implemented incorrectly.
opt_res2 = spo.minimize(en_sum(en), np.array([1, 4]), constraints=nlc)
return opt_res2
print(en_min([1, 3, 1.5, 0, 0, 4]))
Naturally, this does not work (I get error TypeError: 'numpy.complex128' object is not callable amongst others), and I wondered if anyone had any tips about where I could be going wrong, and whether the problem is even tractable in this case? My main confusion comes from not knowing how to properly treat the constraint and how to supply the guess values for x2 (is this related to args in the constraint dictionary?). Any ideas are greatly appreciated, thank you.