Sympy with Cython 在尝试查找根时会产生奇异矩阵



我正在尝试使用 Sympy 求解一组非线性方程。这是我的代码,更改了几个数字,只有一个输入值(实际代码贯穿 170,000 行数据(:

import sympy as sp
K0 = 2.00*10**-4
x2, y2 = sp.symbols('x2, y2')
x0 = 500
y0 = 500
R1 = ((x2 - x0)**2 + (y2 - y0)**2)**0.5
R2 = K0 * R1
H2 = sp.atan(R2 * (x2 - x0)/R1)
V2 = sp.atan(R2 * (y2 - y0)/R1)
x, y = sp.symbols('x, y')
x0 = 1.0
y0 = 2.0
x = R1 * H2
y = R1 * V2
dat = sp.nsolve([x - x0, y - y0], [x2, y2], [512, 512]) # This line is the problem
print "dat = %f, %f" % (dat[0], dat[1])

纯粹使用 Python,代码运行良好并产生良好的输出 - 但它非常慢。为了加快这个过程,我使用 Cython 编译了一个具有完全相同代码的 .pyx 文件(在定义中,def test() (,但在运行时我遇到了:

  File "test.py", line 3, in <module>
    demo.test()
  File "demo.pyx", line 17, in demo.test
    dat = sp.nsolve([x - x0, y - y0], [x2, y2], [512, 512])
  File "C:...site-packagessympyutilitiesdecorator.py", line 91, in func_wrapper
    return func(*args, **kwargs)
  File "C:...site-packagessympysolverssolvers.py", line 2847, in nsolve
    x = findroot(f, x0, J=J, **kwargs)
  File "C:...site-packagesmpmathcalculusoptimization.py", line 960, in findroot
    for x, error in iterations:
  File "C:...site-packagesmpmathcalculusoptimization.py", line 658, in __iter__
    s = self.ctx.lu_solve(Jx, fxn)
  File "C:...site-packagesmpmathmatriceslinalg.py", line 227, in lu_solve
    A, p = ctx.LU_decomp(A)
  File "C:...site-packagesmpmathmatriceslinalg.py", line 137, in LU_decomp
    raise ZeroDivisionError('matrix is numerically singular')
ZeroDivisionError: matrix is numerically singular

我已经将问题缩小到x - x0y - y0部分。出于某种原因,编译的代码无法处理在根不等于 0 时查找根。nsolve 不能简单地使用 Cython 转换为 C 吗?我错过了与Cython有关的东西吗?

您可以将

sympy.lambdify与SciPy的求解器一起使用。如果这还不够快,您可以使用 symengine.Lambdify .

获得正确的函数签名,并派生雅可比函数,需要你跳过箍。如果你想使用一个库,我已经写了pyneqsys:

>>> from pyneqsys.symbolic import SymbolicSys
>>> neqsys = SymbolicSys([x2, y2], [x - x0, y - y0])
>>> neqsys.solve([512, 512])
Out[4]: 
(array([ 547.28609349,  594.58064617]),
     fjac: array([[ 0.91320338,  0.4075041 ],
       [-0.4075041 ,  0.91320338]])
     fun: array([ -1.37667655e-13,   1.52011737e-12])
 message: 'The solution converged.'
    nfev: 17
    njev: 2
     qtf: array([  1.55620322e-10,   4.63225371e-10])
       r: array([ 0.02751454,  0.023682  ,  0.03261983])
  status: 1
 success: True
       x: array([ 547.28609349,  594.58064617]))

如果这 170 000 个求解涉及逐渐更改参数pyneqsys可以利用它(通过将解作为求解之间的猜测传播(。它还可以通过设置环境变量来自动使用symengine.Lambdify SYM_BACKEND=sympysymengine

最新更新