Skip to content

Commit

Permalink
Make constraints a Model rather than the same as their parent class. …
Browse files Browse the repository at this point in the history
…Add initial parameters to connectivity_mapping

Fixes tBuLi#282
  • Loading branch information
pckroon committed Dec 4, 2019
1 parent 60ed844 commit da20c9d
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 4 deletions.
2 changes: 1 addition & 1 deletion symfit/core/fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ def _init_constraints(self, constraints, model):
)
else:
con_models.append(
model.__class__.as_constraint(constraint, model)
Model.as_constraint(constraint, model)
)
return con_models

Expand Down
8 changes: 6 additions & 2 deletions symfit/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -991,8 +991,11 @@ def __init__(self, model_dict, initial, *lsoda_args, **lsoda_kwargs):
self.model_params = set([])

# Only the ones that have a Parameter as initial parameter.
self.initial_params = {value for var, value in self.initial.items()
if isinstance(value, Parameter)}
self.initial_params = set()
for var, value in self.initial.items():
if isinstance(value, Parameter):
self.connectivity_mapping[var].add(value) # Make t depend on t0
self.initial_params.add(value)

for expression in expressions:
vars, params = seperate_symbols(expression)
Expand All @@ -1004,6 +1007,7 @@ def __init__(self, model_dict, initial, *lsoda_args, **lsoda_kwargs):
self.model_params = sorted(self.model_params, key=sort_func)
self.initial_params = sorted(self.initial_params, key=sort_func)


# Make Variable object corresponding to each sigma var.
self.sigmas = {var: Variable(name='sigma_{}'.format(var.name)) for var in self.dependent_vars}

Expand Down
44 changes: 43 additions & 1 deletion tests/test_ode.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import pytest
import numpy as np

from symfit import parameters, variables, ODEModel, exp, Fit, D, Model, GradientModel, Parameter
from symfit import parameters, variables, ODEModel, exp, Fit, D, Model, GradientModel, Parameter, Ge
from symfit.core.minimizers import MINPACK
from symfit.distributions import Gaussian

Expand Down Expand Up @@ -129,6 +129,48 @@ def test_initial_parameters(self):
self.assertEqual([a0, c0], ode_model.initial_params)
self.assertEqual([a0, k, l, m, p], ode_model.model_params)

print(ode_model.connectivity_mapping)
self.assertEqual({d: {l, c, m, d, a, a0},
c: {k, a, p, c, l, m, d, c0, a0},
a: {k, a, p, c, a0, d}},
ode_model.connectivity_mapping)

def test_ODE_constraints(self):
"""
Identical to test_polgar, but with a0 as free Parameter.
"""
a, b, c, d, t = variables('a, b, c, d, t')
k, p, l, m = parameters('k, p, l, m')

a0 = Parameter('a0', min=0, value=10, fixed=False)
c0 = Parameter('c0', min=0, value=0.1)
b = a0 - d + a
model_dict = {
D(d, t): l * c * b - m * d,
D(c, t): k * a * b - p * c - l * c * b + m * d,
D(a, t): - k * a * b + p * c,
}

ode_model = ODEModel(model_dict, initial={t: 0.0, a: a0, c: c0, d: 0.0})

# Generate some data
tdata = np.linspace(0, 3, 1000)
# Eval
AA, AAB, BAAB = ode_model(t=tdata, k=0.1, l=0.2, m=.3, p=0.3, a0=10, c0=0)

constraints = [Ge(a0, c0)]

fit = Fit(ode_model, t=tdata, a=AA, c=AAB, d=BAAB)
results = fit.execute()
print(results)
self.assertGreaterEqual(results.value(a0), results.value(c0))
self.assertAlmostEqual(results.value(a0), 10)
self.assertAlmostEqual(results.value(c0), 0)

self.assertEqual([a0, c0, k, l, m, p], ode_model.params)
self.assertEqual([a0, c0], ode_model.initial_params)
self.assertEqual([a0, k, l, m, p], ode_model.model_params)

def test_simple_kinetics(self):
"""
Simple kinetics data to test fitting
Expand Down

0 comments on commit da20c9d

Please sign in to comment.