我想使用scipy.optimize
库使用约束向量进行约束优化。特别是,我提供了r0
点N
的三维坐标向量 - 因此是一个大小为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
发生了什么事?
答案 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
。