Source code for snowdrop.src.preprocessor.misc

"""Miscellaneous code."""
from collections import OrderedDict
import numpy


[docs] def calibration_to_vector(symbols, calibration_dict): """ Build list of dictionary values. Parameters: symbols : list Symbols. calibration_dict : dict Mapping of names and values. Returns: calibration : list Values list. """ from numpy import nan from snowdrop.src.preprocessor.eval_solver import evaluate sol = evaluate(calibration_dict) calibration = OrderedDict() for group in symbols: symb = symbols[group] max_size = 0 for s in symb: obj = sol.get(s, nan) if isinstance(obj,list): max_size = max(max_size,len(obj)) if max_size == 0: # List does not contain sub-lists values = [sol.get(s, nan) for s in symb] t = numpy.array(values, dtype=float) else: values = [] for s in symb: obj = sol.get(s, nan) if isinstance(obj,list): size = len(obj) e = obj + [obj[-1]]*(max_size-size) values.append(e) else: e = [obj]*max_size values.append(e) t = numpy.array(values, dtype=float) calibration[group] = t return calibration
[docs] def calibration_to_dict(symbols, calib): """ Build `OrderedDict` from `dict`. Parameters: symbols : list Symbols. calibration_dict : dict Mapping of names and values. Returns: calibration : OrderedDict Ordered dictionary. """ from collections import OrderedDict if not isinstance(symbols, dict): symbols = symbols.symbols d = OrderedDict() for group, values in calib.items(): if group == 'covariances': continue syms = symbols[group] for i, s in enumerate(syms): d[s] = values[i] return d
import copy
[docs] class CalibrationDict(OrderedDict): """ Dictionary that holds model calibration names and values. Parameters: OrderedDict: Ordered dictionary Usage examples: cb = CalibrationDict(symbols, calib) """ def __init__(self, symbols=None, calib=None): superclass = super() if symbols is None or calib is None: return calib = copy.deepcopy(calib) for v in calib.values(): v.setflags(write=False) superclass.__init__(calib) self.symbols = symbols self.flat = calibration_to_dict(symbols, calib) self.grouped = calib def __getitem__(self, p): """ """ if isinstance(p,tuple): return [self[e] for e in p] if p in self.symbols.keys(): return super().__getitem__(p) else: return self.flat[p]
[docs] def allocating_function(inplace_function, size_output): """ """ def new_function(*args, **kwargs): val = numpy.zeros(size_output) nargs = args + (val,) inplace_function( *nargs ) if 'diff' in kwargs: return numdiff(new_function, args) return val return new_function
[docs] def numdiff(fun, args): """Vectorized numerical differentiation.""" epsilon = 1e-8 args = list(args) v0 = fun(*args) N = v0.shape[0] l_v = len(v0) dvs = [] for i,a in enumerate(args): l_a = (a).shape[1] dv = numpy.zeros( (N, l_v, l_a) ) nargs = list(args) #.copy() for j in range(l_a): xx = args[i].copy() xx[:,j] += epsilon nargs[i] = xx dv[:,:,j] = (fun(*nargs) - v0)/epsilon dvs.append(dv) return [v0] + dvs