Source code for shamo.core.surrogate.scalar

"""Implement `SurrScalar` class."""
import json

from SALib.sample import saltelli
from SALib.analyze import sobol

from .abc import SurrABC


[docs]class SurrScalar(SurrABC): """Generate a Gaussian process from a set of scalar training data. Parameters ---------- name : str The name of the generated surrogate model. parent_path : str, byte or os.PathLike The path to the parent directory of the surrogate model. Other Parameters ---------------- params : list [tuple [str, shamo.DistABC]] A list of tuples containing the names of the parameters and the corresponding distributions as values. sol_json_path : str The path to the parametric solution the surrogate is built of. is_sobol_available : bool If ``True``, Sobol indices are already available. See Also -------- shamo.core.surrogate.SurrABC """ def __init__(self, name, parent_path, **kwargs): super().__init__(name, parent_path, **kwargs) self.update({"is_sobol_available": kwargs.get("is_sobol_available", False)}) @property def is_sobol_available(self): """Return whether the Sobol indices are already computed. Returns ------- bool Return ``True`` if the indices are already computed, ``False`` otherwise. """ return self["is_sobol_available"] @property def sobol_path(self): """Return the path to the file storing the Sobol indices. Returns ------- pathlib.Path The path to the file storing the Sobol indices. """ return self.path / f"{self.name}_sobol.json"
[docs] def get_sobol(self): """Return the precomputed Sobol indices. Returns ------- dict [str, list [str]|dict [str, float]]|None A dictionary containing the names of the parameters, the values of the first, second and total order Sobol indices and the corresponding confidence with respect to the `conf_level`. If the file does not exist, returns ``None``. """ if self.is_sobol_available: with open(self.sobol_path, "r") as f: return json.load(f) return None
[docs] def gen_sobol(self, n=1000, n_resamples=100, conf_level=0.95): """Compute Sobol sensitivity indices. Parameters ---------- n : int, optional The number of sample to predict with the Gaussian process. The default is ``1000``. n_resamples : int, optional The number of resamples. The default is ``100``. conf_level : float, optional The confidence interval level. The default is ``0.95``. Returns ------- dict [str, list [str]|dict [str, float]] A dictionary containing the names of the parameters, the values of the first, second and total order Sobol indices and the corresponding confidence with respect to the `conf_level`. """ indices = self.get_sobol() if indices is not None: return sobol params_names = [n for n, _ in self.params] prob = { "num_vars": len(self.params), "names": params_names, "dists": [d.salib_name for _, d in self.params], "bounds": [d.salib_bounds for _, d in self.params], } x = saltelli.sample(prob, n) y, _ = self.predict(x) s_i = sobol.analyze(prob, y, num_resamples=n_resamples, conf_level=conf_level) indices = { "params": params_names, "s1": {"val": s_i["S1"].tolist(), "conf": s_i["S1_conf"].tolist()}, "s2": {"val": s_i["S2"].tolist(), "conf": s_i["S2_conf"].tolist()}, "st": {"val": s_i["ST"].tolist(), "conf": s_i["ST_conf"].tolist()}, } with open(self.sobol_path, "w") as f: json.dump(indices, f, indent=4, sort_keys=True) self["is_sobol_available"] = True self.save() return indices