Open JohnGoertz opened 4 years ago
Constraints should not always be of the same type as their parent model apparently.
As a workaround, could you try to create a constraint like this?
cons = Model.as_constraint(sf.Eq(a+b, 0.055), ode_model)
constraints = [cons]
I'm unable to try it myself at the moment, unfortunately.
As an aside, this is not the best way of solving this: you're better of expressing b = 0.055 - a
. But I assume this is a toy problem.
Hm, that gives a key error:
import numpy as np
import symfit as sf
tdata = np.array([10, 26, 44, 70, 120])
adata = 10e-4 * np.array([44, 34, 27, 20, 14])
a, b, t = sf.variables('a, b, t')
k = sf.Parameter('k', 0.1)
a0 = 54 * 10e-4
model_dict = {
sf.D(a, t): - k * a**2,
sf.D(b, t): k * a**2,
}
ode_model = sf.ODEModel(model_dict, initial={t: 0.0, a: a0, b: 0.0})
cons = sf.Model.as_constraint(sf.Eq(a, 0.055-b), ode_model)
constraints = [cons]
fit = sf.Fit(ode_model, t=tdata, a=adata, b=None, constraints=constraints)
fit_result = fit.execute()
print(fit_result)
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-106-04170c57c285> in <module>
12 ode_model = sf.ODEModel(model_dict, initial={t: 0.0, a: a0, b: 0.0})
13
---> 14 cons = sf.Model.as_constraint(sf.Eq(a, 0.055-b), ode_model)
15 constraints = [cons]
16
C:\ProgramData\Anaconda3\envs\sf_env\lib\site-packages\symfit\core\models.py in as_constraint(cls, constraint, model, constraint_type, **init_kwargs)
157 instance = cls.with_dependencies(constraint,
158 dependency_model=model,
--> 159 **init_kwargs)
160
161 # Check if the constraint_type is allowed, and flip the sign if needed
C:\ProgramData\Anaconda3\envs\sf_env\lib\site-packages\symfit\core\models.py in with_dependencies(cls, model_expr, dependency_model, **init_kwargs)
226 if symbol not in model_dict:
227 model_dict[symbol] = dependency_model[symbol]
--> 228 connectivity_mapping[symbol] = dependency_model.connectivity_mapping[symbol]
229 if symbol == var:
230 break
KeyError: k
(And yes, this is a toy problem. The real problem is related to this: https://github.com/tBuLi/symfit/issues/284
Adding constraints to the fitting of an ODEModel raises an error,
__init__() missing 1 required positional argument: 'initial'
Taking the simple coupled ODE model from the docs and adding an equality constraint to the variables (one that will necessarily be true anyways) gives the following output: