2016-08-07 24 views
1

私はMac上でpython 2.7.10でsympy 1.0を使用しています。問題は、intではなくパラメータにfloatを使用すると、solve()は永遠に回転するように見えるということです。Sympyはint型のパラメータで動作しますが、浮動小数点数で回転します

ここに示すように、a、b、およびcをintとして指定したスクリプトです。

from sympy import * 

x = symbols('x') 
a = 500 
b = 10 
c = 333 

y = a + b * (x - c) - (a * (x/c) + x * b * log(x/c)) 

print 'y=', y 

solution = solve(y, x) 
print 'solve() gives:', solution 

この印刷:これは、以下を有する、または、Bをsmpifyingなく出力、およびCを与える

y= -10*x*log(x/333) + 2830*x/333 - 2830 
solve() gives: [333*exp(LambertW(-283*exp(-283/333)/333) + 283/333)] 

Iを数値的に解くnsolve()を用いて比較することで検証したように、これは、正しいです独立して計算されたソリューションを使用します。

さて、私はと、B、Cの定義を変更します。次のように

a = 500.0 
b = 10.0 
c = 333.0 

を次に出力は次のようになります。これにより

y= -10.0*x*log(0.003003003003003*x) + 8.4984984984985*x - 2830.0 

、(解決)一見永遠に、スピンします。この式は数値的に正しいことに注意してください。

ここでもまた、問題は次のとおりです。sympyの式で浮動小数点パラメータを使用するにはどうすればよいですか?

答えて

0

Sympyが問題を抱えている理由はわかりませんが、浮動小数点表現が正確ではないと思われます。

回避策の一つは、明示的にパラメータaを指定せずにsolveになるb、およびc、その後、PS .subs()

import sympy as sp 
x, a, b, c = sp.symbols('x, a, b, c') 
y = a + b * (x - c) - (a * (x/c) + x * b * sp.log(x/c)) 
sol = sp.solve(y, x) 

# find the second root manually by considering the k=-1 branch 
# (solve provides only the k=0 branch) 
sol_two_branches = [sol[0], sol[0].replace(sp.LambertW, lambda *args: sp.LambertW(*args,-1))] 

print([s.subs({a:500,b:10,c:333}).n() for s in sol_two_branches]) 
[333.000000000000, 242.528588686908] 

を使用します。クレジットは、枝の選択について教えてinfromingため@asmeuerに行きますオプションのLambertW

+0

私は間違って仕上げの前に投稿しました。私は言うつもりだった: 最初に、私は浮きを使用して、あなたが見ているものを参照してください。 第2に、浮動小数点数の代わりに整数を使用すると、数字解ではなく、以前私がLambertWに関わっていたソリューションが得られます。奇妙な。 第3に、solve()は単一の式を返します。しかし、2つのルーツがあります。もう一つは242.259の近くです。 solve()もこれを見つけるとは思わないでしょうか? – wchlm

+0

Sigh。 2.浮動小数点の代わりにintを使用すると、私はLambertWを含む解決策を見ています(しかしこれは私が以前に見たのと同じ解決策ではありません - おそらく、このルートのみの特殊な解決策でしょう)。 – wchlm

+0

@wchlm 2つのルーツ。残念ながら、私は '解決'(または 'solveset')両方を提供する方法を見つけることができません(私は専門家ではありません)。 – Stelios

1

私は問題は、解決策は、浮動小数点数を既定値で、ログが逆転したときには巨大な力になる。 solve(rational=False)はこれをオフにする必要がありますが、私にとってはsolveNotImplementedErrorで失敗します。私はそれのためにan issueを開いた。

+0

また、方程式が整数係数で 'solve'に与えられたとき、2つではなく1つのルートだけが返されることにも注意してください。 [Wolfram alpha](https://www.wolframalpha.com/input/?i=Solve%5B-10*x*log(x%2F333)+%2B + 2830 * x%2F333 + - + 2830%3D%3D0 、x%5D)は両方の根を提供します – Stelios

+1

はい、それは解決の既知の問題です。ランバートWを用いた解は、ランバートWの各ブランチに1つずつ、無数の複雑な解を持つ必要があります。 'LambertW(-283 * exp(-283/333)/ 333、-1)'のように、2番目の引数を設定することによって、他のブランチを得ることができます。 – asmeurer

+0

私はそれを知らなかった、ありがとう! – Stelios

関連する問題