2016-02-28 182 views
0

我正在努力弄清楚如何从优化手册 (使用最小化例程SLSQP)做到这一点。我的问题有一个变量x0的数组,我试图为我的函数构造一个约束列表。如何指定scipy.optimize的约束列表?

L = 2 
N = 2 

x0 = np.random.uniform(-1.0, 1.0, size=(L*L*N*2,)) 
x0 = x0.reshape(L,L,N,2) 
ff = x0[:, :, :, 0] + 1j*x0[:, :, :, 1] 

约束需要是这样的形式:FF [X,Y,1] ** 2 + FF [X,Y,2] ** 2 + ... + FF [X,Y, N] ** 2 = 1

我认为这应该是可行的,但我正在学习Python,因为我去解决这个问题。我希望这不是一个无足轻重的地方。我尝试到目前为止,

for i_x in range(L): 
for i_y in range(L): 
    cons = {'type':'eq', 'fun': np.sum(np.abs(ff[i_x, i_y, :])**2) - 1} 

x0 = x0.reshape(L*L*N*2,) 
scipy.optimize.minimize(func, x0, constraints=cons) 

而现在,

def constraints(x0, L, N, cons): 
x0 = x0.reshape(L, L, N, 2) 

for i_x in range(L): 
    for i_y in range(L): 
      def con(x0, i_x = i_x, i_y = i_y): 
       return np.sum(np.abs((x0[i_x, i_y, :, 0] + 1j*x0[i_x, i_y, :, 1])**2)) - 1 
      cons.append({'type':'eq', 'fun': con}) 

return cons 

但我收到错误,“太多的指数为阵”

回答

0

我觉得你的代码的一个问题是,它覆盖约束cons。结果,scipy.optimize.minimize函数看到的唯一约束是np.sum(np.abs(ff[-1, -1, :])**2) = 1,其中-1表示最后一个元素L-1。我建议初始化一个空的列表,然后追加到它:

cons = [] 
    for i_x in range(L): 
     for i_y in range(L): 
      cons.append({'type':'eq', 'fun': ...) 

的第二个问题是,约束必须通过相同的向量您要最小化功能,即参数化必须是一个函数形状矢量(L * L * N * 2)。此函数是ff的函数,它具有形状(L,L,N),并且是一个常量(创建时的“冻结”,初始值为x0)不依赖于最小化算法的当前迭代。

+0

谢谢你,我已经更新了我的尝试。我认为现在的问题是最小化器需要单个列表中的变量,并且我使用数组定义了我的约束。处理解决方案,但我没有任何直接的想法。 – user12800

+0

因为你的约束函数的参数是一维向量,所以在你可以使用许多索引之前,你需要重新整形它,就像你正在尝试的那样,例如:'x0.reshape(L,L,N,2)[i_x,i_y ,:,0]' –

相关问题