tBuLi / symfit

Symbolic Fitting; fitting as it should be.
http://symfit.readthedocs.org
MIT License
232 stars 17 forks source link

Fitting multidimensional datasets - symfit #371

Open opens21 opened 7 months ago

opens21 commented 7 months ago

Can you provide the full Python code to run the example on the webpage?

I get the error:

NameError: name 'Poly' is not defined
---> 24 fit_result = fit.execute()

but I am pretty sure that Poly is not the issue since it works in a different code. This is my full code:

import numpy as np
import symfit as sf
from symfit import variables, parameters, Model, Fit, Poly

# Define variables and parameters
x, y, z = variables('x, y, z')
c1, c2 = parameters('c1, c2')

# Define the model using Poly
model_dict = {z: Poly({(1, 2): c1, (4, 5): c2}, x, y)}
model = Model(model_dict)

# Print the model equation
print(model)

# Generate synthetic data
xdata = np.linspace(0, 100, 100)
ydata = np.linspace(0, 100, 100)
xdata, ydata = np.meshgrid(xdata, ydata)
zdata = 42 * xdata**4 * ydata**5 + 3.14 * xdata * ydata**2

# Create a Fit object and perform the fitting
fit = Fit(model, x=xdata, y=ydata, z=zdata)
fit_result = fit.execute()

# Display the fitted parameters
print(fit_result.params)

# Plot the data and the fitted model
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(xdata, ydata, zdata, label='Data')
ax.scatter(xdata, ydata, fit.model(x=xdata, y=ydata, **fit_result.params), label='Fit', marker='o')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.legend()
plt.show()
davide710 commented 7 months ago

Hi, I don't know if you already solved this, but you just need to add .as_expr() after Poly(), like this:

`x, y, z = variables('x, y, z') c1, c2 = parameters('c1, c2') model_dict = {z: Poly( {(1, 2): c1, (4, 5): c2}, x ,y).as_expr()}

model = Model(model_dict) model = Model({z: c2*x*4y5 + c1xy2})

x = np.linspace(0, 100, 100) y = np.linspace(0, 100, 100) xdata, ydata = np.meshgrid(x, y) zdata = 42 * xdata*4 ydata5 + 3.14 xdata ydata2

fit = Fit(model, x=xdata, y=ydata, z=zdata) fit_result = fit.execute() ` Or at least this solved it for me