我正在和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,它将给出错误。

所以我的问题是可以解决吗?

最佳答案

我很高兴找到了递归限制解决方案。这是以前从未见过的。这篇评论是关于如何简化您的SymPy代码的,因为您似乎对此感到困惑。基本上,您只需要使您的初始值具有象征意义,然后Julia的方法(在大多数情况下)应该处理其余的事情。这是一个轻微的重写:

using SymPy


使用PyCall
@pyimport sys
sys.setrecursionlimit(10000)

“”
获取数字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


结束

关于python - 从Julia调用Python时PyCall错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45808738/

10-13 09:06