2017-08-22 19 views
1

私はJuliaで遊んでいますが、私はPyCallを使ってPythonを呼び出すと思うSympyを使っています。JuliaからPythonを呼び出すときのPyCallエラー

以下のスクリプトを実行すると、長いエラーが発生します。ここはそれのすべてを投稿することが長すぎるのですが、ここでのスタートです:

LoadError: PyError (ccall(@pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, 

PyPtr), o, arg, C_NULL)) <type 'exceptions.RuntimeError'> 
RuntimeError('maximum recursion depth exceeded while calling a Python object',) 
    File "d:\Users\OEM\AppData\Local\JuliaPro-0.6.0.1\pkgs-0.6.0.1\v0.6\Conda\deps\usr\lib\site-packages\sympy\core\cache.py", line 93, in wrapper 
    retval = cfunc(*args, **kwargs) 
    File "d:\Users\OEM\AppData\Local\JuliaPro-0.6.0.1\pkgs-0.6.0.1\v0.6\Conda\deps\usr\lib\site-packages\sympy\core\compatibility.py", line 809, in wrapper 
    result = user_function(*args, **kwds) 
    File "d:\Users\OEM\AppData\Local\JuliaPro-0.6.0.1\pkgs-0.6.0.1\v0.6\Conda\deps\usr\lib\site-packages\sympy\core\function.py", line 427, in __new__ 
    result = super(Function, cls).__new__(cls, *args, **options) 
    File "d:\Users\OEM\AppData\Local\JuliaPro-0.6.0.1\pkgs-0.6.0.1\v0.6\Conda\deps\usr\lib\site-packages\sympy\core\cache.py", line 93, in wrapper 
    retval = cfunc(*args, **kwargs) 
    File "d:\Users\OEM\AppData\Local\JuliaPro-0.6.0.1\pkgs-0.6.0.1\v0.6\Conda\deps\usr\lib\site-packages\sympy\core\compatibility.py", line 809, in wrapper 
    result = user_function(*args, **kwds) 
    File "d:\Users\OEM\AppData\Local\JuliaPro-0.6.0.1\pkgs-0.6.0.1\v0.6\Conda\deps\usr\lib\site-packages\sympy\core\function.py", line 250, in __new__ 
    evaluated = cls.eval(*args) 
    File "d:\Users\OEM\AppData\Local\JuliaPro-0.6.0.1\pkgs-0.6.0.1\v0.6\Conda\deps\usr\lib\site-packages\sympy\functions\elementary\integers.py", line 25, in eval 
    if arg.is_imaginary or (S.ImaginaryUnit*arg).is_real: 
    File "d:\Users\OEM\AppData\Local\JuliaPro-0.6.0.1\pkgs-0.6.0.1\v0.6\Conda\deps\usr\lib\site-packages\sympy\core\decorators.py", line 91, in __sympifyit_wrapper 
    return func(a, b) 
    File "d:\Users\OEM\AppData\Local\JuliaPro-0.6.0.1\pkgs-0.6.0.1\v0.6\Conda\deps\usr\lib\site-packages\sympy\core\decorators.py", line 132, in binary_op_wrapper 
    return func(self, other) 
    File "d:\Users\OEM\AppData\Local\JuliaPro-0.6.0.1\pkgs-0.6.0.1\v0.6\Conda\deps\usr\lib\site-packages\sympy\core\expr.py", line 140, in __mul__ 
    return Mul(self, other) 
    File "d:\Users\OEM\AppData\Local\JuliaPro-0.6.0.1\pkgs-0.6.0.1\v0.6\Conda\deps\usr\lib\site-packages\sympy\core\cache.py", line 93, in wrapper 
    retval = cfunc(*args, **kwargs) 
    File "d:\Users\OEM\AppData\Local\JuliaPro-0.6.0.1\pkgs-0.6.0.1\v0.6\Conda\deps\usr\lib\site-packages\sympy\core\compatibility.py", line 809, in wrapper 
    result = user_function(*args, **kwds) 

そして、あなたが見ることができるかもしれとして、終わりに向かってそれが繰り返される:140その後、行、最後にライン93を参照してください

function oddPeriodSquareRoots() 
#= 
    Get the length of the continued fraction for square root of for the number i. 
    E.g. √7=[2;(1,1,1,4)] 
=# 


irrationalNumber, intPart, fractionalPart = symbols(string("irrationalNumber intPart fractionalPart")) 

for i in [6451] 

    # For perfect squares, the period is 0 
    irrationalNumber = BigFloat(sqrt(BigFloat(i))) 
    if irrationalNumber == floor(irrationalNumber) 
     continue 
    end 

    # Get the continued fraction using symbolic programming 
    irrationalNumber = sqrt(Sym(i)) 

    continuedFractionLength = 0 
    while true 

     intPart = Sym(BigInt(floor(irrationalNumber))) 
     if continuedFractionLength == 0 
      firstContinuedFractionTimes2 = intPart*2 
     end 

     continuedFractionLength += 1 
     if intPart == firstContinuedFractionTimes2 
      break 
     end 

     fractionalPart = irrationalNumber - intPart 
     irrationalNumber = 1/fractionalPart 

    end 

    continuedFractionLength -= 1 # We ignore the first term. 


end 


return continuedFractionLength 
end 

このルーチンは、いくつかの数の平方根のための連分数の長さを計算します、そして、ライン93 ...

は、ここに私のコードです。番号6451の場合、エラーになります。

私の質問はこれを解決できますか?

+0

heh、[projecteuler](https://projecteuler.net/problem=64)? –

+0

また、あなたのコードに再帰がありません。 –

+0

@AzatIbrakovはい、オイラーのプロジェクトです。私は少しでもそれを変更しました!いいえ、whileループがあります。だからそれは161回周りに行くと、私はエラーが発生します。この場合、継続部分は162です。それは私を疑わしいものにする。 – davo36

答えて

0

ありがとうございました。私は(私は全体の時間を持っていた「Sympyの使用」行に加えて)ファイルの先頭に次の行を置くことによってこの問題を解決するために管理:

using SymPy 

using PyCall 
@pyimport sys 
sys.setrecursionlimit(10000) 

これはPythonで再帰制限を設定します。なぜこれが機能するにはそれほど大きくなければならないのか分かりません。

私は、私のタイプ変換などのいくつかを削除しました。これはエラーや速度に役立つかもしれないと思いました。しかし、それは本当にありませんでした。

また、変数をシンボルで宣言した行を削除しても、コードが機能しなくなることはありません。

irrationalNumber, intPart, fractionalPart = symbols(string("irrationalNumber intPart fractionalPart")) 

Pythonにも同じです。それがどういう意味なのか分かりません。

しかし、ジュリアで

、私は交響曲()これらの2行のラッパーことを持っている必要がありますいずれかの方法:

irrationalNumber = sqrt(Sym(i)) 
... 
intPart = Sym(floor(irrationalNumber)) 

typeof演算を使用して、これらの型を検査することでは、私は彼らが、象徴的ではありません見ることができます浮かぶ。それらがなければ、すべてが浮動小数点に変わるので、私はそれを象徴的にやっていません。

1

再帰制限ソリューションが見つかりました。これは以前には見られなかった。このコメントは、SymPyコードを合理化する方法についてのものです。混乱しているようです。基本的には、初期値を象徴的にする必要があります。そして、Juliaのメソッドは、(ほとんどの場合すべて)残りを処理する必要があります。ここで若干書き直したものです:SYS は、sys.setrecursionlimit(10000)

"" @pyimport

using SymPy 

PyCall 使用して」 は番号iのための平方根を継続画分の長さを取得します。 例:√7= [2、(1,1,1,4)] ""」 関数oddPeriodSquareRoots(N)

i = Sym(n) 
# For perfect squares, the period is 0 
continuedFractionLength = 0 

irrationalNumber = sqrt(i) 
if is_integer(irrationalNumber) 
    return continuedFractionLength 
end 

# Get the continued fraction using symbolic programming 

while true 

    intPart = floor(irrationalNumber) 
    if continuedFractionLength == 0 
     firstContinuedFractionTimes2 = intPart*2 
    end 

     continuedFractionLength += 1 
    if intPart == firstContinuedFractionTimes2 
     break 
    end 

    fractionalPart = irrationalNumber - intPart 
    irrationalNumber = 1/fractionalPart 

end 

continuedFractionLength -= 1 # We ignore the first term. 


return continuedFractionLength 

+0

私はそれが事実であるべきだと思ったが、私はそれを働かせることができなかった。私は本当にその行が必要だと思う:i = Sym(n)。私は整数としてケプしているので、私はsqrtとフロアにSymを適用し続けなければなりませんでした。 – davo36

+0

別のことは、あなたが使う関数is_integerが本当に便利だということです。私がジュリアについて懸命に見つけていることは、これらの機能がすべてグローバルであることです。 Pythonでは変数やオブジェクトの後にドットを使用して、それを使って行うことができるすべてのメソッド、アクセスできるデータメンバーなどを見つけることができます。Juliaでは、ある関数が存在するところを読んでいる必要があります。 – davo36

+0

あなたのソリューションはうまくいきます。ニース。私のソリューションとあなたの両方は、Pythonの同じコードよりかなり遅く実行されます。おそらくJuliaとPythonの間にあるすべてのレイヤーが原因だと思います。 – davo36

関連する問題