from typing import Any, overload

from numpy.typing import ArrayLike
from typing_extensions import Self

class _BaseAccumulator:
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __imul__(self, other: float) -> Self: ...
    def __copy__(self) -> Self: ...
    def __deepcopy__(self, memo: Any) -> Self: ...
    def _ipython_key_completions_(self) -> tuple[str, ...]: ...

class WeightedSum(_BaseAccumulator):
    @overload
    def __init__(self) -> None: ...
    @overload
    def __init__(self, value: float) -> None: ...
    @overload
    def __init__(self, value: float, variance: float) -> None: ...
    @property
    def value(self) -> float: ...
    @property
    def variance(self) -> float: ...
    def __iadd__(self, arg0: float) -> Self: ...
    def fill(self, value: ArrayLike, variance: ArrayLike | None = None) -> Self: ...
    @staticmethod
    def _make(a: ArrayLike, b: ArrayLike) -> WeightedSum: ...
    @staticmethod
    def _array(a: ArrayLike, b: ArrayLike) -> WeightedSum: ...
    def __getitem__(self, key: str) -> float: ...
    def __setitem__(self, key: str, value: float) -> None: ...

class Sum(_BaseAccumulator):
    @overload
    def __init__(self) -> None: ...
    @overload
    def __init__(self, value: float) -> None: ...
    @property
    def value(self) -> float: ...
    def __iadd__(self, arg0: float) -> Self: ...
    def fill(self, value: ArrayLike) -> Self: ...
    @property
    def _small(self) -> float: ...
    @property
    def _large(self) -> float: ...

class WeightedMean(_BaseAccumulator):
    @overload
    def __init__(self) -> None: ...
    @overload
    def __init__(
        self,
        sum_of_weights: float,
        sum_of_weights_squared: float,
        value: float,
        variance: float,
    ) -> None: ...
    @property
    def sum_of_weights(self) -> float: ...
    @property
    def sum_of_weights_squared(self) -> float: ...
    @property
    def value(self) -> float: ...
    @property
    def _sum_of_weighted_deltas_squared(self) -> float: ...
    @property
    def variance(self) -> float: ...
    def __call__(
        self, value: ArrayLike, *, weight: ArrayLike | None = None
    ) -> Self: ...
    def fill(self, value: ArrayLike, *, weight: ArrayLike | None = None) -> Self: ...
    @staticmethod
    def _make(
        arg0: ArrayLike, arg1: ArrayLike, arg2: ArrayLike, arg3: ArrayLike
    ) -> WeightedMean: ...
    @staticmethod
    def _array(
        arg0: ArrayLike, arg1: ArrayLike, arg2: ArrayLike, arg3: ArrayLike
    ) -> WeightedMean: ...
    def __getitem__(self, key: str) -> float: ...
    def __setitem__(self, key: str, value: float) -> None: ...

class Mean(_BaseAccumulator):
    @overload
    def __init__(self) -> None: ...
    @overload
    def __init__(self, count: float, value: float, variance: float) -> None: ...
    @property
    def count(self) -> float: ...
    @property
    def value(self) -> float: ...
    @property
    def _sum_of_deltas_squared(self) -> float: ...
    @property
    def variance(self) -> float: ...
    def __call__(
        self, value: ArrayLike, *, weight: ArrayLike | None = None
    ) -> Self: ...
    def fill(self, value: ArrayLike, *, weight: ArrayLike | None = None) -> Self: ...
    @staticmethod
    def _make(arg0: ArrayLike, arg1: ArrayLike, arg2: ArrayLike) -> Mean: ...
    @staticmethod
    def _array(arg0: ArrayLike, arg1: ArrayLike, arg2: ArrayLike) -> Mean: ...
    def __getitem__(self, key: str) -> float: ...
    def __setitem__(self, key: str, value: float) -> None: ...
