Возможно, у вас другой подход, вы уже слышали о sympy
? Это возможность делать символическую математику в Python (как с Mathematica или Maple).
После импорта
from sympy import *
Вы можете определять символы и применять их к переменным Python
x, y = symbols('x y')
Тогда вы можете определить выражения, которые описывают функции этих символов
f = (x - .5)**2 * (y - .5)**2
И поиск пересечения / касания нуля был бы нелинейной решающей задачей
result = nonlinsolve([f], [x, y])
result
{(0.499999999999937, y), (0.500000000000057, y), (x, 0.499999999999937), (x, 0.500000000000057)}
Очевидно, что у него все еще есть ошибка вычислительного покоя - но, по крайней мере, нет большой области артефакта, как в случае с plt.contour (...).
И, тем не менее, вы искали решение, которое возвращает некоторую терпимость, и результат можно интерпретировать следующим образом.
Существует даже функция, с помощью которой вы можете снова преобразовать эти результаты с помощью числовых выражений в массивы доступных для печати данных, она называется lambdify
.
Однако этот следует использовать с осторожностью , так как он использует eval
внутри, что может привести к произвольному коду, если вы не знаете источник выражения, введенного в него.
plt.figure()
numX = np.linspace(-1, 1, 1001)
numY = np.linspace(-1, 1, 1001)
for r in result:
fx = lambdify(x, r[0], "numpy")
fy = lambdify(y, r[1], "numpy")
x_val = fx(numX)
y_val = fy(numY)
if np.shape(x_val) != np.shape(y_val):
if len(np.shape(x_val)) < 1:
x_val = np.ones(len(y_val)) * x_val
else:
y_val = np.ones(len(x_val)) * y_val
plt.plot(x_val, y_val)
Это не слишком гладко, но это работает и приводит к такому результату, который является правильным для моей примерной функции:
