0

私は数値的に非線形方程式のシステム解決しようとしています:Scipyのfsolveの代替品ですか?

def func(p): 
    x, f = p 
    return (math.exp(-x/O)-f, 
      L - L*((1 - math.exp(-x/O))**W) - x*math.exp(-x/O)) 

を、私は現在、次のようにそれのためscipy.fsolveを使用しています:

x, f = fsolve(func, (10, 0.2)) 

私はfsolveを使用する私の方法が正しいことを確かめてください:それは特定の範囲のパラメータに対して完全に機能します。しかし、それは完全に(例えば、O = 8、L = 1.67、W = 8)以下のエラーを持つ別で失敗した:私はそれがうまく解けるであると確信して

RuntimeWarning: The number of calls to function has reached maxfev = 600. 

- がある(少なくとも)それを行うmatlabツール。私が間違っていることは何ですか、それとも私が試すことができる他のソルバーはありますか?

ありがとうございました!

答えて

2

非線形最適化とルート検索は、残念なことに開始点の選択に敏感です。あなたのパラメータ化が冗長思わ

In [19]: def func(p): 
    x, f = p    
    return [np.exp(-x/O) -f, L - L*((1 - np.exp(-x/O))**W) - x*np.exp(-x/O)] 
    ....: 

In [20]: O, L, W = 8, 1.67, 8 

In [21]: res = fsolve(func, [1, 1.2]) 

In [22]: res 
Out[22]: array([ 2.19804447, 0.75975782]) 

In [23]: func(res) 
Out[23]: [-2.2204460492503131e-16, -4.4408920985006262e-15] 

お知らせ:は根の位置がLに依存しない、とあなたはおそらくソルバーがはるかに容易になりますexp(-x/O)の面ですべてのものをパラメータ化することができます。

編集:定義y = exp(-x/O)。最初の数式は、実際には1次元であることを示しています(たとえば、より堅牢なbrentqなどを使用できます)。しかし、あなたもfsolveを使うことができます。

In [43]: ry = fsolve(lambda y: 1 - (1-y)**W + (O/L)*y*np.log(y), 0.4) 

In [44]: ry 
Out[44]: array([ 0.75975782]) 
+0

確かに、代用はそれをうまく解決します!ありがとう! – mck

+0

私の場合、置換はうまくいきましたが、とにかくそれがあったので、より良い初期推測を見つける方法の経験則がありますか?私の問題では、実際には予想される結果を知っていたので、私はそれに近い推測値を設定しようとしました。残念ながら、それは本当に根の所見を改善しませんでした... – mck