fourierror.variable#
A scipp.Variable subclass carrying a full covariance.
- class fourierror.variable.CovVariable(*, dims, values, covariance=None, unit=Unit(1), dtype=None)#
Bases:
VariableA
scipp.Variablethat stores and propagates a full covariance matrix.Instances are
scipp.Variableobjects as far as C++ is concerned: they carry values and variances, soisinstance(x, sc.Variable)holds and every existing scipp function accepts them. In addition they carry acovariance: aVariablewith dims(*dims, *mirror(dims))and unitunit**2, whose diagonal is kept equal to the inheritedvariances.- Parameters:
dims (
Sequence[str]) – Dimension labels.values (
Any) – Array of values.covariance (
Any) – Covariance matrix, as ascipp.Variablewith dims(*dims, *mirror(dims)), an array-like of shape(*shape, *shape), orNonefor a zero covariance.unit (
Any) – Physical unit of the values; the covariance carriesunit**2.dtype (
Any) – Element type, deduced fromvaluesif omitted.
Examples
Two 50% correlated measurements:
>>> a = covariance_array( ... dims=['x'], ... values=[1.0, 2.0], ... covariance=[[0.04, 0.02], [0.02, 0.04]], ... unit='m', ... ) >>> a.variances array([0.04, 0.04])
Summing correlated elements accounts for the off-diagonal terms, which plain scipp cannot do:
>>> round(float(a.sum('x').variance), 12) 0.12
- classmethod from_variable(var, covariance=None)#
Build a
CovVariablefrom a plainVariable.With
covariance=Nonethe variable’s ownvariancesbecome the diagonal, i.e. its elements are assumed uncorrelated – exactly the assumption plain scipp makes implicitly.- Return type:
- property covariance: Variable#
The full covariance matrix, with dims
(*dims, *mirror(dims)).A copy. Returning the stored matrix would let a caller write through the accessor –
var.covariance.values[0, 0] = x– and leave thevariances == diag(covariance)invariant broken with no error. Bind it to a local name if you read it repeatedly; it isN x N.- Setter accepts:
Any
- property variances#
Array of variances of the data.
Returns a NumPy array that shares memory with the variable’s variance buffer, or None if the variable has no variances.
Examples
>>> import scipp as sc >>> var = sc.array(dims=['x'], values=[1.0, 2.0, 3.0], variances=[0.1, 0.2, 0.3]) >>> var.variances array([0.1, 0.2, 0.3])
Variables without variances return None:
>>> var_no_var = sc.array(dims=['x'], values=[1.0, 2.0, 3.0]) >>> var_no_var.variances is None True
Variances can be set or removed:
>>> var_no_var.variances = [0.01, 0.02, 0.03] >>> var_no_var.variances array([0.01, 0.02, 0.03]) >>> var_no_var.variances = None >>> var_no_var.variances is None True
- Setter accepts:
Any
- to_variable()#
Explicitly drop the correlations, returning a plain
Variable.The variances of the result are the diagonal of the covariance, so marginal uncertainties are preserved.
- Return type:
- __add__(other)#
Return
self + other, propagating the covariance.- Return type:
- __radd__(other)#
Return
self + other, propagating the covariance.- Return type:
- __sub__(other)#
Return
self - other, propagating the covariance.- Return type:
- __rsub__(other)#
Return
other - self, propagating the covariance.- Return type:
- __mul__(other)#
Return
self * other, propagating the covariance.- Return type:
- __rmul__(other)#
Return
self * other, propagating the covariance.- Return type:
- __truediv__(other)#
Return
self / other, propagating the covariance.- Return type:
- __rtruediv__(other)#
Return
other / self, propagating the covariance.- Return type:
- __neg__()#
Return
-self; the covariance is unchanged.- Return type:
- __abs__()#
Return
abs(self), flipping the sign of correlations as needed.- Return type:
- __pow__(exponent)#
Return
self ** exponent, propagating the covariance.Raises
CovarianceErrorif the exponent has an uncertainty.- Return type:
- sqrt()#
Elementwise square root, propagating the covariance.
- Return type:
- exp()#
Elementwise exponential, propagating the covariance.
- Return type:
- log()#
Elementwise natural logarithm, propagating the covariance.
- Return type:
- sin()#
Elementwise sine of an angle, propagating the covariance.
- Return type:
- cos()#
Elementwise cosine of an angle, propagating the covariance.
- Return type:
- sum(dim=None)#
Sum over
dim, accounting for correlations between the summands.- Return type:
- mean(dim=None)#
Mean over
dim(all dims ifNone), including off-diagonal terms.- Return type:
- __getitem__(key)#
Slice, selecting the same elements on both axes of the covariance.
- Return type:
- transpose(dims=None)#
Transpose to
dims, reordering both axes of the covariance.- Parameters:
dims (
Sequence[str] |None) – The new dimension order; reversed ifNone.- Return type:
- broadcast(dims=None, shape=None, sizes=None)#
Broadcast, recording the correlations the broadcast introduces.
Plain scipp raises
VariancesErrorhere (ADR 0015) because a broadcast duplicates an uncertain value, perfectly correlating the copies. With a full covariance matrix those correlations are representable, so the operation becomes well defined.- Return type:
- to(*, unit=None, dtype=None, copy=True)#
Convert unit and/or dtype, scaling the covariance quadratically.
- Parameters:
unit (
Any) – Target unit.dtype (
Any) – Target dtype.copy (
bool) – Passed toscipp.Variable.to.
- Return type:
- copy(deep=True)#
Return a copy of the variable and its covariance.
- Parameters:
deep (
bool) – Whether to copy the underlying buffers.- Return type:
- exception fourierror.variable.CovarianceError#
Bases:
RuntimeErrorRaised when an operation cannot propagate a full covariance matrix.
- fourierror.variable.concat(variables, dim)#
Concatenate along
dim, producing a block-diagonal covariance.The inputs are assumed mutually independent, so the cross-blocks are zero.
- Return type:
- fourierror.variable.covariance_array(*, dims, values, covariance=None, unit=Unit(1), dtype=None)#
Create a
CovVariable, mirroringscipp.array().- Return type:
- fourierror.variable.covariance_scalar(value, *, variance=0.0, unit=Unit(1))#
Create a 0-D
CovVariable, mirroringscipp.scalar().- Return type:
- fourierror.variable.install_dispatch()#
Route scipp’s free functions through
CovVariable.Scipp’s free functions (
sc.sum,sc.concat, …) call into C++ and return a plainVariable, dropping the covariance with no error. Inside aDataGroupthis is especially easy to miss, becausecall_funcinsrc/scipp/core/_cpp_wrapper_util.pyhands the raw C++ function todata_group_nary– so the per-item call never reaches this class, and overriding methods cannot help.This patches the listed functions in the
scippnamespace so they dispatch to the covariance-aware implementation, or refuse when there is none. Opt-in, and reversible withuninstall_dispatch().It is a stand-in for the
__scipp_dispatch__protocol proposed in the README: functions outside_AWAREand_LOSSYare untouched and still degrade silently, which is why the real fix belongs in scipp itself.- Return type:
None
- fourierror.variable.install_operand_deferral()#
Make plain scipp objects defer to a covariance-carrying right operand.
Installed automatically when
fourierror.data_arrayis imported, because without itplain_variable * cov_data_arraysilently returns a plainDataArray:CovDataArraysubclassesDataArraybut notVariable, so Python grants it no reflected-operand priority, andVariable.__mul__’sDataArrayoverload wins outright. A fix for silently wrong numbers should not be opt-in.Narrow by construction: the wrappers change behaviour only when the right operand carries a
_covariance, so plain scipp arithmetic is untouched. Idempotent.- Return type:
None
- fourierror.variable.uninstall_dispatch()#
Undo
install_dispatch().Leaves the operand deferral in place; that is a correctness fix installed at import, not part of the opt-in free-function patching. Use
uninstall_operand_deferral()to undo it too.- Return type:
None
- fourierror.variable.uninstall_operand_deferral()#
Restore scipp’s own arithmetic operators.
Only for callers who need scipp’s operator slots pristine. Afterwards
plain_variable * cov_data_arraysilently drops the covariance again.- Return type:
None