numpy sympy solve()结果不能在np中使用,isclose():ufunc 'isfinite'不支持

omtl5h9j  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(105)

我的代码如下。目标是,给定1)一个半径为r的圆,2)其上的一个点(x0, y0),3)通过该点的一条线slope,找出该线与圆相交的另一点。简单地说,我们假设该线与圆不相切。

from sympy import *
import numpy as np

x0, y0 = 1.0, 0.0
slope = 0.0
r = 1.0

x = Symbol('x')
y = Symbol('y')
res = solve([x*x + y*y - r*r, y-y0 - slope*(x-x0)], [x, y])
#if len(res)==1:    # the line NOT tangent with the circle
#   x1, y1 = res[0]
if np.isclose(res[0], [x0, y0]):
   x1, y1 = res[1]
else:
   x1, y1 = res[0]

字符串
我使用np.isclose()solve()结果中排除给定点(x0, y0)。然而,代码在np.isclose()行生成错误,内容如下:

TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''


我在VScode的DEBUG CONSOLE中调试代码如下。

> res
[(-1, 0), (1, 0)]
> res[0]
(-1, 0)
> np.isclose((-1, 0), [1, 0])
array([False,  True])
> np.isclose(res[0], [1, 0])
Traceback (most recent call last):
  File "/Users/ufo/miniconda3/envs/ai/lib/python3.10/site-packages/numpy/core/numeric.py", line 2358, in isclose
    xfin = isfinite(x)
TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''


显然,如果np.isclose()被给定两个元组/列表,它是工作的。但是如果它被给定一个来自sympy.solve()的结果,它会产生错误。
np.isclose()怎么办?

qni6mghb

qni6mghb1#

正如在评论中提到的,由于库中“数字”的不同实现,存在一些兼容性问题。sympy的目的是进行符号计算,并将具有特殊功能,请参阅文档。因此,需要转换。
此外,为了筛选出正确的解,你需要做一个额外的步骤,np.isclose(...).all(),因为你期望两个坐标彼此接近。

from sympy import *
import numpy as np

x0, y0 = 1.0, 0.0
slope = 0.0
r = 1.0

x = Symbol('x')
y = Symbol('y')
res = solve([x*x + y*y - r*r, y-y0 - slope*(x-x0)], [x, y])

if np.isclose(list(map(float, res[0])), [x0, y0]).all():
   x1, y1 = res[1] # carefull that are still sympy.core.numbers.Float!
else:
   x1, y1 = res[0] # carefull that are still sympy.core.numbers.Float!

print(x1, y1)
#-1.00000000000000 0.0

字符串
要获得更紧凑的解决方案,请使用 hpaulj 的建议进行铸造:

# ...

res = np.array(res, float)

if np.isclose(res[0], [x0, y0]).all():
   x1, y1 = res[1] # as numpy.float64
else:
   x1, y1 = res[0] # as numpy.float64

相关问题