summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2021-08-19 09:50:40 +0200
committerDaniel Friesel <daniel.friesel@uos.de>2021-08-19 09:50:40 +0200
commit26d07c8eae44d0a6919fd775728cdb1bb2808298 (patch)
treeb0380add225649a5ccc16455856b8c508281a4ea /lib
parent5312f01724edad7ef380ded9a6e34971b56c7939 (diff)
ParallelParamFit -> ParamFit, optionally without parallelism
Diffstat (limited to 'lib')
-rw-r--r--lib/model.py6
-rw-r--r--lib/parameters.py4
-rw-r--r--lib/paramfit.py16
-rw-r--r--lib/runner.py2
-rw-r--r--lib/utils.py14
5 files changed, 30 insertions, 12 deletions
diff --git a/lib/model.py b/lib/model.py
index 345dea5..98a9d4f 100644
--- a/lib/model.py
+++ b/lib/model.py
@@ -5,8 +5,8 @@ import numpy as np
import os
from .automata import PTA, ModelAttribute
from .functions import StaticFunction, SubstateFunction, SplitFunction
-from .parameters import ParallelParamStats, codependent_param_dict
-from .paramfit import ParallelParamFit
+from .parameters import ParallelParamStats, ParamStats, codependent_param_dict
+from .paramfit import ParamFit
from .utils import soft_cast_int, by_name_to_by_param, regression_measures
logger = logging.getLogger(__name__)
@@ -233,7 +233,7 @@ class AnalyticModel:
if not self.fit_done:
- paramfit = ParallelParamFit()
+ paramfit = ParamFit()
for name in self.names:
for attr in self.attr_by_name[name].keys():
diff --git a/lib/parameters.py b/lib/parameters.py
index 41153a2..82b1fdc 100644
--- a/lib/parameters.py
+++ b/lib/parameters.py
@@ -319,11 +319,11 @@ class ParallelParamStats:
def compute(self):
"""
- Fit functions on previously enqueue data.
+ Fit functions on previously enqueued data.
Fitting is one in parallel with one process per core.
- Results can be accessed using the public ParallelParamFit.results object.
+ Results can be accessed using the public ParamFit.results object.
"""
with Pool() as pool:
results = pool.map(_compute_param_statistics_parallel, self.queue)
diff --git a/lib/paramfit.py b/lib/paramfit.py
index 8bc7505..5fdaf7a 100644
--- a/lib/paramfit.py
+++ b/lib/paramfit.py
@@ -17,7 +17,7 @@ from .utils import (
logger = logging.getLogger(__name__)
-class ParallelParamFit:
+class ParamFit:
"""
Fit a set of functions on parameterized measurements.
@@ -25,9 +25,10 @@ class ParallelParamFit:
function type for each parameter.
"""
- def __init__(self):
- """Create a new ParallelParamFit object."""
+ def __init__(self, parallel=True):
+ """Create a new ParamFit object."""
self.fit_queue = list()
+ self.parallel = parallel
def enqueue(self, key, param, args, kwargs=dict()):
"""
@@ -49,10 +50,13 @@ class ParallelParamFit:
Fitting is one in parallel with one process per core.
- Results can be accessed using the public ParallelParamFit.results object.
+ Results can be accessed using the public ParamFit.results object.
"""
- with Pool() as pool:
- self.results = pool.map(_try_fits_parallel, self.fit_queue)
+ if self.parallel:
+ with Pool() as pool:
+ self.results = pool.map(_try_fits_parallel, self.fit_queue)
+ else:
+ self.results = list(map(_try_fits_parallel, self.fit_queue))
def get_result(self, key):
"""
diff --git a/lib/runner.py b/lib/runner.py
index aaa3807..3290913 100644
--- a/lib/runner.py
+++ b/lib/runner.py
@@ -652,7 +652,7 @@ class Multipass:
universal_newlines=True,
)
if res.returncode != 0:
- raise RuntimeError("make info Failure")
+ raise RuntimeError(f"make info Failure. command = {command}")
return res.stdout.split("\n")
def _cached_info(self, opts=list()) -> list:
diff --git a/lib/utils.py b/lib/utils.py
index 22ac8da..2c879c0 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -190,6 +190,9 @@ def partition_by_param(data, param_values, ignore_parameters=list()):
def param_dict_to_list(param_dict, parameter_names, default=None):
+ """
+ Convert {"foo": 1, "bar": 2}, ["bar", "foo", "quux"] to [2, 1, None]
+ """
ret = list()
for parameter_name in parameter_names:
ret.append(param_dict.get(parameter_name, None))
@@ -197,6 +200,17 @@ def param_dict_to_list(param_dict, parameter_names, default=None):
def observations_to_by_name(observations: list, attributes: list):
+ """
+ Convert observation list to by_name dictionary for AnalyticModel analysis
+
+ :param observations: list of dicts, each representing one measurement. dict keys:
+ "name": name of observed state/transition/...
+ "param": {"parameter name": parameter value, ...} dict
+ :param attributes: observed attributes (i.e., actual measurements). Each measurement dict must have an
+ entry holding the data value for each attribute. It should not be None.
+
+ :returns: tuple (by_name, parameter_names) which can be passed to AnalyticModel
+ """
parameter_names = set()
by_name = dict()
for observation in observations: