Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ODEModel with constraints gives error #282

Open
JohnGoertz opened this issue Nov 21, 2019 · 2 comments · May be fixed by #288
Open

ODEModel with constraints gives error #282

JohnGoertz opened this issue Nov 21, 2019 · 2 comments · May be fixed by #288
Labels

Comments

@JohnGoertz
Copy link

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:

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})

constraints = [sf.Eq(a+b,0.055)]

fit = sf.Fit(ode_model, t=tdata, a=adata, b=None, constraints=constraints)
fit_result = fit.execute()
print(fit_result)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-133-bcdec22720dd> in <module>
     14 constraints = [sf.Eq(a+b,0.055)]
     15 
---> 16 fit = sf.Fit(ode_model, t=tdata, a=adata, b=None, constraints=constraints)
     17 fit_result = fit.execute()
     18 print(fit_result)

C:\ProgramData\Anaconda3\envs\sf_env\lib\site-packages\symfit\core\support.py in wrapped_func(*args, **kwargs)
    421                     else:
    422                         bound_args.arguments[param.name] = param.default
--> 423             return func(*bound_args.args, **bound_args.kwargs)
    424         return wrapped_func
    425 

C:\ProgramData\Anaconda3\envs\sf_env\lib\site-packages\symfit\core\fit.py in __init__(self, model, *ordered_data, **named_data)
    374 
    375         self.constraints = self._init_constraints(constraints=constraints,
--> 376                                                   model=self.model)
    377 
    378         # Bind as much as possible the provided arguments.

C:\ProgramData\Anaconda3\envs\sf_env\lib\site-packages\symfit\core\fit.py in _init_constraints(self, constraints, model)
    565                 else:
    566                     con_models.append(
--> 567                         model.__class__.as_constraint(constraint, model)
    568                     )
    569         return con_models

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)
    207         :return: A stand-alone :class:`~symfit.core.models.BaseModel` subclass.
    208         """
--> 209         model = cls(model_expr, **init_kwargs)  # Initiate model instance.
    210         if any(var in dependency_model for var in model.independent_vars):
    211             # This model depends on the output of the dependency_model,

TypeError: __init__() missing 1 required positional argument: 'initial'
@pckroon
Copy link
Collaborator

pckroon commented Nov 21, 2019

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.

@JohnGoertz
Copy link
Author

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: #284

@pckroon pckroon added the bug label Nov 25, 2019
pckroon added a commit to pckroon/symfit that referenced this issue Dec 4, 2019
…Add initial parameters to connectivity_mapping

Fixes tBuLi#282
pckroon added a commit to pckroon/symfit that referenced this issue Dec 4, 2019
…Add initial parameters to connectivity_mapping

Fixes tBuLi#282
@pckroon pckroon linked a pull request Dec 13, 2019 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
2 participants