This post reviews how to fit an implicit function using the scipy package.
import numpy as np
import matplotlib.pyplot as plt
from scipy import optimizeSketching the function
First, lets sketch the function. Assume we have the following implicit function (here an elliptic curve):
def model(x, y, a=-2., b=+0.5):
    return x ** 3 + a * x + b - y ** 2We can draw the function using contour with a level of zero:
xlin = np.linspace(-5, 5, 200)
ylin = np.linspace(-5, 5, 200)
X, Y = np.meshgrid(xlin, ylin)
Z = model(X, Y)
fig, axe = plt.subplots()
c = axe.contour(X, Y, Z, [0])  # Zero isopleth is indeed the solution of the equationWhich renders as follow:

Generating dataset
We can use the contour drawn in previous step to extract a dataset of such an implicit function:
data = c.get_paths()[0].vertices
data += 0.1 * np.random.normal(size=data.shape)We also add a bit of noise on it, to make things crispier.
Fitting the curve
Now we have the model and the dataset, we can fit the model to the dataset by writing an appropriate loss function to minimize. We write the following factory and loss function:
def loss_factory(x, y):
    def wrapped(parameters):
        return 0.5 * np.sum(model(x, y, *parameters) ** 2)
    return wrapped
loss = loss_factory(*data.T)Now everything is setup to minimize the loss function and regress the implicit curve parameters:
sol = optimize.minimize(loss, x0=[1, 1])
#  message: Optimization terminated successfully.
#  success: True
#   status: 0
#      fun: 373.14780914303003
#        x: [-2.099e+00  4.963e-01]
#      nit: 5
#      jac: [ 0.000e+00  0.000e+00]
# hess_inv: [[ 9.784e-04 -1.055e-03]
#            [-1.055e-03  3.385e-03]]
#     nfev: 27
#     njev: 9The results of the adjustments looks like:

