我正在玩Julia并且我正在使用Sympy我认为使用PyCall来调用Python。
当我运行下面的脚本时,我收到一个很长的错误。在这里发布所有内容太长了,但这是它的开始:
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)
正如你可能看到的那样,最后它会重复:看到最后的第93行,然后是第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
此例程计算某个数字的平方根的连续分数的长度。对于数字6451,它给出了错误。
所以我的问题是,这可以解决吗?
答案 0 :(得分:1)
我很高兴找到了递归限制解决方案。这在以前没有见过。这个评论是关于如何简化你的SymPy代码,因为你似乎对此感到困惑。基本上,你只需要使你的初始值符号化,然后Julia的方法应该(在大多数情况下)处理其余的。这是一个轻微的重写:
using SymPy
使用PyCall @pyimport sys sys.setrecursionlimit(10000)
“”” 获得数字i的平方根的连续分数的长度。 例如。 √7= [2;(1,1,1,4-)] “”” function 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
端
答案 1 :(得分:0)
非常感谢大家的投入。我设法通过将这些行放在文件的顶部来解决这个问题(除了我一直使用的“使用Sympy”行之外):
using SymPy
using PyCall
@pyimport sys
sys.setrecursionlimit(10000)
这在Python中设置了递归限制。不知道为什么它必须如此大才能发挥作用。
我还删除了一些类型转换等。我认为这可能有助于错误和/或速度。但事实并非如此。
此外,删除我用符号声明变量的行不会阻止代码工作。
irrationalNumber, intPart, fractionalPart = symbols(string("irrationalNumber intPart fractionalPart"))
Python相同。所以不确定它的重点是什么。
但是在朱莉娅,无论哪种方式,我必须围绕这两行包含Sym()包装:
irrationalNumber = sqrt(Sym(i))
...
intPart = Sym(floor(irrationalNumber))
通过检查这些类型,使用typeof,我可以看到它们是象征性的,而不是浮动的。没有它们,一切都会变成花车,所以我不会象征性地做它。