synthesizer.utils.precision¶
A module for controlling the default output precision.
Synthesizer computes spectra, lines, photometry and other outputs at a
user-controllable floating-point precision. Every function that produces a
floating-point output takes an out_dtype argument; when this is left
unset (None) the global default defined here is used.
The global default is float64. To halve the memory footprint of outputs across the board, set the default to float32 once at the top of a script:
import numpy as np from synthesizer import set_default_out_dtype
set_default_out_dtype(np.float32)
Individual calls can always override the global default by passing
out_dtype explicitly.
Note that out_dtype only controls output arrays. Input arrays (particle
data and grids) are used at whatever precision they are provided at and are
never cast or copied behind the scenes; see the precision documentation for
the rules on mixing input precisions.
Functions
- synthesizer.utils.precision.convert_array_dtype(array, dtype, name=None)[source]¶
Convert a numeric array-like object to a floating-point dtype.
This works for NumPy arrays, unyt_arrays (preserving their units), lists and scalars, and ensures the result has contiguous storage. If the input already has the requested dtype and contiguous storage it is returned untouched, otherwise a copy is made.
Converting to a lower precision can overflow: values beyond the range of the target dtype would silently become inf, so this raises a PrecisionOverflow error instead.
- Parameters:
array (array-like/float) – The input array-like object or scalar.
dtype (np.dtype/type) – The target dtype to convert to.
name (str, optional) – The name of the array, for the error message.
- Returns:
The converted array (or scalar).
- Return type:
array-like/float
- Raises:
PrecisionOverflow – If the values don’t fit in the target dtype.
ValueError – If the input isn’t numeric.
- synthesizer.utils.precision.get_default_out_dtype()[source]¶
Return the global default output dtype.
- Returns:
The current global default output dtype.
- Return type:
np.dtype
- synthesizer.utils.precision.get_float_dtype(dtype)[source]¶
Get the floating point dtype to compute at for an input dtype.
Inputs at a supported floating point precision (float32 or float64) keep it, anything else (e.g. integers) is computed at float64.
- Parameters:
dtype (np.dtype/type) – The dtype of the input.
- Returns:
The dtype to compute and allocate outputs with.
- Return type:
np.dtype
- synthesizer.utils.precision.max_abs(values)[source]¶
Get the largest absolute value in an array.
- Parameters:
values (np.ndarray/unyt_array) – The array.
- Returns:
The largest absolute value in the array (0 for an empty array).
- Return type:
float
- synthesizer.utils.precision.resolve_out_dtype(out_dtype)[source]¶
Resolve a function’s out_dtype argument to a concrete dtype.
- Parameters:
out_dtype (np.dtype/type/None) – The out_dtype argument as passed by the caller. None means “use the global default”.
- Returns:
The dtype outputs should be allocated with.
- Return type:
np.dtype
- synthesizer.utils.precision.scalar_like(value, ref)[source]¶
Return a scalar typed to match a reference array’s dtype.
NumPy’s weak scalar rule normally keeps a bare Python float from widening a reduced precision array, but unyt does not honour it: arithmetic between a float32 unyt_array and a Python float still produces float64. Typing the scalar against the array keeps such an expression at the precision that was asked for.
Non-floating reference dtypes are left alone, since typing a float against an integer array would truncate it.
- Parameters:
value (float/int) – The scalar to type.
ref (np.ndarray/unyt_array) – The array whose dtype the scalar should take.
- Returns:
valueas a scalar ofref’s dtype, or unchanged when that dtype is not a floating one.- Return type:
np.floating/float/int
- Raises:
AttributeError – If
refhas no dtype, i.e. is not an array.
- synthesizer.utils.precision.set_default_out_dtype(dtype)[source]¶
Set the global default output dtype.
- Parameters:
dtype (np.dtype/type) – The dtype to use for all outputs when out_dtype is not passed explicitly. Must be float32 or float64.
- synthesizer.utils.precision.verify_out_precision(skip_inf_scan_if=None)[source]¶
Verify a function’s outputs respect its out_dtype argument.
Decorates any function or method taking an
out_dtypeargument. The requested dtype is resolved as the function would (None meaning the global default), and each checked output is verified:An output at a different precision is an internal inconsistency: it is converted, with an InternalPrecisionWarning asking for it to be reported (converting raises PrecisionOverflow if the values don’t fit).
A reduced precision output containing inf has overflowed, which raises PrecisionOverflow.
Outputs can be arrays, Synthesizer output objects (Sed, LineCollection, PhotometryCollection) or dicts, lists and tuples of these.
- Parameters:
skip_inf_scan_if (callable, optional) – Called with the resolved dtype and the function’s arguments (as keywords) before the inf scan. Returning True means the outputs are provably finite at that dtype, so the scan is skipped.
- Returns:
The decorator.
- Return type:
callable
- synthesizer.utils.precision.weighted_sum_fits(dtype, max_abs_value, weights)[source]¶
Check a weighted sum of values cannot overflow a dtype.
A sum of values times non-negative weights, where each value is at most max_abs_value in magnitude, can be no larger than max_abs_value times the total weight. If that bound (with a factor of 2 margin for rounding) fits in dtype, the sum cannot overflow. A NaN or inf bound never fits.
- Parameters:
dtype (np.dtype) – The dtype the sum is computed and stored at.
max_abs_value (float) – The largest absolute value being summed.
weights (np.ndarray/unyt_array/float) – The weights (their absolute values are totalled).
- Returns:
True if the sum cannot overflow dtype.
- Return type:
bool