使用约束向量到scipy.optimize函数

时间:2018-06-01 23:09:47

标签: python optimization scipy

我想使用scipy.optimize库使用约束向量进行约束优化。特别是,我提供了r0N的三维坐标向量 - 因此是一个大小为N x 3的矩阵 - 作为函数的输入。坐标是笛卡尔坐标,我希望冻结所有y依赖。这意味着我需要将N x 3矩阵的第二列保持为常量y0。我如何定义这样的约束列表?

具体来说,让我们考虑一下COBYLA算法(https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_cobyla.html#scipy.optimize.fmin_cobyla)。我尝试了以下结构:

cons = []
for i in range(xyz0.shape[0]):
    def f(x):
        return x[i,1]-xyz0cyl[i,1]
    cons.append(f)
fmin_cobyla(energy, xyz0, cons, rhoend=1e-7)

并收到错误:

41 for i in range(xyz0.shape[0]):
42     def f(x):
---> 43         return x[i,1]-xyz0cyl[i,1]
 44     cons.append(f)
 45 

IndexError: too many indices for array

发生了什么事?

1 个答案:

答案 0 :(得分:0)

你的方法在很多方面都是错误的。

首先,config.cache_store = :mem_cache_store, "localhost" # assuming you run memcached on localhost 将一个序列作为约束,这样你的Nx3数组在传递给约束函数之前首先被展平,只留下一个维度的数组。因此,除了minimize约束函数内的数组到原始Nx3之外,你不能用元组索引;对于大型N来说可能相当昂贵:

reshape

其次,Python中的闭包是后期绑定;所有约束函数将在 for 循环完成后使用return x.reshape(-1, 3)[i,1] - xyz0cyl[i,1] 的最后一个值。您只能在修复第一个错误后才发现优化没有按预期进行。请参阅How do lexical closures work?了解详情。

更好的方法是在您的能量函数中实际使y轴(即第1列)静止,或者只是将Nx2矩阵传递给i