2012-02-18 97 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