Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
"""
obj_slot_values = dict((k, getattr(self, k)) for k in
# self.__slots__ would not work when
# self is an instance of a subclass:
AffineScalarFunc.__slots__)
return obj_slot_values
def __setstate__(self, data_dict):
"""
Hook for the pickle module.
"""
for (name, value) in data_dict.items():
setattr(self, name, value)
# Nicer name, for users: isinstance(ufloat(...), UFloat) is True:
UFloat = AffineScalarFunc
def get_ops_with_reflection():
"""
Returns operators with a reflection, along with their derivatives
(for float operands).
"""
# Operators with a reflection:
# We do not include divmod(). This operator could be included, by
# allowing its result (a tuple) to be differentiated, in
# derivative_value(). However, a similar result can be achieved
# by the user by calculating separately the division and the
# result.
derivatives_wrt_vars = dict((var, 0.) for var in variables)
# The chain rule is used (we already have
# derivatives_wrt_args):
for (func, f_derivative) in zip(aff_funcs, derivatives_wrt_args):
for (var, func_derivative) in func.derivatives.items():
derivatives_wrt_vars[var] += f_derivative * func_derivative
for (vname, f_derivative) in zip(aff_varkws, derivatives_wrt_args):
func = aff_kws[vname]
for (var, func_derivative) in func.derivatives.items():
derivatives_wrt_vars[var] += f_derivative * func_derivative
# The function now returns an AffineScalarFunc object:
return AffineScalarFunc(f_nominal_value, derivatives_wrt_vars)
def __getstate__(self):
"""
Hook for the pickle module.
"""
obj_slot_values = dict((k, getattr(self, k)) for k in
# self.__slots__ would not work when
# self is an instance of a subclass:
AffineScalarFunc.__slots__)
return obj_slot_values
# them to zero:
variances[variances < 0] = 0.
# Creation of new, independent variables:
# We use the fact that the eigenvectors in 'transform' are
# special: 'transform' is unitary: its inverse is its transpose:
variables = tuple(
# The variables represent "pure" uncertainties:
Variable(0, sqrt(variance), tag)
for (variance, tag) in zip(variances, tags))
# Representation of the initial correlated values:
values_funcs = tuple(
AffineScalarFunc(value, dict(zip(variables, coords)))
for (coords, value) in zip(transform, nom_values))
return values_funcs
[derivative]))
except AttributeError:
pass
else:
_modified_operators.append(op)
########################################
# Reversed versions (useful for float*AffineScalarFunc, for instance):
for (op, derivatives) in _ops_with_reflection.items():
attribute_name = '__%s__' % op
# float objects don't exactly have the same attributes between
# different versions of Python (for instance, __div__ and
# __rdiv__ were removed, in Python 3):
try:
setattr(AffineScalarFunc, attribute_name,
wrap(getattr(float, attribute_name), derivatives))
except AttributeError:
pass
else:
_modified_ops_with_reflection.append(op)
########################################
# Conversions to pure numbers are meaningless. Note that the
# behavior of float(1j) is similar.
for coercion_type in ('complex', 'int', 'long', 'float'):
def raise_error(self):
raise TypeError("can't convert an affine function (%s)"
' to %s; use x.nominal_value'
# In case AffineScalarFunc is sub-classed:
% (self.__class__, coercion_type))
aff_varkws = []
for key, val in kwargs.items():
if isinstance(val, Variable):
aff_kws[key] = to_affine_scalar(val)
aff_varkws.append(key)
except NotUpcast:
# This function does not know how to itself perform
# calculations with non-float-like arguments (as they
# might for instance be objects whose value really changes
# if some Variable objects had different values):
# Is it clear that we can't delegate the calculation?
if any(isinstance(arg, AffineScalarFunc) for arg in args):
# This situation arises for instance when calculating
# AffineScalarFunc(...)*numpy.array(...). In this
# case, we must let NumPy handle the multiplication
# (which is then performed element by element):
return NotImplemented
else:
# If none of the arguments is an AffineScalarFunc, we
# can delegate the calculation to the original
# function. This can be useful when it is called with
# only one argument (as in
# numpy.log10(numpy.ndarray(...)):
return f(*args, **kwargs)
########################################
# Nominal value of the constructed AffineScalarFunc:
args_values = [e.nominal_value for e in aff_funcs]
def __deepcopy__(self, memo):
"""
Hook for the standard copy module.
The returned AffineScalarFunc is a completely fresh copy,
which is fully independent of any variable defined so far.
New variables are specially created for the returned
AffineScalarFunc object.
"""
return AffineScalarFunc(
self._nominal_value,
dict((copy.deepcopy(var), deriv)
for (var, deriv) in self.derivatives.items()))
def __getstate__(self):
"""
Hook for the standard pickle module.
"""
obj_slot_values = dict((k, getattr(self, k)) for k in self.__slots__)
obj_slot_values.update(AffineScalarFunc.__getstate__(self))
# Conversion to a usual dictionary:
return obj_slot_values