Source code for qfeval_functions.functions.mvar

import torch

from .msum import msum


[docs] def mvar( x: torch.Tensor, span: int, dim: int = -1, ddof: int = 1 ) -> torch.Tensor: r"""Compute the moving (sliding window) variance of a tensor. This function calculates the variance of elements within a sliding window of size :attr:`span` along the specified dimension. The output tensor has the same shape as the input tensor. For positions where the sliding window cannot fully cover preceding elements (i.e., the first ``span - 1`` elements along the selected dimension), the result is ``nan``. The moving variance is computed using the formula: .. math:: \text{MVAR}[i] = \frac{1}{\text{span} - \text{ddof}} \left( \sum_{j=i-\text{span}+1}^{i} x[j]^2 - \frac{(\sum_{j=i-\text{span}+1}^{i} x[j])^2}{\text{span}} \right) This uses the computational formula for variance that is numerically stable and efficient for sliding window calculations. Args: x (Tensor): The input tensor containing values. span (int): The size of the sliding window. Must be positive. dim (int, optional): The dimension along which to compute the moving variance. Default is -1 (the last dimension). ddof (int, optional): Delta degrees of freedom. The divisor used in the calculation is ``span - ddof``. Use 0 for population variance. Default is 1 (sample variance). Returns: Tensor: A tensor of the same shape as the input, containing the moving variance values. The first ``span - 1`` elements along the specified dimension are ``nan``. Example: >>> # Simple moving variance with window size 3 >>> x = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0]) >>> QF.mvar(x, span=3) tensor([nan, nan, 1., 1., 1.]) >>> # 2D tensor with moving variance along columns >>> x = torch.tensor([[1.0, 2.0, 1.0, 3.0], ... [4.0, 5.0, 4.0, 6.0], ... [2.0, 3.0, 2.0, 4.0]]) >>> QF.mvar(x, span=2, dim=1) tensor([[ nan, 0.5000, 0.5000, 2.0000], [ nan, 0.5000, 0.5000, 2.0000], [ nan, 0.5000, 0.5000, 2.0000]]) >>> # Population variance (ddof=0) >>> x = torch.tensor([1.0, 3.0, 5.0, 7.0]) >>> QF.mvar(x, span=2, ddof=0) tensor([nan, 1., 1., 1.]) >>> # Sample variance (ddof=1, default) >>> QF.mvar(x, span=2, ddof=1) tensor([nan, 2., 2., 2.]) >>> # Moving variance along rows >>> x = torch.tensor([[1.0, 2.0], ... [3.0, 4.0], ... [5.0, 6.0]]) >>> QF.mvar(x, span=2, dim=0) tensor([[nan, nan], [2., 2.], [2., 2.]]) .. seealso:: :func:`mstd`: Moving standard deviation function (square root of this). :func:`msum`: Moving sum function used in the implementation. :func:`ma`: Moving average function. """ numerator = msum(x**2, span, dim) - msum(x, span, dim) ** 2 / span result: torch.Tensor = numerator / (span - ddof) return result