0

I am able to plot a curve in a NumPy array using Matplotlib (see for example Save plot to numpy array).

I want to know if there is a way to find the zeros of a two-variable polynomial using only NumPy, without using Matplotlib and contour:

xmin,xmax,deltaX = -1.5,1.5,0.01 
ymin,ymax,deltaY = -1.5,1.5,0.01 
xrange = numpy.arange(xmin,xmax,deltaX) 
yrange = numpy.arange(ymin,ymax,deltaY) 
x,y = numpy.meshgrid(xrange,yrange) 
F = x**2*y**3-(x**2+y**2-1)**3

The zeros of F do not resemble the curve $x^2y^3-(x^2+y^2-1)^3$ at all.

I have tried some methods (see for example https://codegolf.stackexchange.com/questions/86879/algebraic-curve-plotter), but they do not work for singular algebraic curves like the previous one.

There is a way to plot an algebraic curve using only NumPy, without using Matplotlib and contour?

Nick ODell
  • 15,465
  • 3
  • 32
  • 66
protarius
  • 1
  • 1

1 Answers1

3

If you'd like to find where the array F equals zero, it's as simple as F == 0. Since you're using floating point, the calculation will be slightly inaccurate, so you'll need to change that to np.abs(F) <= epsilon, where epsilon is a small number which determines how close something is to zero before you consider it zero.

That gives you a binary mask of where the function equals zero. You can use np.argwhere() to convert that to indexes where the function equals zero.

Example:

epsilon = 1e-7
for x_index, y_index in np.argwhere((np.abs(F) <= epsilon)):
    x_val = x[x_index, y_index]
    y_val = y[x_index, y_index]
    F_val = F[x_index, y_index]
    print(f"Value of function at ({x_val:.2f}, {y_val:.2f}) = {F_val}")

Output:

Value of function at (0.00, -1.00) = -1.7749370367472734e-30
Value of function at (-1.00, 0.00) = 3.065340390710535e-45
Value of function at (1.00, 0.00) = -8.521646286175293e-44
Value of function at (-1.00, 1.00) = -4.884981308350689e-15
Value of function at (0.00, 1.00) = 1.774937036747201e-30
Value of function at (1.00, 1.00) = -1.554312234475219e-14

There are also methods that can find the zeros of this function analytically, rather than numerically.

Nick ODell
  • 15,465
  • 3
  • 32
  • 66
  • Regrettably, this approach provides only partial points rather than the entire curve and by increasing the tolerance you obtain a set of points that does not resemble the curve. Does Numpy offer a method to obtain the complete curve as provided by Matplotlib's contour function? – protarius Jul 18 '23 at 15:51
  • @protarius Matplotlib doesn't know what the zeros of your function actually are - it's approximating by doing a linear interpolation between the points of the function that it's actually provided. You can do something similar by running `contourpy.contour_generator(x=x, y=y, z=F)`, which is actually what matplotlib is doing internally. – Nick ODell Jul 18 '23 at 16:55
  • This is what I was searching for. I will delve into studying the algorithms. – protarius Jul 19 '23 at 10:00