2012-02-18 110 views
5

我经常需要解决非线性问题,其中变量的数量超过了约束的数量(或者有时是相反的)。通常一些约束或变量以复杂的方式是冗余的。有什么办法可以解决这些问题吗?受约束的系统的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(),但我不认为这是一个最佳解决方案。

+0

这是一个真正的问题SciPy的或者是它实际上是一个数学一名身穿假胡子? – talonmies 2012-02-18 16:48:21

+0

我相信这是一个scipy的问题。我可以使用自己编写的自定义求解器来解决这些类型的问题,但希望能够使用现有的scipy求解器。此外,matlab的fsolve似乎能够解决这些问题。这似乎是一种常见的情况,很难相信scipy无法处理它(貌似)。 – 2012-02-18 17:08:23

+0

'fsolve'使用信任域方法IIRC。那么你真的想知道是否有类似的scipy函数来“解析”吗? – talonmies 2012-02-18 17:27:01

回答

3

如何从F()的返回数组的大小调整为变量的数目:

import numpy as np 
import scipy.optimize 

mat = np.random.randn(5, 7) 

def F(x): 
    y = np.dot(mat, x) 
    return np.resize(np.array([ y[0]**2 + y[1]**3 + 12, y[2] + 17]), 7) 

while True:  
    x0 = np.random.randn(7) 
    r = scipy.optimize.leastsq(F, x0) 
    err = F(r[0]) 
    norm = np.dot(err, err) 
    if norm < 1e-6: 
     break 

print err 
+0

谢谢,这似乎工作。这有没有自动完成的原因?如果没有副作用,我可能会建议自动填充作为scipy的补丁。 – 2012-02-19 15:18:16