proper docstrings

This commit is contained in:
Valentin Boettcher 2019-05-13 15:43:14 +02:00
parent c13a93b3fe
commit 297b02c4ff

View file

@ -88,16 +88,11 @@ class SecondaryValue:
return kwargs return kwargs
def _calculate(self, values, derivs, error): def _calculate_gauss_propagation(self, values, derivs, error):
"""Calculates a value from the expression by substituting """Calculates a single gaussian error propagation.
variables by the values of the given keyword arguments. If an
argument is specified as a tuplpe of (value, error) the
gausssian error propagation will be computed.
:returns: value or [value, error] or [value, error], dependencies :returns: error
:rtype: dtype
:rtype: numpy data type or np array of [value, errors, ...] or
a tuple the beforementioned as first element
""" """
term = np.array([(derivs[var](**values) * err) \ term = np.array([(derivs[var](**values) * err) \
@ -108,17 +103,13 @@ class SecondaryValue:
return self._dtype(term) return self._dtype(term)
def __call__(self, *args, **kwargs): def _process_args(self, *args, **kwargs):
"""Calculates a value from the expression by substituting """Process the deconstruct given to `__call__`.
variables by the values of the given keyword arguments. If an
argument is specified as a tuplpe of (value, error) the
gausssian error propagation will be computed.
:returns: value or [value, error] or [value, error], dependencies :returns: values (input values), errors (their errors),
dep_values (the values and errors of the dependencies)
:rtype: numpy data type or np array of [value, errors, ...] or :rtype: Tuple
a tuple the beforementioned as first element and a
dictionary with the calculated dependencies as a second value
""" """
kwargs, dep_values = self._calc_deps(**kwargs) kwargs, dep_values = self._calc_deps(**kwargs)
@ -146,52 +137,104 @@ class SecondaryValue:
values = {var: (val[0] if isinstance(val, Iterable) else val) \ values = {var: (val[0] if isinstance(val, Iterable) else val) \
for var, val in kwargs.items()} for var, val in kwargs.items()}
# do the actual calulation return values, errors, dep_values
terms = []
scalar_values, vector_values = filter_out_vecotrized(values) def _calculate_central_value(self, scalar_values, vector_values):
value = 0 """Calculate the central value from the scalar and/or
value_length = length = max([len(elem) \ vectorized input values.
for elem in vector_values.values()] or [0])
:param dict scalar_values: the scalar input variables
:param dict vector_values: the vectorized input variables
:returns: the central value or an array of central values
:rtype: dtype / np.array[dtype]
"""
central_value = 0
value_length = max([len(elem) \
for elem in vector_values.values()] or [0])
if vector_values: if vector_values:
value = np.empty(value_length) central_value = np.empty(value_length)
for i in range(0, value_length): for i in range(0, value_length):
current_values = {**scalar_values, current_values = join_row(scalar_values, vector_values, i)
**{key: val[i] \
for key, val in vector_values.items()}} central_value[i] = self._parsed_lambda(**current_values)
value[i] = self._parsed_lambda(**current_values)
else: else:
value = self._parsed_lambda(**values) central_value = self._dtype(self._parsed_lambda(**scalar_values))
if not errors: return central_value
return value
def _calculate_errors(self, errors, vector_values, scalar_values):
"""Calculate the errors for the secondary value.
:param list[dict] errors: A list of dictionaries containing the errors.
:param dict vector_values: the central values
:param dict scalar_values: the scalar central values
:returns: error or list or errors
"""
# get them cached
derivs = self._get_derivatives(*list(errors[0].keys())) derivs = self._get_derivatives(*list(errors[0].keys()))
terms = []
# iterate error series (horizontal)
for error in errors: for error in errors:
scalar_errors, vector_errors = filter_out_vecotrized(error) scalar_errors, vector_errors = filter_out_vecotrized(error)
length = max([len(elem) for elem in (list(vector_values.values()) length = max([len(elem) \
+ list(vector_errors.values()))] or [0]) for elem in (list(vector_values.values())
+ list(vector_errors.values()))] or [0])
# if there are only scalar values and errors
if length == 0: if length == 0:
terms.append(self._calculate(values, terms.append(self._calculate_gauss_propagation(scalar_values,
derivs, error)) derivs, error))
# calculate error for every (value, error) pair. Errors
# are padded.
else: else:
tmp = np.empty(length, dtype=self._dtype) tmp = np.empty(length, dtype=self._dtype)
for i in range(0, length): for i in range(0, length):
current_values = {**scalar_values, current_values = join_row(scalar_values, vector_values, i)
**{key: val[i] \ current_errors = join_row(scalar_errors, vector_errors, i)
for key, val in vector_values.items()}}
current_errors = {**scalar_errors, tmp[i] = \
**{key: val[i] \ self._calculate_gauss_propagation(current_values,
for key, val in vector_errors.items()}} derivs, current_errors)
tmp[i] = self._calculate(current_values,
derivs, current_errors)
terms.append(tmp) terms.append(tmp)
return terms
def __call__(self, *args, **kwargs):
"""Calculates a value from the expression by substituting
variables by the values of the given keyword arguments. If an
argument is specified as a tuplpe of (value, error) the
gausssian error propagation will be computed.
The values and errors can be iterable, but must compatible shapes.
:returns: value or [value, error] or [value, error], dependencies
:rtype: numpy data type or np array of [value, errors, ...] or
a tuple the beforementioned as first element and a
dictionary with the calculated dependencies as a second value
"""
# process the keyword arguments
values, errors, dep_values = self._process_args(*args, **kwargs)
# calulate the central value
scalar_values, vector_values = filter_out_vecotrized(values)
central_value = self._calculate_central_value(scalar_values, vector_values)
if not errors:
return central_value
# calculate errors
result = self._calculate_errors(errors, vector_values, scalar_values)
# create the result tuple
result.insert(0, central_value)
result = tuple(result)
result = np.array([self._dtype(value)] + terms, dtype=self._dtype)
if dep_values: if dep_values:
return result, dep_values return result, dep_values
@ -248,3 +291,7 @@ def filter_out_vecotrized(dictionary):
scalar[key] = value scalar[key] = value
return scalar, vector return scalar, vector
def join_row(scalar, vector, index):
return {**scalar, **{key: val[index] \
for key, val in vector.items()}}