2016-05-28 16 views
0

我正在尋找一種有效的方法來查找間隔[a,b]上函數f的所有根。 我遇到的問題是,scipy.optimize中的所有好方法都要求f(a)和f(b)有不同的符號,或者我提供了初始猜測x0,但在運行碼。函數f是光滑的(至少是C1),並且沒有病態行爲[沒有像sin(1/x)]。然而,它需要建立一個矩陣A(x)並找到它的特徵值,因此是耗時的。預計在[a,b]上有0到10個根,其位置完全是任意的。我承擔不起他們中的任何一個(例如,我不能接受100次初始猜測x0,只希望我能抓住所有的根源)。使用Python在間隔上查找多個根

我在考慮實施類似這樣的:

  1. 找到所有極值{M_1,M_2 ..,m_k} f控制scipy.optimize [也許FMIN,但我不知道哪些方法是最有效的]:
    • 搜索從點開始梯度算法[初始猜測]
    • 搜索一個最大M_2從點M_1開始的最小M_1 + DX〔迫使梯度算法前進]
    • 搜索最小m_3 ...
  2. 如果兩個連續的極值m_i和m_(i + 1)有相反的符號,則應用間隔[m_i,m_(i + 1)]上的brentq來查找根。

  • 是否有解決這個問題的一個更好的辦法?

  • 如果不是,fmin和brentq是scipy.optimize庫中的最佳選擇,以便儘量減少對函數f的調用次數。

+3

*「查找所有極值...」*這將用一個不同的難題替換一個難題。 –

+0

只是爲了增加痛苦,任何根預期是複雜的共軛?但是對於手頭的問題,您需要深入挖掘功能,以便真正瞭解它。然後你有更多的信息來智能地攻擊問題,而不是盲目的。 –

+0

既然你的函數是C1,一種方法可能是用足夠多項式的多項式(曲線擬合)在數值上逼近你的函數,並使用多項式的根(很容易找到)作爲原函數的近似根。如有必要,這些根可以通過根發現算法進行改進。 – Stelios

回答

0

取決於您的功能,但可能使用SymPy符號解決。那會給所有的根。如果需要,它可以象徵性地找到特徵值。

查找所有極值與找到函數導數的所有根相同,所以它不會比查找所有根更簡單(如WarrenWeckesser所述)。

以數字方式查找所有根需要使用關於該功能的知識。舉一個簡單的例子,假設你知道根之間的最小間距。你可以嘗試遞歸地劃分區間並在每個區域找到根。找到最大根數後停止。但是如果間距很小,這可能需要許多功能評估(例如,在最壞的情況下,當有零根時)。您可以施加的約束越多,您可以減少越多的功能評估。

1

對此的一種「常用」方法是找到函數的近似值,對於該函數,找到根很容易,然後找到近似值的根。例如,您可以在多個點上對函數值進行採樣,將樣條線擬合到點,然後查找樣條線的根(這是一個簡單的問題)。這至少會爲根提供最初的猜測。

更棘手的部分是確定採樣點。如果您知道您的函數爲C1,則可以根據函數值在功能出現不光滑的點上更密集地進行採樣。幾年前我需要做這個,所以這裏有一個啓發式的烹飪方法來解決這個問題:https://gist.github.com/pv/acc71bafede0a84b074c7751985ecc6f爲我工作,但YMMV。