Imagine that you want to use ODE fitting, but your data aren't
directly linked to an ODE variable. In this case, you can use the
class :class:symfit.core.models.CallableNumericalModel.
Given are the variables x, y and z. x and y and the parameter a form an ODE model, where the derivative contains (due to the e-function) y. z is the result of a function with y and the additional parameter b.
a and b must be optimized, as shown below. The class uses the given model dictionary and the information about the variable and the parameters to fit the data.
In [12]:
from symfit import variables, Parameter, Fit, D, ODEModel, CallableNumericalModel
import numpy as np
import matplotlib.pyplot as plt
# Create data
x_data = np.linspace(0.0, 10.0, 1000)
a_expected = 0.6
b_expected = 10.0
z_data = 2 * np.exp(a_expected * x_data) + b_expected
# Initialise variables and parameters
x, y, z = variables('x, y, z')
a = Parameter('a', 0.0)
b = Parameter('b', 0.0)
# Define model
ode_model = ODEModel({D(y, x): a * y}, initial={x: 0.0, y: 1.0})
model_dict = {
z: 2 * y + b,
y: lambda x, a: ode_model(x=x, a=a).y,
}
model = CallableNumericalModel(model_dict, connectivity_mapping={z: {y, b}, y: {x, a}})
# Apply model
fit = Fit(model, x=x_data, z=z_data)
fit_result = fit.execute()
In [13]:
print('a =', fit_result.value(a))
In [14]:
print('b =', fit_result.value(b))