Skip to content

Commit

Permalink
Merge pull request #157 from ICB-DCM/develop
Browse files Browse the repository at this point in the history
Release 0.0.6
  • Loading branch information
yannikschaelte authored Mar 13, 2019
2 parents 8763e4f + dec1629 commit 3580790
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,4 @@ venv/*
tmp/*
amici_models/*
*.txt
test/doc/example/tmp/benchmark-models/
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ install:
# run tests
script:
- python3 -m flake8 --exclude=build,doc,example,tmp,amici_models
- xvfb-run -a python3 -m pytest --cov=pypesto ./test
- travis_wait 20 python3 -m pytest --cov=pypesto ./test/test_*
- travis_wait 20 xvfb-run -a python3 -m pytest --cov=pypesto --cov-append ./test/visualize/test_*
- coverage xml
- test/run_notebook.sh doc/example/

Expand All @@ -49,4 +50,3 @@ deploy:
# cache dependencies

cache: pip

6 changes: 6 additions & 0 deletions doc/releasenotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ Release notes
..........


0.0.6 (2019-03-13)
------------------

* Several minor error fixes, in particular on tests and steady state.


0.0.5 (2019-03-11)
------------------

Expand Down
18 changes: 18 additions & 0 deletions pypesto/objective/aggregated.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import numpy as np
from copy import deepcopy

from .objective import Objective

Expand Down Expand Up @@ -90,6 +91,14 @@ def __init__(self, objectives, x_names=None, options=None):

super().__init__(**init_kwargs)

def __deepcopy__(self, memodict=None):
other = AggregatedObjective(
objectives=[deepcopy(objective) for objective in self.objectives],
x_names=deepcopy(self.x_names),
options=deepcopy(self.options),
)
return other

def aggregate_fun_sensi_orders(self, x, sensi_orders):
rvals = [
objective.fun(x, sensi_orders)
Expand Down Expand Up @@ -189,6 +198,15 @@ def aggregate_hess(self, x):
def aggregate_hessp(self, x):
return sum(objective.hessp(x) for objective in self.objectives)

def reset_steadystate_guesses(self):
"""
Propagates reset_steadystate_guesses() to child objectives if available
(currently only applies for amici_objective)
"""
for objective in self.objectives:
if hasattr(objective, 'reset_steadystate_guesses'):
objective.reset_steadystate_guesses()


def _check_boolean_value_consistent(objectives, attr):
values = set(
Expand Down
34 changes: 22 additions & 12 deletions pypesto/objective/amici_objective.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,14 @@ def __init__(self,
guess_steadystate: bool, optional (default = True)
Whether to guess steadystates based on previous steadystates and
respective derivatives.
respective derivatives. This option may lead to unexpected
results for models with conservation laws and should accordingly
be deactivated for those models.
n_threads: int, optional (default = 1)
Number of threads that are used for parallelization over
experimental conditions.
experimental conditions. If amici was not installed with openMP
support this option will have no effect.
options: pypesto.ObjectiveOptions, optional
Further options.
Expand Down Expand Up @@ -152,11 +155,15 @@ def __init__(self,
# preallocate guesses, construct a dict for every edata for which we
# need to do preequilibration
if self.guess_steadystate:
if self.amici_model.ncl() > 0:
raise ValueError('Steadystate prediciton is not supported for'
'models with conservation laws!')

if self.amici_model.getSteadyStateSensitivityMode() == \
amici.SteadyStateSensitivityMode_simulationFSA:
raise ValueError('Steadystate guesses cannot be enabled when'
' `simulationFSA` as '
'SteadyStateSensitivityMode')
'SteadyStateSensitivityMode!')
self.steadystate_guesses = {
'fval': np.inf,
'data': {
Expand Down Expand Up @@ -217,7 +224,8 @@ def __deepcopy__(self, memodict=None):
model = amici.ModelPtr(self.amici_model.clone())
solver = amici.SolverPtr(self.amici_solver.clone())
edatas = [amici.ExpData(data) for data in self.edatas]
other = AmiciObjective(model, solver, edatas)
other = AmiciObjective(model, solver, edatas,
guess_steadystate=self.guess_steadystate)
for attr in self.__dict__:
if attr not in ['amici_solver', 'amici_model', 'edatas']:
other.__dict__[attr] = copy.deepcopy(self.__dict__[attr])
Expand Down Expand Up @@ -245,10 +253,7 @@ def _call_amici(
if sensi_order > self.max_sensi_order:
raise Exception("Sensitivity order not allowed.")

# prepare result objects

rdatas = []

# prepare outputs
nllh = 0.0
snllh = np.zeros(self.dim)
s2nllh = np.zeros([self.dim, self.dim])
Expand Down Expand Up @@ -280,7 +285,7 @@ def _call_amici(
self.amici_model,
self.amici_solver,
self.edatas,
num_threads=self.n_threads
num_threads=min(self.n_threads, len(self.edatas)),
)

for data_ix, rdata in enumerate(rdatas):
Expand Down Expand Up @@ -324,7 +329,7 @@ def _call_amici(
if sres.size else opt_sres

# check whether we should update data for preequilibration guesses
if 'fval' in self.steadystate_guesses and \
if self.guess_steadystate and \
nllh <= self.steadystate_guesses['fval']:
self.steadystate_guesses['fval'] = nllh
for data_ix, rdata in enumerate(rdatas):
Expand Down Expand Up @@ -429,9 +434,12 @@ def apply_steadystate_guess(self, condition_ix, x):
if guess_data['x_ss'] is not None:
x_ss_guess = guess_data['x_ss']
if guess_data['sx_ss'] is not None:
x_ss_guess += guess_data['sx_ss'].transpose().dot(
linear_update = guess_data['sx_ss'].transpose().dot(
(x_sim - guess_data['x'])
)
# limit linear updates to max 20 % elementwise change
if (x_ss_guess/linear_update).max() < 0.2:
x_ss_guess += linear_update

self.edatas[condition_ix].x0 = tuple(x_ss_guess)

Expand Down Expand Up @@ -685,13 +693,15 @@ def sim_sres_to_opt_sres(par_opt_ids,
"""
opt_sres = np.zeros((sim_sres.shape[0], len(par_opt_ids)))

for par_sim_idx, par_opt_id in enumerate(mapping_par_opt_to_par_sim):
par_sim_idx = 0
for par_opt_id in mapping_par_opt_to_par_sim:
if not isinstance(par_opt_id, str):
# this was a numeric override for which we ignore the hessian
continue

par_opt_idx = par_opt_ids.index(par_opt_id)
opt_sres[:, par_opt_idx] += \
coefficient * sim_sres[:, par_sim_idx]
par_sim_idx += 1

return opt_sres
2 changes: 1 addition & 1 deletion pypesto/objective/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def _update_trace(self, x, sensi_orders, mode, result):
or 0 not in sensi_orders \
else res_to_chi2(res_result)
schi2 = None if not self.options.trace_record_schi2 \
or 0 not in sensi_orders or 1 not in sensi_orders \
or 1 not in sensi_orders \
else sres_to_schi2(res_result, sres_result)

# check whether to append to trace
Expand Down
2 changes: 1 addition & 1 deletion pypesto/objective/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ def sres_to_schi2(res, sres):
"""
if res is None or sres is None:
return None
return res * sres
return res.dot(sres)
2 changes: 2 additions & 0 deletions pypesto/optimize/optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ def objective_decorator(minimize):

def wrapped_minimize(self, problem, x0, index):
problem.objective.reset_history(index=index)
if hasattr(problem.objective, 'reset_steadystate_guesses'):
problem.objective.reset_steadystate_guesses()
result = minimize(self, problem, x0, index)
problem.objective.finalize_history()
result = fill_result_from_objective_history(
Expand Down
2 changes: 1 addition & 1 deletion pypesto/startpoint/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def assign_startpoints(n_starts, startpoint_method, problem, options):
n_required_points = n_starts - n_guessed_points

if n_required_points <= 0:
return x_guesses[n_starts, :]
return x_guesses[:n_starts, :]

# apply startpoint method
x_sampled = startpoint_method(
Expand Down
2 changes: 1 addition & 1 deletion pypesto/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.0.5"
__version__ = "0.0.6"
2 changes: 1 addition & 1 deletion pypesto/visualize/reference_points.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def create_references(references=None, x=None, fval=None, color=None,

# parse input (x and fval)
if (x is not None) and (fval is not None):
ref.append(ReferencePoint(x=x, fval=fval, color=color))
ref.append(ReferencePoint(x=x, fval=fval, color=color, legend=legend))

# assign colors for reference points which have no user-specified colors
return assign_colors(ref)
3 changes: 1 addition & 2 deletions test/test_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ class EngineTest(unittest.TestCase):

def test_basic(self):
for engine in [pypesto.SingleCoreEngine(),
pypesto.MultiProcessEngine(),
pypesto.MultiProcessEngine(5)]:
pypesto.MultiProcessEngine(n_procs=2)]:
self._test_basic(engine)

def _test_basic(self, engine):
Expand Down
File renamed without changes.

0 comments on commit 3580790

Please sign in to comment.