欠约束系统的 SciPy 优化
我经常需要解决非线性问题,其中变量的数量超过约束的数量(有时相反)。通常,一些约束或变量以复杂的方式是多余的。有什么办法可以解决此类问题吗?
大多数 scipy 求解器似乎假设约束的数量等于变量的数量,并且雅可比行列式是非奇异的。 leastsq
有时会起作用,但当约束少于变量数量时它甚至不会尝试。我意识到我可以在 linalg.norm(F)
上运行 fmin
,但这比任何使用雅可比行列式的方法效率要低得多。
这是一个问题的例子,它演示了我正在谈论的内容。显然它有一个解决方案,但是 leastsq
给出了错误。当然,这个例子很容易手工解决,我放在这里只是为了演示这个问题。
import numpy as np
import scipy.optimize
mat = np.random.randn(5, 7)
def F(x):
y = np.dot(mat, x)
return np.array([ y[0]**2 + y[1]**3 + 12, y[2] + 17 ])
x0 = np.random.randn(7)
scipy.optimize.leastsq(F, x0)
我收到的错误消息是:
Traceback (most recent call last):
File "question.py", line 13, in <module>
scipy.optimize.leastsq(F, x0)
File "/home/dstahlke/apps/scipy/lib64/python2.7/site-packages/scipy/optimize/minpack.py", line 278, in leastsq
raise TypeError('Improper input: N=%s must not exceed M=%s' % (n,m))
TypeError: Improper input: N=7 must not exceed M=2
我已经在网上搜索答案,甚至在 SciPy 邮件列表上询问,但没有得到回应。目前,我破解了 SciPy 源代码,以便 newton_krylov 求解器使用 pinv() ,但我认为这不是最佳解决方案。
I often have to solve nonlinear problems in which the number of variables exceeds the number of constraints (or sometimes the other way around). Usually some of the constraints or variables are redundant in a complicated way. Is there any way to solve such problems?
Most of the scipy solvers seem to assume that the number of constraints equals the number of variables, and that the Jacobian is nonsingular. leastsq
works sometimes but it doesn't even try when the constraints are fewer than the number of variables. I realize that I could just run fmin
on linalg.norm(F)
, but this is much less efficient than any method which makes use of the Jacobian.
Here is an example of a problem which demonstrates what I am talking about. It obviously has a solution, but leastsq
gives an error. Of course, this example is easy to solve by hand, I just put it here to demonstrate the issue.
import numpy as np
import scipy.optimize
mat = np.random.randn(5, 7)
def F(x):
y = np.dot(mat, x)
return np.array([ y[0]**2 + y[1]**3 + 12, y[2] + 17 ])
x0 = np.random.randn(7)
scipy.optimize.leastsq(F, x0)
The error message I get is:
Traceback (most recent call last):
File "question.py", line 13, in <module>
scipy.optimize.leastsq(F, x0)
File "/home/dstahlke/apps/scipy/lib64/python2.7/site-packages/scipy/optimize/minpack.py", line 278, in leastsq
raise TypeError('Improper input: N=%s must not exceed M=%s' % (n,m))
TypeError: Improper input: N=7 must not exceed M=2
I have scoured the net for an answer and have even asked on the SciPy mailing list, and got no response. For now I hacked the SciPy source so that the newton_krylov
solver uses pinv()
, but I don't think this is an optimal solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如何将返回数组的大小从 F() 调整为变量的数量:
How about resize the return array from F() to the number of variables: