Issue
My code is as following. The goal is to, given 1) a circle with radius r
, 2) a point (x0, y0)
on it, and 3) a line with slope
through that point, find out the other point that the line intersects with the circle. To be simple, we assume the line is NOT tangent with the circle.
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]
I use np.isclose()
to exclude the given point (x0, y0)
from the solve()
results. However, the code generates an error at line of np.isclose()
which says:
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''
I debug the code in VScode's DEBUG CONSOLE like following.
> 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''
Obviously, if np.isclose()
was given two tuple/list, it is working. But if it was given one result from sympy.solve(), it raises errors.
What should I do with np.isclose()
?
Solution
As mentioned in the comments, there are some compatible issues due to different implementation of "numbers" in the the libraries. sympy
purposes is to do symbolic computations and will have special functionalities, see the docs. So, a casting is needed.
Further, to filter the right solution you need to do an extra step, np.isclose(...).all()
, since you are expecting that both coordinate to be close to each other.
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
For a more compact solution, use the the advise of hpaulj for the casting:
# ...
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
Answered By - cards
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.