diff --git a/.mypyignore b/.mypyignore index 2d44636f..34f3d08f 100644 --- a/.mypyignore +++ b/.mypyignore @@ -28,6 +28,9 @@ scipy\.(_lib|integrate|stats)\.((_|\w)+\.)+__replace__ # `NamedTuple` on `pytho # stubtest doesn't understand `if sys.version_info >= _: ...` blocks scipy\.sparse\.(\w+)\.warn +# annoying and useless __new__ +scipy\.stats\.(_new_distributions\.)?Normal\.__new__ + # mypy fails recognize type-check-only ufunc subtypes as ufuncs # https://github.com/KotlinIsland/basedmypy/issues/816 scipy\.special\._basic\.digamma diff --git a/.mypyignore-todo b/.mypyignore-todo deleted file mode 100644 index 67f1b9ed..00000000 --- a/.mypyignore-todo +++ /dev/null @@ -1,5 +0,0 @@ -scipy\.stats\.__all__ -scipy\.stats\.(Uniform|Normal|Mixture) -scipy\.stats\.(abs|truncate|exp|log) -scipy\.stats\.make_distribution -scipy\.stats\.order_statistic diff --git a/pyproject.toml b/pyproject.toml index c1ca53a4..0235c423 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -139,7 +139,6 @@ uv run --frozen --no-editable --isolated --refresh-package=scipy-stubs stubtest --mypy-config-file=pyproject.toml --allowlist=.mypyignore - --allowlist=.mypyignore-todo --ignore-unused-allowlist $modules """ diff --git a/scipy-stubs/stats/__init__.pyi b/scipy-stubs/stats/__init__.pyi index 4cbfc76e..811505d5 100644 --- a/scipy-stubs/stats/__init__.pyi +++ b/scipy-stubs/stats/__init__.pyi @@ -5,6 +5,7 @@ from ._bws_test import bws_test from ._censored_data import CensoredData from ._correlation import chatterjeexi from ._covariance import Covariance +from ._distribution_infrastructure import Mixture, abs, exp, log, make_distribution, order_statistic, truncate from ._entropy import differential_entropy, entropy from ._fit import fit, goodness_of_fit from ._hypotests import ( @@ -72,6 +73,7 @@ from ._multivariate import ( vonmises_fisher, wishart, ) +from ._new_distributions import Normal, Uniform from ._page_trend_test import page_trend_test from ._resampling import ( BootstrapMethod, @@ -302,9 +304,13 @@ __all__ = [ "Covariance", "DegenerateDataWarning", "FitError", + "Mixture", "MonteCarloMethod", "NearConstantInputWarning", + "Normal", "PermutationMethod", + "Uniform", + "abs", "alexandergovern", "alpha", "anderson", @@ -371,6 +377,7 @@ __all__ = [ "entropy", "epps_singleton_2samp", "erlang", + "exp", "expectile", "expon", "exponnorm", @@ -450,6 +457,7 @@ __all__ = [ "levy_stable", "linregress", "lmoment", + "log", "loggamma", "logistic", "loglaplace", @@ -458,6 +466,7 @@ __all__ = [ "logser", "loguniform", "lomax", + "make_distribution", "mannwhitneyu", "matrix_normal", "maxwell", @@ -493,6 +502,7 @@ __all__ = [ "normaltest", "norminvgauss", "obrientransform", + "order_statistic", "ortho_group", "page_trend_test", "pareto", @@ -560,6 +570,7 @@ __all__ = [ "trim1", "trim_mean", "trimboth", + "truncate", "truncexpon", "truncnorm", "truncpareto", @@ -598,13 +609,4 @@ __all__ = [ "zipfian", "zmap", "zscore", - # "Mixture", - # "Normal", - # "Uniform", - # "abs", - # "exp", - # "log", - # "make_distribution", - # "order_statistic", - # "truncate", ] diff --git a/scipy-stubs/stats/_distribution_infrastructure.pyi b/scipy-stubs/stats/_distribution_infrastructure.pyi new file mode 100644 index 00000000..8d305e5e --- /dev/null +++ b/scipy-stubs/stats/_distribution_infrastructure.pyi @@ -0,0 +1,638 @@ +# mypy: disable-error-code="explicit-override" +# pyright: reportUnannotatedClassAttribute=false + +import abc +from collections.abc import Callable, Mapping, Sequence, Set as AbstractSet +from typing import Any, ClassVar, Final, Generic, Literal as L, Protocol, TypeAlias, TypedDict, overload, type_check_only +from typing_extensions import LiteralString, Never, Self, TypeIs, TypeVar, Unpack, override + +import numpy as np +import optype as op +import optype.numpy as onp +import optype.typing as opt +from scipy._typing import AnyShape, ToRNG +from ._distn_infrastructure import rv_continuous +from ._probability_distribution import _BaseDistribution + +__all__ = ["Mixture", "abs", "exp", "log", "make_distribution", "order_statistic", "truncate"] + +### + +_FloatT = TypeVar("_FloatT", bound=_Float, default=_Float) +_FloatT_co = TypeVar("_FloatT_co", bound=_Float, default=_Float, covariant=True) + +_RealT = TypeVar("_RealT", bound=_Float | _Int, default=_Float | _Int) +_RealT_co = TypeVar("_RealT_co", bound=_Float | _Int, default=_Float | _Int, covariant=True) + +_ShapeT1 = TypeVar("_ShapeT1", bound=onp.AtLeast1D, default=onp.AtLeast1D) +_ShapeT = TypeVar("_ShapeT", bound=_ND, default=_ND) +_ShapeT_co = TypeVar("_ShapeT_co", bound=_ND, default=_ND, covariant=True) + +_DistT0 = TypeVar("_DistT0", bound=_CDist0) +_DistT1 = TypeVar("_DistT1", bound=_CDist[_1D]) +_DistT_1 = TypeVar("_DistT_1", bound=_CDist[onp.AtMost1D]) +_DistT2 = TypeVar("_DistT2", bound=_CDist[_2D]) +_DistT_2 = TypeVar("_DistT_2", bound=_CDist[onp.AtMost2D]) +_DistT3 = TypeVar("_DistT3", bound=_CDist[_3D]) +_DistT_3 = TypeVar("_DistT_3", bound=_CDist[onp.AtMost3D]) +_DistT = TypeVar("_DistT", bound=ContinuousDistribution) +_DistT_co = TypeVar("_DistT_co", bound=ContinuousDistribution, default=ContinuousDistribution, covariant=True) + +_AxesT = TypeVar("_AxesT", bound=_Axes, default=Any) + +### + +_Int: TypeAlias = np.integer[Any] +_Float: TypeAlias = np.floating[Any] +_OutFloat: TypeAlias = np.float64 | np.longdouble + +_NT = TypeVar("_NT", default=int) +_0D: TypeAlias = tuple[()] # noqa: PYI042 +_1D: TypeAlias = tuple[_NT] # noqa: PYI042 +_2D: TypeAlias = tuple[_NT, _NT] # noqa: PYI042 +_3D: TypeAlias = tuple[_NT, _NT, _NT] # noqa: PYI042 +_ND: TypeAlias = tuple[_NT, ...] + +_To1D: TypeAlias = op.CanIndex | _1D[op.CanIndex] +_To2D: TypeAlias = _2D[op.CanIndex] +_To3D: TypeAlias = _3D[op.CanIndex] + +_ToFloatMax1D: TypeAlias = onp.ToFloatStrict1D | onp.ToFloat +_ToFloatMax2D: TypeAlias = onp.ToFloatStrict2D | _ToFloatMax1D +_ToFloatMax3D: TypeAlias = onp.ToFloatStrict3D | _ToFloatMax2D +_ToFloatMaxND: TypeAlias = onp.ToFloatND | onp.ToFloat + +_ToJustIntMax1D: TypeAlias = onp.ToJustIntStrict1D | onp.ToJustInt +_ToJustIntMax2D: TypeAlias = onp.ToJustIntStrict2D | _ToJustIntMax1D +_ToJustIntMax3D: TypeAlias = onp.ToJustIntStrict3D | _ToJustIntMax2D +_ToJustIntMaxND: TypeAlias = onp.ToJustIntND | onp.ToJustInt + +_JustFloat: TypeAlias = opt.Just[float] | _Float +_Null: TypeAlias = opt.Just[object] +_Axes: TypeAlias = object # placeholder for `matplotlib.axes.Axes` + +_DomainRegion: TypeAlias = L["domain", "typical"] +_DomainDrawType: TypeAlias = L["in", "out", "on", "nan"] +_ValidationPolicy: TypeAlias = L["skip_all"] | None +_CachePolicy: TypeAlias = L["no_cache"] | None +_PlotQuantity: TypeAlias = L["x", "pdf", "cdf", "ccdf", "icdf", "iccdf", "logpdf", "logcdf", "logccdf", "ilogcdf", "ilogccdf"] +_SMomentMethod: TypeAlias = L["formula", "general", "transform", "normalize", "cache"] + +_ParamValues: TypeAlias = Mapping[str, _ToFloatMaxND] +_ToDomain: TypeAlias = tuple[onp.ToFloat | str, onp.ToFloat | str] +_ToTol: TypeAlias = opt.Just[float] | _Null +_DrawProportions: TypeAlias = tuple[onp.ToFloat, onp.ToFloat, onp.ToFloat, onp.ToFloat] +_Elementwise: TypeAlias = Callable[[onp.ArrayND[np.float64]], onp.ArrayND[_FloatT]] + +_CDist: TypeAlias = ContinuousDistribution[_Float, _ShapeT] +_CDist0: TypeAlias = ContinuousDistribution[_FloatT, _0D] +_TransDist: TypeAlias = TransformedDistribution[_DistT, _FloatT, _ShapeT] +_LinDist: TypeAlias = ShiftedScaledDistribution[_DistT, _FloatT, _ShapeT] +_FoldDist: TypeAlias = FoldedDistribution[_DistT, _FloatT, _ShapeT] +_TruncDist: TypeAlias = TruncatedDistribution[_DistT, _ShapeT] + +@type_check_only +class _ParamField(Protocol[_FloatT_co, _ShapeT_co]): + # This actually works (even on mypy)! + @overload + def __get__(self: _ParamField[_FloatT, _0D], obj: object, tp: type | None = None, /) -> _FloatT: ... + @overload + def __get__(self: _ParamField[_FloatT, _ShapeT1], obj: object, tp: type | None = None, /) -> onp.Array[_ShapeT1, _FloatT]: ... + +@type_check_only +class _DistOpts(TypedDict, total=False): + tol: _ToTol + validation_policy: _ValidationPolicy + cache_policy: _CachePolicy + +### + +_null: Final[_Null] = ... + +def _isnull(x: object) -> TypeIs[_Null | None]: ... + +# TODO(jorenham): Generic dtype and shape +class _Domain(abc.ABC): + # NOTE: This is a `ClassVar[dict[str, float]]` that's overridden as instance attribute in `_SimpleDomain`. + # https://github.com/scipy/scipy/pull/22139 + symbols: Mapping[float, LiteralString] = ... + + @abc.abstractmethod + @override + def __str__(self, /) -> str: ... + @abc.abstractmethod + def contains(self, /, x: onp.ArrayND[Any]) -> onp.ArrayND[np.bool_]: ... + @abc.abstractmethod + def draw(self, /, n: int) -> onp.ArrayND[_FloatT]: ... + @abc.abstractmethod + def get_numerical_endpoints(self, /, x: _ParamValues) -> tuple[onp.ArrayND[_OutFloat], onp.ArrayND[_OutFloat]]: ... + +# TODO(jorenham): Generic dtype +class _SimpleDomain(_Domain, metaclass=abc.ABCMeta): + def __init__(self, /, endpoints: _ToDomain = ..., inclusive: tuple[bool, bool] = (False, False)) -> None: ... + @override + def __str__(self, /) -> str: ... # noqa: PYI029 + @override + def get_numerical_endpoints(self, /, parameter_values: _ParamValues) -> _2D[onp.ArrayND[_OutFloat]]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] + @override + def contains( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] + self, + /, + item: onp.ArrayND[_Int | _Float], + parameter_values: _ParamValues | None = None, + ) -> onp.ArrayND[np.bool_]: ... + + # + def define_parameters(self, /, *parameters: _Parameter) -> None: ... + +class _RealDomain(_SimpleDomain): + @override + def draw( # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] + self, + /, + n: int, + type_: _DomainDrawType, + min: onp.ArrayND[_Float | _Int], + max: onp.ArrayND[_Float | _Int], + squeezed_base_shape: _ND, + rng: ToRNG = None, + ) -> onp.ArrayND[np.float64]: ... + +_ValidateOut0D: TypeAlias = tuple[_RealT, np.dtype[_RealT], onp.Array0D[np.bool_]] +_ValidateOutND: TypeAlias = tuple[onp.ArrayND[_RealT, _ShapeT1], np.dtype[_RealT], onp.ArrayND[np.bool_, _ShapeT1]] + +# +class _Parameter(abc.ABC, Generic[_RealT_co]): + def __init__( + self, + /, + name: str, + *, + domain: _Domain, + symbol: str | None = None, + typical: _Domain | _ToDomain | None = None, + ) -> None: ... + # + @overload + @abc.abstractmethod + def validate(self, /, arr: onp.ToFloat) -> _ValidateOut0D[_RealT_co]: ... + @overload + @abc.abstractmethod + def validate(self, /, arr: onp.ToFloatND) -> _ValidateOutND[_RealT_co]: ... + # + def draw( + self, + /, + size: _ND | None = None, + *, + rng: ToRNG = None, + region: _DomainRegion = "domain", + proportions: _DrawProportions | None = None, + parameter_values: _ParamValues | None = None, + ) -> onp.ArrayND[_RealT_co]: ... + +class _RealParameter(_Parameter[_FloatT_co], Generic[_FloatT_co]): + @overload # type: ignore[override] + def validate(self, /, arr: onp.ToFloat, parameter_values: _ParamValues) -> _ValidateOut0D[_FloatT_co]: ... + @overload + def validate(self, /, arr: onp.ToFloatND, parameter_values: _ParamValues) -> _ValidateOutND[_FloatT_co]: ... # pyright: ignore[reportIncompatibleMethodOverride] + +class _Parameterization: + parameters: Final[Mapping[str, _Parameter]] + + def __init__(self, /, *parameters: _Parameter) -> None: ... + def __len__(self, /) -> int: ... + def copy(self, /) -> Self: ... + def matches(self, /, parameters: AbstractSet[str]) -> bool: ... + def validation(self, /, parameter_values: Mapping[str, _Parameter]) -> tuple[onp.ArrayND[np.bool_], np.dtype[_Float]]: ... + def draw( + self, + /, + sizes: _ND | Sequence[_ND] | None = None, + rng: ToRNG = None, + proportions: _DrawProportions | None = None, + region: _DomainRegion = "domain", + ) -> dict[str, onp.ArrayND[_Float]]: ... + +### + +class ContinuousDistribution(_BaseDistribution[_FloatT_co, _ShapeT_co], Generic[_FloatT_co, _ShapeT_co]): + __array_priority__: ClassVar[float] = 1 + _parameterizations: ClassVar[Sequence[_Parameterization]] + + _not_implemented: Final[str] + _original_parameters: dict[str, _FloatT_co | onp.ArrayND[_FloatT_co, _ShapeT_co]] + + _variable: _Parameter + + @property + def tol(self, /) -> float | np.float64 | _Null | None: ... + @tol.setter + def tol(self, tol: float | np.float64 | _Null | None, /) -> None: ... + # + @property + def validation_policy(self, /) -> _ValidationPolicy: ... + @validation_policy.setter + def validation_policy(self, validation_policy: _ValidationPolicy, /) -> None: ... + # + @property + def cache_policy(self, /) -> _CachePolicy: ... + @cache_policy.setter + def cache_policy(self, cache_policy: _CachePolicy, /) -> None: ... + # + def __init__( + self, + /, + *, + tol: _ToTol = ..., + validation_policy: _ValidationPolicy = None, + cache_policy: _CachePolicy = None, + ) -> None: ... + def __neg__(self, /) -> _LinDist[Self, _FloatT_co, _ShapeT_co]: ... + def __abs__(self, /) -> _FoldDist[Self, _FloatT_co, _ShapeT_co]: ... + + # + @overload + def __add__(self, x: float | _Int | np.bool_, /) -> _LinDist[Self, np.float64 | _FloatT_co, _ShapeT_co]: ... + @overload + def __add__(self, x: _FloatT, /) -> _LinDist[Self, _FloatT | _FloatT_co, _ShapeT_co]: ... + @overload + def __add__(self, x: onp.ToFloat, /) -> _LinDist[Self, _Float, _ShapeT_co]: ... + @overload + def __add__(self: _DistT0, x: onp.CanArrayND[_FloatT, _ShapeT], /) -> _LinDist[_DistT0, _FloatT | _FloatT_co, _ShapeT]: ... + @overload + def __add__(self: _DistT_1, x: onp.ToFloatStrict1D, /) -> _LinDist[_DistT_1, _Float, _1D]: ... + @overload + def __add__(self: _DistT_2, x: onp.ToFloatStrict2D, /) -> _LinDist[_DistT_2, _Float, _2D]: ... + @overload + def __add__(self: _DistT_3, x: onp.ToFloatStrict3D, /) -> _LinDist[_DistT_3, _Float, _3D]: ... + @overload + def __add__(self, x: onp.ToFloatND, /) -> _LinDist[Self]: ... + __radd__ = __add__ + + # + @overload + def __sub__(self, lshift: float | _Int | np.bool_, /) -> _LinDist[Self, np.float64 | _FloatT_co, _ShapeT_co]: ... + @overload + def __sub__(self, lshift: _FloatT, /) -> _LinDist[Self, _FloatT | _FloatT_co, _ShapeT_co]: ... + @overload + def __sub__(self, lshift: onp.ToFloat, /) -> _LinDist[Self, _Float, _ShapeT_co]: ... + @overload + def __sub__( + self: _DistT0, lshift: onp.CanArrayND[_FloatT, _ShapeT], / + ) -> _LinDist[_DistT0, _FloatT | _FloatT_co, _ShapeT]: ... + @overload + def __sub__(self: _DistT_1, lshift: onp.ToFloatStrict1D, /) -> _LinDist[_DistT_1, _Float, _1D]: ... + @overload + def __sub__(self: _DistT_2, lshift: onp.ToFloatStrict2D, /) -> _LinDist[_DistT_2, _Float, _2D]: ... + @overload + def __sub__(self: _DistT_3, lshift: onp.ToFloatStrict3D, /) -> _LinDist[_DistT_3, _Float, _3D]: ... + @overload + def __sub__(self, lshift: onp.ToFloatND, /) -> _LinDist[Self]: ... + __rsub__ = __sub__ + + # + @overload + def __mul__(self, scale: float | _Int | np.bool_, /) -> _LinDist[Self, np.float64 | _FloatT_co, _ShapeT_co]: ... + @overload + def __mul__(self, scale: _FloatT, /) -> _LinDist[Self, _FloatT | _FloatT_co, _ShapeT_co]: ... + @overload + def __mul__(self, scale: onp.ToFloat, /) -> _LinDist[Self, _Float, _ShapeT_co]: ... + @overload + def __mul__( + self: _DistT0, scale: onp.CanArrayND[_FloatT, _ShapeT], / + ) -> _LinDist[_DistT0, _FloatT | _FloatT_co, _ShapeT]: ... + @overload + def __mul__(self: _DistT_1, scale: onp.ToFloatStrict1D, /) -> _LinDist[_DistT_1, _Float, _1D]: ... + @overload + def __mul__(self: _DistT_2, scale: onp.ToFloatStrict2D, /) -> _LinDist[_DistT_2, _Float, _2D]: ... + @overload + def __mul__(self: _DistT_3, scale: onp.ToFloatStrict3D, /) -> _LinDist[_DistT_3, _Float, _3D]: ... + @overload + def __mul__(self, scale: onp.ToFloatND, /) -> _LinDist[Self]: ... + __rmul__ = __mul__ + + # + @overload + def __truediv__(self, iscale: float | _Int | np.bool_, /) -> _LinDist[Self, np.float64 | _FloatT_co, _ShapeT_co]: ... + @overload + def __truediv__(self, iscale: _FloatT, /) -> _LinDist[Self, _FloatT | _FloatT_co, _ShapeT_co]: ... + @overload + def __truediv__(self, iscale: onp.ToFloat, /) -> _LinDist[Self, _Float, _ShapeT_co]: ... + @overload + def __truediv__( + self: _DistT0, iscale: onp.CanArrayND[_FloatT, _ShapeT], / + ) -> _LinDist[_DistT0, _FloatT | _FloatT_co, _ShapeT]: ... + @overload + def __truediv__(self: _DistT_1, iscale: onp.ToFloatStrict1D, /) -> _LinDist[_DistT_1, _Float, _1D]: ... + @overload + def __truediv__(self: _DistT_2, iscale: onp.ToFloatStrict2D, /) -> _LinDist[_DistT_2, _Float, _2D]: ... + @overload + def __truediv__(self: _DistT_3, iscale: onp.ToFloatStrict3D, /) -> _LinDist[_DistT_3, _Float, _3D]: ... + @overload + def __truediv__(self, iscale: onp.ToFloatND, /) -> _LinDist[Self]: ... + __rtruediv__ = __truediv__ + + # + def __pow__(self, exp: onp.ToInt, /) -> MonotonicTransformedDistribution[Self, _ShapeT_co]: ... + __rpow__ = __pow__ + + # + def reset_cache(self, /) -> None: ... + def plot( + self, + x: _PlotQuantity = "x", + y: _PlotQuantity = "pdf", + *, + t: tuple[_PlotQuantity, _JustFloat, _JustFloat] = ("cdf", 0.0005, 0.9995), + ax: _AxesT | None = None, + ) -> _AxesT: ... + + # + # NOTE: This will be removed in 1.15.0rc2, see https://github.com/scipy/scipy/pull/22149 + @overload + def llf(self, sample: _ToFloatMaxND, /, *, axis: None) -> _OutFloat: ... + @overload + def llf(self: _CDist0, sample: _ToFloatMax1D, /, *, axis: AnyShape | None = -1) -> _OutFloat: ... + @overload + def llf(self: _CDist[_ShapeT1], sample: _ToFloatMax1D, /, *, axis: AnyShape = -1) -> onp.ArrayND[_OutFloat, _ShapeT1]: ... + @overload + def llf(self: _CDist0, sample: onp.ToFloatStrict2D, /, *, axis: _To1D = -1) -> onp.Array1D[_OutFloat]: ... + @overload + def llf(self: _CDist0, sample: onp.ToFloatStrict2D, /, *, axis: _To2D) -> _OutFloat: ... + @overload + def llf(self: _CDist0, sample: onp.ToFloatStrict3D, /, *, axis: _To1D = -1) -> onp.Array2D[_OutFloat]: ... + @overload + def llf(self: _CDist0, sample: onp.ToFloatStrict3D, /, *, axis: _To2D) -> onp.Array1D[_OutFloat]: ... + @overload + def llf(self: _CDist0, sample: onp.ToFloatStrict3D, /, *, axis: _To3D) -> _OutFloat: ... + @overload + def llf( + self: _CDist[_ShapeT1], sample: _ToFloatMaxND, /, *, axis: AnyShape = -1 + ) -> onp.Array[_ShapeT1, _OutFloat] | onp.ArrayND[_OutFloat]: ... # the first union type is needed on numpy <2.1 + @overload + def llf(self, sample: _ToFloatMaxND, /, *, axis: AnyShape | None = -1) -> _OutFloat | onp.ArrayND[_OutFloat]: ... + +# 7 years of asking and >400 upvotes, but still no higher-kinded typing support: https://github.com/python/typing/issues/548 +class TransformedDistribution(ContinuousDistribution[_FloatT_co, _ShapeT_co], Generic[_DistT_co, _FloatT_co, _ShapeT_co]): + _dist: _DistT_co # readonly + + def __init__( + self: _TransDist[ContinuousDistribution[_FloatT, _ShapeT], _FloatT, _ShapeT], # nice trick, eh? + X: _DistT_co, + /, + *args: Never, + **kwargs: Unpack[_DistOpts], + ) -> None: ... + +class ShiftedScaledDistribution(_TransDist[_DistT_co, _FloatT_co, _ShapeT_co], Generic[_DistT_co, _FloatT_co, _ShapeT_co]): + _loc_domain: ClassVar[_RealDomain] = ... + _loc_param: ClassVar[_RealParameter] = ... + _scale_domain: ClassVar[_RealDomain] = ... + _scale_param: ClassVar[_RealParameter] = ... + + loc: _ParamField[_FloatT_co, _ShapeT_co] + scale: _ParamField[_FloatT_co, _ShapeT_co] + + # TODO(jorenham): override `__[r]{add,sub,mul,truediv}__` so that it returns a `Self` (but maybe with different shape) + +class FoldedDistribution(_TransDist[_DistT_co, _FloatT_co, _ShapeT_co], Generic[_DistT_co, _FloatT_co, _ShapeT_co]): + @overload + def __init__(self: _FoldDist[_DistT0, _Float, _0D], X: _DistT0, /, *args: Never, **kwargs: Unpack[_DistOpts]) -> None: ... + @overload + def __init__(self: _FoldDist[_DistT1, _Float, _1D], X: _DistT1, /, *args: Never, **kwargs: Unpack[_DistOpts]) -> None: ... + @overload + def __init__(self: _FoldDist[_DistT2, _Float, _2D], X: _DistT2, /, *args: Never, **kwargs: Unpack[_DistOpts]) -> None: ... + @overload + def __init__(self: _FoldDist[_DistT3, _Float, _3D], X: _DistT3, /, *args: Never, **kwargs: Unpack[_DistOpts]) -> None: ... + @overload + def __init__(self: _FoldDist[_DistT, _Float, _ND], X: _DistT, /, *args: Never, **kwargs: Unpack[_DistOpts]) -> None: ... + +class TruncatedDistribution(_TransDist[_DistT_co, _Float, _ShapeT_co], Generic[_DistT_co, _ShapeT_co]): + _lb_domain: ClassVar[_RealDomain] = ... + _lb_param: ClassVar[_RealParameter] = ... + _ub_domain: ClassVar[_RealDomain] = ... + _ub_param: ClassVar[_RealParameter] = ... + + lb: _ParamField[_Float, _ShapeT_co] + ub: _ParamField[_Float, _ShapeT_co] + + @overload + def __init__( + self: _TruncDist[_DistT0, _0D], + X: _DistT0, + /, + *args: Never, + lb: onp.ToFloat = ..., + ub: onp.ToFloat = ..., + **kwargs: Unpack[_DistOpts], + ) -> None: ... + @overload + def __init__( + self: _TruncDist[_DistT1, _1D], + X: _DistT1, + /, + *args: Never, + lb: _ToFloatMax1D = ..., + ub: _ToFloatMax1D = ..., + **kwargs: Unpack[_DistOpts], + ) -> None: ... + @overload + def __init__( + self: _TruncDist[_DistT2, _2D], + X: _DistT2, + /, + *args: Never, + lb: _ToFloatMax2D = ..., + ub: _ToFloatMax2D = ..., + **kwargs: Unpack[_DistOpts], + ) -> None: ... + @overload + def __init__( + self: _TruncDist[_DistT3, _3D], + X: _DistT3, + /, + *args: Never, + lb: _ToFloatMax3D = ..., + ub: _ToFloatMax3D = ..., + **kwargs: Unpack[_DistOpts], + ) -> None: ... + @overload + def __init__( + self: _TruncDist[_DistT, _ND], + X: _DistT, + /, + *args: Never, + lb: _ToFloatMaxND = ..., + ub: _ToFloatMaxND = ..., + **kwargs: Unpack[_DistOpts], + ) -> None: ... + +# always float64 or longdouble +class OrderStatisticDistribution(_TransDist[_DistT_co, _OutFloat, _ShapeT_co], Generic[_DistT_co, _ShapeT_co]): + # these should actually be integral; but the `_IntegerDomain` isn't finished yet + _r_domain: ClassVar[_RealDomain] = ... + _r_param: ClassVar[_RealParameter] = ... + _n_domain: ClassVar[_RealDomain] = ... + _n_param: ClassVar[_RealParameter] = ... + + @overload + def __init__( + self: OrderStatisticDistribution[_DistT0, _0D], + dist: _DistT0, + /, + *args: Never, + r: onp.ToJustInt, + n: onp.ToJustInt, + **kwargs: Unpack[_DistOpts], + ) -> None: ... + @overload + def __init__( + self: OrderStatisticDistribution[_DistT1, _1D], + dist: _DistT1, + /, + *args: Never, + r: _ToJustIntMax1D, + n: _ToJustIntMax1D, + **kwargs: Unpack[_DistOpts], + ) -> None: ... + @overload + def __init__( + self: OrderStatisticDistribution[_DistT2, _2D], + dist: _DistT2, + /, + *args: Never, + r: _ToJustIntMax2D, + n: _ToJustIntMax2D, + **kwargs: Unpack[_DistOpts], + ) -> None: ... + @overload + def __init__( + self: OrderStatisticDistribution[_DistT3, _3D], + dist: _DistT3, + /, + *args: Never, + r: _ToJustIntMax3D, + n: _ToJustIntMax3D, + **kwargs: Unpack[_DistOpts], + ) -> None: ... + @overload + def __init__( + self: OrderStatisticDistribution[_DistT, _ND], + X: _DistT, + /, + *args: Never, + r: _ToJustIntMaxND, + n: _ToJustIntMaxND, + **kwargs: Unpack[_DistOpts], + ) -> None: ... + +# without HKT there's no reasonable way tot determine the floating scalar type +class MonotonicTransformedDistribution(_TransDist[_DistT_co, _Float, _ShapeT_co], Generic[_DistT_co, _ShapeT_co]): + _g: Final[_Elementwise] + _h: Final[_Elementwise] + _dh: Final[_Elementwise] + _logdh: Final[_Elementwise] + _increasing: Final[bool] + _repr_pattern: Final[str] + + def __init__( + self: MonotonicTransformedDistribution[_CDist[_ShapeT], _ShapeT], + X: _DistT_co, + /, + *args: Never, + g: _Elementwise, + h: _Elementwise, + dh: _Elementwise, + logdh: _Elementwise | None = None, + increasing: bool = True, + repr_pattern: str | None = None, + **kwargs: Unpack[_DistOpts], + ) -> None: ... + +class Mixture(_BaseDistribution[_FloatT_co, _0D], Generic[_FloatT_co]): + _shape: _0D + _dtype: np.dtype[_FloatT_co] + _components: Sequence[_CDist0[_FloatT_co]] + _weights: onp.Array1D[_FloatT_co] + validation_policy: None + + @property + def components(self, /) -> list[_CDist0[_FloatT_co]]: ... + @property + def weights(self, /) -> onp.Array1D[_FloatT_co]: ... + # + def __init__(self, /, components: Sequence[_CDist0[_FloatT_co]], *, weights: onp.ToFloat1D | None = None) -> None: ... + # + @override + def kurtosis(self, /, *, method: _SMomentMethod | None = None) -> _OutFloat: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride] + +### + +# still waiting on the intersection type PEP... + +@overload +def truncate(X: _DistT0, lb: onp.ToFloat = ..., ub: onp.ToFloat = ...) -> _TruncDist[_DistT0, _0D]: ... +@overload +def truncate(X: _DistT1, lb: _ToFloatMax1D = ..., ub: _ToFloatMax1D = ...) -> _TruncDist[_DistT1, _1D]: ... +@overload +def truncate(X: _DistT2, lb: _ToFloatMax2D = ..., ub: _ToFloatMax2D = ...) -> _TruncDist[_DistT2, _2D]: ... +@overload +def truncate(X: _DistT3, lb: _ToFloatMax3D = ..., ub: _ToFloatMax3D = ...) -> _TruncDist[_DistT3, _3D]: ... +@overload +def truncate(X: _DistT, lb: _ToFloatMaxND = ..., ub: _ToFloatMaxND = ...) -> _TruncDist[_DistT, _ND]: ... + +# +@overload +def order_statistic(X: _DistT0, /, *, r: onp.ToJustInt, n: onp.ToJustInt) -> OrderStatisticDistribution[_DistT0, _0D]: ... +@overload +def order_statistic(X: _DistT1, /, *, r: _ToJustIntMax1D, n: _ToJustIntMax1D) -> OrderStatisticDistribution[_DistT1, _1D]: ... +@overload +def order_statistic(X: _DistT2, /, *, r: _ToJustIntMax2D, n: _ToJustIntMax2D) -> OrderStatisticDistribution[_DistT2, _2D]: ... +@overload +def order_statistic(X: _DistT3, /, *, r: _ToJustIntMax3D, n: _ToJustIntMax3D) -> OrderStatisticDistribution[_DistT3, _3D]: ... +@overload +def order_statistic(X: _DistT, /, *, r: _ToJustIntMaxND, n: _ToJustIntMaxND) -> OrderStatisticDistribution[_DistT, _ND]: ... + +# +@overload +def abs(X: _DistT0, /) -> _FoldDist[_DistT0, _Float, _0D]: ... +@overload +def abs(X: _DistT1, /) -> _FoldDist[_DistT1, _Float, _1D]: ... +@overload +def abs(X: _DistT2, /) -> _FoldDist[_DistT2, _Float, _2D]: ... +@overload +def abs(X: _DistT3, /) -> _FoldDist[_DistT3, _Float, _3D]: ... +@overload +def abs(X: _DistT, /) -> _FoldDist[_DistT, _Float, _ND]: ... + +# +@overload +def exp(X: _DistT0, /) -> MonotonicTransformedDistribution[_DistT0, _0D]: ... +@overload +def exp(X: _DistT1, /) -> MonotonicTransformedDistribution[_DistT1, _1D]: ... +@overload +def exp(X: _DistT2, /) -> MonotonicTransformedDistribution[_DistT2, _2D]: ... +@overload +def exp(X: _DistT3, /) -> MonotonicTransformedDistribution[_DistT3, _3D]: ... +@overload +def exp(X: _DistT, /) -> MonotonicTransformedDistribution[_DistT, _ND]: ... + +# +@overload +def log(X: _DistT0, /) -> MonotonicTransformedDistribution[_DistT0, _0D]: ... +@overload +def log(X: _DistT1, /) -> MonotonicTransformedDistribution[_DistT1, _1D]: ... +@overload +def log(X: _DistT2, /) -> MonotonicTransformedDistribution[_DistT2, _2D]: ... +@overload +def log(X: _DistT3, /) -> MonotonicTransformedDistribution[_DistT3, _3D]: ... +@overload +def log(X: _DistT, /) -> MonotonicTransformedDistribution[_DistT, _ND]: ... + +# NOTE: These currently don't support >0-d parameters, and it looks like they always return float64, regardless of dtype +@type_check_only +class CustomDistribution(ContinuousDistribution[np.float64, _0D]): + _dtype: np.dtype[_Float] # ignored + +def make_distribution(dist: rv_continuous) -> type[CustomDistribution]: ... diff --git a/scipy-stubs/stats/_new_distributions.pyi b/scipy-stubs/stats/_new_distributions.pyi new file mode 100644 index 00000000..e2750571 --- /dev/null +++ b/scipy-stubs/stats/_new_distributions.pyi @@ -0,0 +1,164 @@ +from typing import Any, ClassVar, Generic, TypeAlias, overload +from typing_extensions import Never, TypeVar, Unpack + +import numpy as np +import optype.numpy as onp +from ._distribution_infrastructure import ContinuousDistribution, _DistOpts, _RealDomain, _RealParameter + +__all__ = ["Normal", "Uniform"] + +### + +_Float: TypeAlias = np.floating[Any] + +_NT = TypeVar("_NT", default=int) +_0D: TypeAlias = tuple[()] # noqa: PYI042 +_1D: TypeAlias = tuple[_NT] # noqa: PYI042 +_2D: TypeAlias = tuple[_NT, _NT] # noqa: PYI042 +_3D: TypeAlias = tuple[_NT, _NT, _NT] # noqa: PYI042 +_ND: TypeAlias = tuple[_NT, ...] + +_ToFloat_1D: TypeAlias = onp.ToFloatStrict1D | onp.ToFloat +_ToFloat_2D: TypeAlias = onp.ToFloatStrict2D | _ToFloat_1D +_ToFloat_3D: TypeAlias = onp.ToFloatStrict3D | _ToFloat_2D +_ToFloat_ND: TypeAlias = onp.ToFloatND | onp.ToFloat + +_FloatT = TypeVar("_FloatT", bound=_Float, default=_Float) +_FloatT_co = TypeVar("_FloatT_co", bound=_Float, default=_Float, covariant=True) + +_ShapeT = TypeVar("_ShapeT", bound=_ND, default=_ND) +_ShapeT_co = TypeVar("_ShapeT_co", bound=_ND, default=_ND, covariant=True) + +### + +class Normal(ContinuousDistribution[_FloatT_co, _ShapeT_co], Generic[_ShapeT_co, _FloatT_co]): + _mu_domain: ClassVar[_RealDomain] = ... + _mu_param: ClassVar[_RealParameter] = ... + _sigma_domain: ClassVar[_RealDomain] = ... + _sigma_param: ClassVar[_RealParameter] = ... + _x_support: ClassVar[_RealDomain] = ... + _x_param: ClassVar[_RealParameter] = ... + _normalization: ClassVar[np.float64] = ... + _log_normalization: ClassVar[np.float64] = ... + + @property + def mu(self, /) -> _FloatT_co | onp.Array[_ShapeT_co, _FloatT_co]: ... + @property + def sigma(self, /) -> _FloatT_co | onp.Array[_ShapeT_co, _FloatT_co]: ... + + # TODO(jorenham): __new__ + + # + @overload # default + def __init__(self: Normal[tuple[()], np.float64], /, **kw: Unpack[_DistOpts]) -> None: ... + @overload # mu: N-d + def __init__( + self: Normal[_ShapeT, _FloatT], + /, + *, + mu: onp.CanArrayND[_FloatT, _ShapeT], + sigma: onp.CanArrayND[_FloatT | np.integer[Any] | np.bool_, _ShapeT] | onp.ToInt, + **kw: Unpack[_DistOpts], + ) -> None: ... + @overload # sigma: N-d + def __init__( + self: Normal[_ShapeT, _FloatT], + /, + *, + mu: onp.CanArrayND[_FloatT | np.integer[Any] | np.bool_, _ShapeT] | onp.ToInt, + sigma: onp.CanArrayND[_FloatT, _ShapeT], + **kw: Unpack[_DistOpts], + ) -> None: ... + @overload # mu, sigma: 0-d float + def __init__(self: Normal[_0D, np.float64], /, *, mu: float, sigma: float | onp.ToInt, **kw: Unpack[_DistOpts]) -> None: ... + @overload # mu, sigma: 0-d float + def __init__(self: Normal[_0D, np.float64], /, *, mu: float | onp.ToInt, sigma: float, **kw: Unpack[_DistOpts]) -> None: ... + @overload # mu: 0-d , sigma: 0-d + def __init__(self: Normal[_0D, _FloatT], /, *, mu: _FloatT, sigma: _FloatT | onp.ToInt, **kw: Unpack[_DistOpts]) -> None: ... + @overload # a, sigma: 0-d + def __init__(self: Normal[_0D, _FloatT], /, *, mu: _FloatT | onp.ToInt, sigma: _FloatT, **kw: Unpack[_DistOpts]) -> None: ... + @overload # a, sigma: 0-d + def __init__(self: Normal[_0D], /, *, mu: onp.ToFloat = 0.0, sigma: onp.ToFloat = 1.0, **kw: Unpack[_DistOpts]) -> None: ... + @overload # mu: 1-d + def __init__(self: Normal[_1D], /, *, mu: onp.ToFloatStrict1D, sigma: _ToFloat_1D = 1.0, **kw: Unpack[_DistOpts]) -> None: ... + @overload # sigma: 1-d + def __init__(self: Normal[_1D], /, *, mu: _ToFloat_1D = 0.0, sigma: onp.ToFloatStrict1D, **kw: Unpack[_DistOpts]) -> None: ... + @overload # mu: 2-d + def __init__(self: Normal[_2D], /, *, mu: onp.ToFloatStrict2D, sigma: _ToFloat_2D = 1.0, **kw: Unpack[_DistOpts]) -> None: ... + @overload # sigma: 2-d + def __init__(self: Normal[_2D], /, *, mu: _ToFloat_2D = 0.0, sigma: onp.ToFloatStrict2D, **kw: Unpack[_DistOpts]) -> None: ... + @overload # mu: 3-d + def __init__(self: Normal[_2D], /, *, mu: onp.ToFloatStrict3D, sigma: _ToFloat_3D = 1.0, **kw: Unpack[_DistOpts]) -> None: ... + @overload # sigma: 3-d + def __init__(self: Normal[_3D], /, *, mu: _ToFloat_3D = 0.0, sigma: onp.ToFloatStrict3D, **kw: Unpack[_DistOpts]) -> None: ... + @overload # mu: >=1-d + def __init__( + self: Normal[onp.AtLeast1D], + /, + *, + mu: onp.ToFloatND, + sigma: _ToFloat_ND = 1.0, + **kw: Unpack[_DistOpts], + ) -> None: ... + @overload # sigma: >=1-d + def __init__( + self: Normal[onp.AtLeast1D], + /, + *, + mu: _ToFloat_ND = 0.0, + sigma: onp.ToFloatND, + **kw: Unpack[_DistOpts], + ) -> None: ... + +class StandardNormal(Normal[tuple[()], np.float64]): # undocumented + mu: ClassVar[np.float64] = ... # pyright: ignore[reportIncompatibleMethodOverride] + sigma: ClassVar[np.float64] = ... # pyright: ignore[reportIncompatibleMethodOverride] + + def __init__(self, /, **kw: Unpack[_DistOpts]) -> None: ... + +class Uniform(ContinuousDistribution[_FloatT_co, _ShapeT_co], Generic[_ShapeT_co, _FloatT_co]): + _a_domain: ClassVar[_RealDomain] = ... + _a_param: ClassVar[_RealParameter] = ... + _b_domain: ClassVar[_RealDomain] = ... + _b_param: ClassVar[_RealParameter] = ... + _x_support: ClassVar[_RealDomain] = ... + _x_param: ClassVar[_RealParameter] = ... + + @property + def a(self, /) -> _FloatT_co | onp.Array[_ShapeT_co, _FloatT_co]: ... + @property + def b(self, /) -> _FloatT_co | onp.Array[_ShapeT_co, _FloatT_co]: ... + @property + def ab(self, /) -> _FloatT_co | onp.Array[_ShapeT_co, _FloatT_co]: ... # b - a + + # NOTE: `a` and `b` are both required; the defaults are just there to confuse you or something... + @overload # a: 0-d float, b: 0-d + def __init__(self: Uniform[_0D, np.float64], /, *, a: float, b: float | onp.ToInt, **kw: Unpack[_DistOpts]) -> None: ... + @overload # a, b: 0-d float + def __init__(self: Uniform[_0D, np.float64], /, *, a: float | onp.ToInt, b: float, **kw: Unpack[_DistOpts]) -> None: ... + @overload # a: 0-d , b: 0-d + def __init__(self: Uniform[_0D, _FloatT], /, *, a: _FloatT, b: _FloatT | onp.ToInt, **kw: Unpack[_DistOpts]) -> None: ... + @overload # a, b: 0-d + def __init__(self: Uniform[_0D, _FloatT], /, *, a: _FloatT | onp.ToInt, b: _FloatT, **kw: Unpack[_DistOpts]) -> None: ... + @overload # a, b: 0-d + def __init__(self: Uniform[_0D], /, *, a: onp.ToFloat, b: onp.ToFloat, **kw: Unpack[_DistOpts]) -> None: ... + @overload # a: 1-d + def __init__(self: Uniform[_1D], /, *, a: onp.ToFloatStrict1D, b: _ToFloat_1D, **kw: Unpack[_DistOpts]) -> None: ... + @overload # b: 1-d + def __init__(self: Uniform[_1D], /, *, a: _ToFloat_1D, b: onp.ToFloatStrict1D, **kw: Unpack[_DistOpts]) -> None: ... + @overload # a: 2-d + def __init__(self: Uniform[_2D], /, *, a: onp.ToFloatStrict2D, b: _ToFloat_2D, **kw: Unpack[_DistOpts]) -> None: ... + @overload # b: 2-d + def __init__(self: Uniform[_2D], /, *, a: _ToFloat_2D, b: onp.ToFloatStrict2D, **kw: Unpack[_DistOpts]) -> None: ... + @overload # a: 3-d + def __init__(self: Uniform[_2D], /, *, a: onp.ToFloatStrict3D, b: _ToFloat_3D, **kw: Unpack[_DistOpts]) -> None: ... + @overload # b: 3-d + def __init__(self: Uniform[_3D], /, *, a: _ToFloat_3D, b: onp.ToFloatStrict3D, **kw: Unpack[_DistOpts]) -> None: ... + @overload # a: >=1-d + def __init__(self: Uniform[onp.AtLeast1D], /, *, a: onp.ToFloatND, b: _ToFloat_ND, **kw: Unpack[_DistOpts]) -> None: ... + @overload # b: >=1-d + def __init__(self: Uniform[onp.AtLeast1D], /, *, a: _ToFloat_ND, b: onp.ToFloatND, **kw: Unpack[_DistOpts]) -> None: ... + @overload # a: None -> ValueError + def __init__(self, /, *, a: None = None, b: _ToFloat_ND | None = None, **kw: Unpack[_DistOpts]) -> Never: ... + @overload # b: None -> ValueError + def __init__(self, /, *, a: _ToFloat_ND | None = None, b: None = None, **kw: Unpack[_DistOpts]) -> Never: ... diff --git a/scipy-stubs/stats/_probability_distribution.pyi b/scipy-stubs/stats/_probability_distribution.pyi new file mode 100644 index 00000000..611cc21f --- /dev/null +++ b/scipy-stubs/stats/_probability_distribution.pyi @@ -0,0 +1,780 @@ +# mypy: disable-error-code="explicit-override" + +import abc +from collections.abc import Iterable +from typing import Any, Generic, Literal as L, TypeAlias, overload, type_check_only +from typing_extensions import TypeVar + +import numpy as np +import optype as op +import optype.numpy as onp +from scipy._typing import ToRNG +from ._qmc import QMCEngine + +_T = TypeVar("_T") +_XT = TypeVar("_XT", bound=np.number[Any], default=np.number[Any]) +_XT_co = TypeVar("_XT_co", bound=np.number[Any], default=np.float64, covariant=True) +_ShapeT = TypeVar("_ShapeT", bound=onp.AtLeast1D, default=onp.AtLeast1D) +_ShapeT0 = TypeVar("_ShapeT0", bound=tuple[int, ...], default=tuple[int, ...]) +_ShapeT0_co = TypeVar("_ShapeT0_co", bound=tuple[int, ...], default=tuple[int, ...], covariant=True) + +_Tuple2: TypeAlias = tuple[_T, _T] +_ToQRNG: TypeAlias = QMCEngine | ToRNG + +_MedianMethod: TypeAlias = L["formula", "icdf"] | None +_ModeMethod: TypeAlias = L["formula", "optimization"] | None +_SampleMethod: TypeAlias = L["formula", "inverse_transform"] | None +_RMomentMethod: TypeAlias = L["formula", "transform", "quadrature", "cache"] | None +_CMomentMethod: TypeAlias = L["formula", "transform", "quadrature", "cache", "normalize"] | None +_SMomentMethod: TypeAlias = L["formula", "transform", "general", "cache", "normalize"] | None +_KurtosisConvention: TypeAlias = L["non-excess", "excess"] +_EntropyMethod: TypeAlias = L["formula", "logexp", "quadrature"] | None + +_PDFMethod: TypeAlias = L["formula", "logexp"] | None +_CDFMethod: TypeAlias = L["formula", "logexp", "complement", "quadrature", "subtraction"] | None +_CCDFMethod: TypeAlias = L["formula", "logexp", "complement", "quadrature", "addition"] | None +_ICDFMethod: TypeAlias = L["formula", "complement", "inversion"] | None + +_Float: TypeAlias = np.float64 | np.longdouble +_Float1D: TypeAlias = onp.Array1D[_Float] +_Float2D: TypeAlias = onp.Array2D[_Float] +_Float3D: TypeAlias = onp.Array3D[_Float] +_FloatND: TypeAlias = onp.ArrayND[_Float, _ShapeT] + +_Complex: TypeAlias = np.complex128 | np.clongdouble +_ComplexND: TypeAlias = onp.ArrayND[_Complex, _ShapeT] + +_ToFloatND: TypeAlias = onp.CanArrayND[np.floating[Any] | np.integer[Any] | np.bool_, _ShapeT] +_ToFloat0ND: TypeAlias = onp.ToFloat | onp.ToFloatND +_ToFloatMax1D: TypeAlias = onp.ToFloatStrict1D | onp.ToFloat +_ToFloatMax2D: TypeAlias = onp.ToFloatStrict2D | _ToFloatMax1D +_ToFloatMax3D: TypeAlias = onp.ToFloatStrict3D | _ToFloatMax2D +_ToFloatMaxND: TypeAlias = _ToFloatND[_ShapeT] | _ToFloatMax1D + +### + +class _ProbabilityDistribution(Generic[_XT_co], metaclass=abc.ABCMeta): + @abc.abstractmethod + def support(self, /) -> _Tuple2[_XT_co | onp.ArrayND[_XT_co]]: ... + @abc.abstractmethod + def median(self, /, *, method: _MedianMethod) -> _XT_co | onp.ArrayND[_XT_co]: ... + @abc.abstractmethod + def mode(self, /, *, method: _ModeMethod) -> _XT_co | onp.ArrayND[_XT_co]: ... + @abc.abstractmethod + def sample( + self, /, shape: int | tuple[int, ...], *, method: _SampleMethod, rng: _ToQRNG + ) -> _XT_co | onp.Array[Any, _XT_co]: ... # `Any` shape is needed on `numpy<2.1` + + # + @abc.abstractmethod + def mean(self, /, *, method: _RMomentMethod) -> _XT_co | onp.ArrayND[_XT_co]: ... + @abc.abstractmethod + def variance(self, /, *, method: _CMomentMethod) -> _XT_co | onp.ArrayND[_XT_co]: ... + @abc.abstractmethod + def standard_deviation(self, /, *, method: _CMomentMethod) -> _XT_co | onp.ArrayND[_XT_co]: ... + @abc.abstractmethod + def skewness(self, /, *, method: _SMomentMethod) -> _XT_co | onp.ArrayND[_XT_co]: ... + @abc.abstractmethod + def kurtosis(self, /, *, method: _SMomentMethod) -> _XT_co | onp.ArrayND[_XT_co]: ... + + # + @overload + @abc.abstractmethod + def moment(self, /, order: onp.ToInt, kind: L["raw"], *, method: _RMomentMethod) -> _Float | _FloatND: ... + @overload + @abc.abstractmethod + def moment(self, /, order: onp.ToInt, kind: L["central"], *, method: _CMomentMethod) -> _Float | _FloatND: ... + @overload + @abc.abstractmethod + def moment(self, /, order: onp.ToInt, kind: L["standardized"], *, method: _SMomentMethod) -> _Float | _FloatND: ... + + # + @abc.abstractmethod + def entropy(self, /, *, method: _EntropyMethod) -> _Float | _FloatND: ... + @abc.abstractmethod + def logentropy(self, /, *, method: _EntropyMethod) -> _Complex | _ComplexND: ... + + # + @abc.abstractmethod + def pdf(self, x: _ToFloat0ND, /, *, method: _PDFMethod) -> _Float | _FloatND: ... + @abc.abstractmethod + def logpdf(self, x: _ToFloat0ND, /, *, method: _PDFMethod) -> _Float | _FloatND: ... + + # + @abc.abstractmethod + def cdf(self, x: _ToFloat0ND, y: _ToFloat0ND | None, /, *, method: _CDFMethod) -> _Float | _FloatND: ... + @abc.abstractmethod + def icdf(self, p: _ToFloat0ND, /, *, method: _ICDFMethod) -> _Float | _FloatND: ... + @abc.abstractmethod + def ccdf(self, x: _ToFloat0ND, y: _ToFloat0ND | None, /, *, method: _CCDFMethod) -> _Float | _FloatND: ... + @abc.abstractmethod + def iccdf(self, p: _ToFloat0ND, /, *, method: _ICDFMethod) -> _Float | _FloatND: ... + @abc.abstractmethod + def logcdf(self, x: _ToFloat0ND, y: _ToFloat0ND | None, /, *, method: _CDFMethod) -> _Float | _FloatND: ... + @abc.abstractmethod + def ilogcdf(self, logp: _ToFloat0ND, /, *, method: _ICDFMethod) -> _Float | _FloatND: ... + @abc.abstractmethod + def logccdf(self, x: _ToFloat0ND, y: _ToFloat0ND | None, /, *, method: _CCDFMethod) -> _Float | _FloatND: ... + @abc.abstractmethod + def ilogccdf(self, logp: _ToFloat0ND, /, *, method: _ICDFMethod) -> _Float | _FloatND: ... + +### + +_Self: TypeAlias = _BaseDistribution[_XT, _ShapeT0] +_Self0: TypeAlias = _Self[_XT, tuple[()]] +_Self1: TypeAlias = _Self[_XT, tuple[int]] +_Self2: TypeAlias = _Self[_XT, tuple[int, int]] +_Self3: TypeAlias = _Self[_XT, tuple[int, int, int]] +_Self1_: TypeAlias = _Self[_XT, onp.AtLeast1D] + +# TODO(jorenham): Merge into ContinuousDistribution? +@type_check_only +class _BaseDistribution(_ProbabilityDistribution[_XT_co], Generic[_XT_co, _ShapeT0_co]): + @overload + def support(self: _Self0[_XT], /) -> _Tuple2[_XT]: ... + @overload + def support(self: _Self[_XT, _ShapeT], /) -> _Tuple2[onp.Array[_ShapeT, _XT]]: ... + + # + @overload + def median(self: _Self0[_XT], /, *, method: _MedianMethod = None) -> _XT: ... + @overload + def median(self: _Self[_XT, _ShapeT], /, *, method: _MedianMethod = None) -> onp.Array[_ShapeT, _XT]: ... + + # + @overload + def mode(self: _Self0[_XT], /, *, method: _ModeMethod = None) -> _XT: ... + @overload + def mode(self: _Self[_XT, _ShapeT], /, *, method: _ModeMethod = None) -> onp.Array[_ShapeT, _XT]: ... + + # + @overload + def sample(self: _Self0[_XT], /, shape: tuple[()] = (), *, method: _SampleMethod = None, rng: _ToQRNG = None) -> _XT: ... + @overload + def sample( + self: _Self0[_XT], + /, + shape: op.CanIndex, + *, + method: _SampleMethod = None, + rng: _ToQRNG = None, + ) -> onp.Array1D[_XT]: ... + @overload + def sample( + self: _Self0[_XT], + /, + shape: _ShapeT, + *, + method: _SampleMethod = None, + rng: _ToQRNG = None, + ) -> onp.ArrayND[_XT, _ShapeT]: ... + @overload + def sample( + self: _Self[_XT, _ShapeT], + /, + shape: tuple[()] = (), + *, + method: _SampleMethod = None, + rng: _ToQRNG = None, + ) -> onp.ArrayND[_XT, _ShapeT]: ... + @overload + def sample( + self: _Self[_XT, _ShapeT], + /, + shape: op.CanIndex | Iterable[op.CanIndex], + *, + method: _SampleMethod = None, + rng: _ToQRNG = None, + ) -> onp.ArrayND[_XT, _ShapeT] | onp.ArrayND[_XT]: ... # first union type is needed on `numpy<2.1` + @overload + def sample( + self, + /, + shape: op.CanIndex | Iterable[op.CanIndex], + *, + method: _SampleMethod = None, + rng: _ToQRNG = None, + ) -> _XT_co | onp.ArrayND[_XT_co, _ShapeT] | onp.ArrayND[_XT_co]: ... # first union type is needed on `numpy<2.1` + + # + @overload + def mean(self: _Self0[_XT], /, *, method: _RMomentMethod = None) -> _XT: ... + @overload + def mean(self: _Self[_XT, _ShapeT], /, *, method: _RMomentMethod = None) -> onp.ArrayND[_XT, _ShapeT]: ... + + # + @overload + def variance(self: _Self0[_XT], /, *, method: _CMomentMethod = None) -> _XT: ... + @overload + def variance(self: _Self[_XT, _ShapeT], /, *, method: _CMomentMethod = None) -> onp.ArrayND[_XT, _ShapeT]: ... + + # + @overload + def standard_deviation(self: _Self0[_XT], /, *, method: _CMomentMethod = None) -> _XT: ... + @overload + def standard_deviation(self: _Self[_XT, _ShapeT], /, *, method: _CMomentMethod = None) -> onp.ArrayND[_XT, _ShapeT]: ... + + # + @overload + def skewness(self: _Self0[_XT], /, *, method: _SMomentMethod = None) -> _XT: ... + @overload + def skewness(self: _Self[_XT, _ShapeT], /, *, method: _SMomentMethod = None) -> onp.ArrayND[_XT, _ShapeT]: ... + + # + @overload + def kurtosis( + self: _Self0[_XT], /, *, method: _SMomentMethod = None, convention: _KurtosisConvention = "non-excess" + ) -> _XT: ... + @overload + def kurtosis( + self: _Self[_XT, _ShapeT], /, *, method: _SMomentMethod = None, convention: _KurtosisConvention = "non-excess" + ) -> onp.ArrayND[_XT, _ShapeT]: ... + + # + @overload + def moment(self: _Self0, /, order: onp.ToInt = 1, kind: L["raw"] = "raw", *, method: _RMomentMethod = None) -> _Float: ... + @overload + def moment(self: _Self0, /, order: onp.ToInt, kind: L["central"], *, method: _CMomentMethod = None) -> _Float: ... + @overload + def moment(self: _Self0, /, order: onp.ToInt = 1, *, kind: L["central"], method: _CMomentMethod = None) -> _Float: ... + @overload + def moment(self: _Self0, /, order: onp.ToInt, kind: L["standardized"], *, method: _SMomentMethod = None) -> _Float: ... + @overload + def moment(self: _Self0, /, order: onp.ToInt = 1, *, kind: L["standardized"], method: _SMomentMethod = None) -> _Float: ... + @overload + def moment( + self: _Self[Any, _ShapeT], /, order: onp.ToInt = 1, kind: L["raw"] = "raw", *, method: _RMomentMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload + def moment( + self: _Self[Any, _ShapeT], /, order: onp.ToInt, kind: L["central"], *, method: _CMomentMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload + def moment( + self: _Self[Any, _ShapeT], /, order: onp.ToInt = 1, *, kind: L["central"], method: _CMomentMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload + def moment( + self: _Self[Any, _ShapeT], /, order: onp.ToInt, kind: L["standardized"], *, method: _SMomentMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload + def moment( # pyright: ignore[reportIncompatibleMethodOverride] # pyright false positive bug + self: _Self[Any, _ShapeT], /, order: onp.ToInt = 1, *, kind: L["standardized"], method: _SMomentMethod = None + ) -> _FloatND[_ShapeT]: ... + + # + @overload + def entropy(self: _Self0, /, *, method: _EntropyMethod = None) -> _Float: ... + @overload + def entropy(self: _Self[Any, _ShapeT], /, *, method: _EntropyMethod = None) -> _FloatND[_ShapeT]: ... + + # + @overload + def logentropy(self: _Self0, /, *, method: _EntropyMethod = None) -> _Complex: ... + @overload + def logentropy(self: _Self[Any, _ShapeT], /, *, method: _EntropyMethod = None) -> _ComplexND[_ShapeT]: ... + + # + # TODO(jorenham): Adjust these, depending on the result of https://github.com/scipy/scipy/issues/22145 + # NOTE: The signatures of `pdf` and `logpdf` are equivalent + @overload # self: T1-d, x: 0-d + def pdf(self: _Self[Any, _ShapeT], x: onp.ToFloat, /, *, method: _PDFMethod = None) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: 0-d + def pdf(self: _Self0, x: onp.ToFloat, /, *, method: _PDFMethod = None) -> _Float: ... + @overload # self: 0-d, x: 1-d + def pdf(self: _Self0, x: onp.ToFloatStrict1D, /, *, method: _PDFMethod = None) -> _Float1D: ... + @overload # self: 0-d, x: 2-d + def pdf(self: _Self0, x: onp.ToFloatStrict2D, /, *, method: _PDFMethod = None) -> _Float2D: ... + @overload # self: 0-d, x: 3-d + def pdf(self: _Self0, x: onp.ToFloatStrict3D, /, *, method: _PDFMethod = None) -> _Float3D: ... + @overload # self: 0-d, x: T1-d + def pdf(self: _Self0, x: _ToFloatND[_ShapeT], /, *, method: _PDFMethod = None) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: >=1-d + def pdf( # first union type is needed on `numpy<2.1` + self: _Self0, x: _ToFloatND[_ShapeT] | onp.ToFloatND, /, *, method: _PDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 1-d, x: 1-d + def pdf(self: _Self1, x: onp.ToFloatStrict1D, /, *, method: _PDFMethod = None) -> _Float2D: ... + @overload # self: 1-d, x: 2-d + def pdf(self: _Self1, x: onp.ToFloatStrict2D, /, *, method: _PDFMethod = None) -> _Float3D: ... + @overload # self: 1-d, x: >=-d + def pdf(self: _Self1, x: onp.ToFloatND, /, *, method: _PDFMethod = None) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 2-d, x: 1-d + def pdf(self: _Self2, x: onp.ToFloatStrict1D, /, *, method: _PDFMethod = None) -> _Float3D: ... + @overload # self: 2-d, x: >=1-d + def pdf(self: _Self2, x: onp.ToFloatND, /, *, method: _PDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 3-d, x: >=1-d + def pdf(self: _Self3, x: onp.ToFloatND, /, *, method: _PDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: >=1-d + def pdf(self: _Self1_, x: _ToFloat0ND, /, *, method: _PDFMethod = None) -> _FloatND: ... + + # + @overload # self: T1-d, x: 0-d + def logpdf(self: _Self[Any, _ShapeT], x: onp.ToFloat, /, *, method: _PDFMethod = None) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: 0-d + def logpdf(self: _Self0, x: onp.ToFloat, /, *, method: _PDFMethod = None) -> _Float: ... + @overload # self: 0-d, x: 1-d + def logpdf(self: _Self0, x: onp.ToFloatStrict1D, /, *, method: _PDFMethod = None) -> _Float1D: ... + @overload # self: 0-d, x: 2-d + def logpdf(self: _Self0, x: onp.ToFloatStrict2D, /, *, method: _PDFMethod = None) -> _Float2D: ... + @overload # self: 0-d, x: 3-d + def logpdf(self: _Self0, x: onp.ToFloatStrict3D, /, *, method: _PDFMethod = None) -> _Float3D: ... + @overload # self: 0-d, x: T1-d + def logpdf(self: _Self0, x: _ToFloatND[_ShapeT], /, *, method: _PDFMethod = None) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: >=1-d + def logpdf( # first union type is needed on `numpy<2.1` + self: _Self0, x: _ToFloatND[_ShapeT] | onp.ToFloatND, /, *, method: _PDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 1-d, x: 1-d + def logpdf(self: _Self1, x: onp.ToFloatStrict1D, /, *, method: _PDFMethod = None) -> _Float2D: ... + @overload # self: 1-d, x: 2-d + def logpdf(self: _Self1, x: onp.ToFloatStrict2D, /, *, method: _PDFMethod = None) -> _Float3D: ... + @overload # self: 1-d, x: >=1-d + def logpdf(self: _Self1, x: onp.ToFloatND, /, *, method: _PDFMethod = None) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 2-d, x: 1-d + def logpdf(self: _Self2, x: onp.ToFloatStrict1D, /, *, method: _PDFMethod = None) -> _Float3D: ... + @overload # self: 2-d, x: >=1-d + def logpdf(self: _Self2, x: onp.ToFloatND, /, *, method: _PDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 3-d, x: >=1-d + def logpdf(self: _Self3, x: onp.ToFloatND, /, *, method: _PDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: >=1-d + def logpdf(self: _Self1_, x: _ToFloat0ND, /, *, method: _PDFMethod = None) -> _FloatND: ... + + # + # NOTE: Apart from the `method` type, the signatures of `[log]cdf` and `[log]ccdf` are equivalent + @overload # self: T1-d, x: 0-d, y?: 0-d + def cdf( + self: _Self[Any, _ShapeT], x: onp.ToFloat, y: onp.ToFloat | None = None, /, *, method: _CDFMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: 0-d, y?: 0-d + def cdf(self: _Self0, x: onp.ToFloat, y: onp.ToFloat | None = None, /, *, method: _CDFMethod = None) -> _Float: ... + @overload # self: 0-d, x: 1-d, y?: <=1-d + def cdf( + self: _Self0, x: onp.ToFloatStrict1D, y: _ToFloatMax1D | None = None, /, *, method: _CDFMethod = None + ) -> _Float1D: ... + @overload # self: 0-d, x: <=1-d, y: 1-d + def cdf(self: _Self0, x: _ToFloatMax1D, y: onp.ToFloatStrict1D, /, *, method: _CDFMethod = None) -> _Float1D: ... + @overload # self: 0-d, x: 2-d, y?: <=2-d + def cdf( + self: _Self0, x: onp.ToFloatStrict2D, y: _ToFloatMax2D | None = None, /, *, method: _CDFMethod = None + ) -> _Float2D: ... + @overload # self: 0-d, x: <=2-d, y: 2-d + def cdf(self: _Self0, x: _ToFloatMax2D, y: onp.ToFloatStrict2D, /, *, method: _CDFMethod = None) -> _Float2D: ... + @overload # self: 0-d, x: 3-d, y?: <=3-d + def cdf( + self: _Self0, x: onp.ToFloatStrict3D, y: _ToFloatMax3D | None = None, /, *, method: _CDFMethod = None + ) -> _Float3D: ... + @overload # self: 0-d, x: <=3-d, y: 3-d + def cdf(self: _Self0, x: _ToFloatMax3D, y: onp.ToFloatStrict3D, /, *, method: _CDFMethod = None) -> _Float3D: ... + @overload # self: 0-d, x: T1-d, y?: T1-d | <=1-d + def cdf( + self: _Self0, x: _ToFloatND[_ShapeT], y: _ToFloatMax1D | None = None, /, *, method: _CDFMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: T1-d | <=1-d, y: T1-d + def cdf( + self: _Self0, x: _ToFloatMaxND[_ShapeT], y: _ToFloatND[_ShapeT], /, *, method: _CDFMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: >=1-d, y?: >=0-d + def cdf( # first union type is needed on `numpy<2.1` + self: _Self0, x: _ToFloatND[_ShapeT] | onp.ToFloatND, y: _ToFloat0ND | None = None, /, *, method: _CDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 0-d, x: >=0-d, y: >=1-d + def cdf( # first union type is needed on `numpy<2.1` + self: _Self0, x: _ToFloat0ND, y: _ToFloatND[_ShapeT] | onp.ToFloatND, /, *, method: _CDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 1-d, x: 1-d, y?: <=1-d + def cdf( + self: _Self1, x: onp.ToFloatStrict1D, y: _ToFloatMax1D | None = None, /, *, method: _CDFMethod = None + ) -> _Float2D: ... + @overload # self: 1-d, x: <=1-d, y: 1-d + def cdf(self: _Self1, x: _ToFloatMax1D, y: onp.ToFloatStrict1D, /, *, method: _CDFMethod = None) -> _Float2D: ... + @overload # self: 1-d, x: 2-d, y?: <=2-d + def cdf( + self: _Self1, x: onp.ToFloatStrict2D, y: _ToFloatMax2D | None = None, /, *, method: _CDFMethod = None + ) -> _Float3D: ... + @overload # self: 1-d, x: <=2-d, y: 2-d + def cdf(self: _Self1, x: _ToFloatMax2D, y: onp.ToFloatStrict2D, /, *, method: _CDFMethod = None) -> _Float3D: ... + @overload # self: 1-d, x: >=1-d, y?: >=0-d + def cdf( + self: _Self1, x: onp.ToFloatND, y: _ToFloat0ND | None = None, /, *, method: _CDFMethod = None + ) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 1-d, x: >=0-d, y: >=1-d + def cdf(self: _Self1, x: _ToFloat0ND, y: onp.ToFloatND, /, *, method: _CDFMethod = None) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 2-d, x: 1-d, y?: <=1-d + def cdf( + self: _Self2, x: onp.ToFloatStrict1D, y: _ToFloatMax1D | None = None, /, *, method: _CDFMethod = None + ) -> _Float3D: ... + @overload # self: 2-d, x: <=1-d, y: 1-d + def cdf(self: _Self2, x: _ToFloatMax1D, y: onp.ToFloatStrict1D, /, *, method: _CDFMethod = None) -> _Float3D: ... + @overload # self: 2-d, x: >=1-d, y?: >=0-d + def cdf( + self: _Self2, x: onp.ToFloatND, y: _ToFloat0ND | None = None, /, *, method: _CDFMethod = None + ) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 2-d, x: >=0-d, y: >=1-d + def cdf(self: _Self2, x: _ToFloat0ND, y: onp.ToFloatND, /, *, method: _CDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 3-d, x: >=0-d, y?: >=0-d + def cdf( + self: _Self3, x: _ToFloat0ND, y: _ToFloat0ND | None = None, /, *, method: _CDFMethod = None + ) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: >=1-d, x: >=0-d, y?: >=0-d + def cdf(self: _Self1_, x: _ToFloat0ND, y: _ToFloat0ND | None = None, /, *, method: _CDFMethod = None) -> _FloatND: ... + + # + @overload # self: T1-d, x: 0-d, y?: 0-d + def logcdf( + self: _Self[Any, _ShapeT], x: onp.ToFloat, y: onp.ToFloat | None = None, /, *, method: _CDFMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: 0-d, y?: 0-d + def logcdf(self: _Self0, x: onp.ToFloat, y: onp.ToFloat | None = None, /, *, method: _CDFMethod = None) -> _Float: ... + @overload # self: 0-d, x: 1-d, y?: <=1-d + def logcdf( + self: _Self0, x: onp.ToFloatStrict1D, y: _ToFloatMax1D | None = None, /, *, method: _CDFMethod = None + ) -> _Float1D: ... + @overload # self: 0-d, x: <=1-d, y: 1-d + def logcdf(self: _Self0, x: _ToFloatMax1D, y: onp.ToFloatStrict1D, /, *, method: _CDFMethod = None) -> _Float1D: ... + @overload # self: 0-d, x: 2-d, y?: <=2-d + def logcdf( + self: _Self0, x: onp.ToFloatStrict2D, y: _ToFloatMax2D | None = None, /, *, method: _CDFMethod = None + ) -> _Float2D: ... + @overload # self: 0-d, x: <=2-d, y: 2-d + def logcdf(self: _Self0, x: _ToFloatMax2D, y: onp.ToFloatStrict2D, /, *, method: _CDFMethod = None) -> _Float2D: ... + @overload # self: 0-d, x: 3-d, y?: <=3-d + def logcdf( + self: _Self0, x: onp.ToFloatStrict3D, y: _ToFloatMax3D | None = None, /, *, method: _CDFMethod = None + ) -> _Float3D: ... + @overload # self: 0-d, x: <=3-d, y: 3-d + def logcdf(self: _Self0, x: _ToFloatMax3D, y: onp.ToFloatStrict3D, /, *, method: _CDFMethod = None) -> _Float3D: ... + @overload # self: 0-d, x: T1-d, y?: T1-d | <=1-d + def logcdf( + self: _Self0, x: _ToFloatND[_ShapeT], y: _ToFloatMax1D | None = None, /, *, method: _CDFMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: T1-d | <=1-d, y: T1-d + def logcdf( + self: _Self0, x: _ToFloatMaxND[_ShapeT], y: _ToFloatND[_ShapeT], /, *, method: _CDFMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: >=1-d, y?: >=0-d + def logcdf( # first union type is needed on `numpy<2.1` + self: _Self0, x: _ToFloatND[_ShapeT] | onp.ToFloatND, y: _ToFloat0ND | None = None, /, *, method: _CDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 0-d, x: >=0-d, y: >=1-d + def logcdf( # first union type is needed on `numpy<2.1` + self: _Self0, x: _ToFloat0ND, y: _ToFloatND[_ShapeT] | onp.ToFloatND, /, *, method: _CDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 1-d, x: 1-d, y?: <=1-d + def logcdf( + self: _Self1, x: onp.ToFloatStrict1D, y: _ToFloatMax1D | None = None, /, *, method: _CDFMethod = None + ) -> _Float2D: ... + @overload # self: 1-d, x: <=1-d, y: 1-d + def logcdf(self: _Self1, x: _ToFloatMax1D, y: onp.ToFloatStrict1D, /, *, method: _CDFMethod = None) -> _Float2D: ... + @overload # self: 1-d, x: 2-d, y?: <=2-d + def logcdf( + self: _Self1, x: onp.ToFloatStrict2D, y: _ToFloatMax2D | None = None, /, *, method: _CDFMethod = None + ) -> _Float3D: ... + @overload # self: 1-d, x: <=2-d, y: 2-d + def logcdf(self: _Self1, x: _ToFloatMax2D, y: onp.ToFloatStrict2D, /, *, method: _CDFMethod = None) -> _Float3D: ... + @overload # self: 1-d, x: >=1-d, y?: >=0-d + def logcdf( + self: _Self1, x: onp.ToFloatND, y: _ToFloat0ND | None = None, /, *, method: _CDFMethod = None + ) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 1-d, x: >=0-d, y: >=1-d + def logcdf(self: _Self1, x: _ToFloat0ND, y: onp.ToFloatND, /, *, method: _CDFMethod = None) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 2-d, x: 1-d, y?: <=1-d + def logcdf( + self: _Self2, x: onp.ToFloatStrict1D, y: _ToFloatMax1D | None = None, /, *, method: _CDFMethod = None + ) -> _Float3D: ... + @overload # self: 2-d, x: <=1-d, y: 1-d + def logcdf(self: _Self2, x: _ToFloatMax1D, y: onp.ToFloatStrict1D, /, *, method: _CDFMethod = None) -> _Float3D: ... + @overload # self: 2-d, x: >=1-d, y?: >=0-d + def logcdf( + self: _Self2, x: onp.ToFloatND, y: _ToFloat0ND | None = None, /, *, method: _CDFMethod = None + ) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 2-d, x: >=0-d, y: >=1-d + def logcdf(self: _Self2, x: _ToFloat0ND, y: onp.ToFloatND, /, *, method: _CDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 3-d, x: >=0-d, y?: >=0-d + def logcdf( + self: _Self3, x: _ToFloat0ND, y: _ToFloat0ND | None = None, /, *, method: _CDFMethod = None + ) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: >=1-d, x: >=0-d, y?: >=0-d + def logcdf(self: _Self1_, x: _ToFloat0ND, y: _ToFloat0ND | None = None, /, *, method: _CDFMethod = None) -> _FloatND: ... + + # + @overload # self: T1-d, x: 0-d, y?: 0-d + def ccdf( + self: _Self[Any, _ShapeT], x: onp.ToFloat, y: onp.ToFloat | None = None, /, *, method: _CCDFMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: 0-d, y?: 0-d + def ccdf(self: _Self0, x: onp.ToFloat, y: onp.ToFloat | None = None, /, *, method: _CCDFMethod = None) -> _Float: ... + @overload # self: 0-d, x: 1-d, y?: <=1-d + def ccdf( + self: _Self0, x: onp.ToFloatStrict1D, y: _ToFloatMax1D | None = None, /, *, method: _CCDFMethod = None + ) -> _Float1D: ... + @overload # self: 0-d, x: <=1-d, y: 1-d + def ccdf(self: _Self0, x: _ToFloatMax1D, y: onp.ToFloatStrict1D, /, *, method: _CCDFMethod = None) -> _Float1D: ... + @overload # self: 0-d, x: 2-d, y?: <=2-d + def ccdf( + self: _Self0, x: onp.ToFloatStrict2D, y: _ToFloatMax2D | None = None, /, *, method: _CCDFMethod = None + ) -> _Float2D: ... + @overload # self: 0-d, x: <=2-d, y: 2-d + def ccdf(self: _Self0, x: _ToFloatMax2D, y: onp.ToFloatStrict2D, /, *, method: _CCDFMethod = None) -> _Float2D: ... + @overload # self: 0-d, x: 3-d, y?: <=3-d + def ccdf( + self: _Self0, x: onp.ToFloatStrict3D, y: _ToFloatMax3D | None = None, /, *, method: _CCDFMethod = None + ) -> _Float3D: ... + @overload # self: 0-d, x: <=3-d, y: 3-d + def ccdf(self: _Self0, x: _ToFloatMax3D, y: onp.ToFloatStrict3D, /, *, method: _CCDFMethod = None) -> _Float3D: ... + @overload # self: 0-d, x: T1-d, y?: T1-d | <=1-d + def ccdf( + self: _Self0, x: _ToFloatND[_ShapeT], y: _ToFloatMax1D | None = None, /, *, method: _CCDFMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: T1-d | <=1-d, y: T1-d + def ccdf( + self: _Self0, x: _ToFloatMaxND[_ShapeT], y: _ToFloatND[_ShapeT], /, *, method: _CCDFMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: >=1-d, y?: >=0-d + def ccdf( # first union type is needed on `numpy<2.1` + self: _Self0, x: _ToFloatND[_ShapeT] | onp.ToFloatND, y: _ToFloat0ND | None = None, /, *, method: _CCDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 0-d, x: >=0-d, y: >=1-d + def ccdf( # first union type is needed on `numpy<2.1` + self: _Self0, x: _ToFloat0ND, y: _ToFloatND[_ShapeT] | onp.ToFloatND, /, *, method: _CCDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 1-d, x: 1-d, y?: <=1-d + def ccdf( + self: _Self1, x: onp.ToFloatStrict1D, y: _ToFloatMax1D | None = None, /, *, method: _CCDFMethod = None + ) -> _Float2D: ... + @overload # self: 1-d, x: <=1-d, y: 1-d + def ccdf(self: _Self1, x: _ToFloatMax1D, y: onp.ToFloatStrict1D, /, *, method: _CCDFMethod = None) -> _Float2D: ... + @overload # self: 1-d, x: 2-d, y?: <=2-d + def ccdf( + self: _Self1, x: onp.ToFloatStrict2D, y: _ToFloatMax2D | None = None, /, *, method: _CCDFMethod = None + ) -> _Float3D: ... + @overload # self: 1-d, x: <=2-d, y: 2-d + def ccdf(self: _Self1, x: _ToFloatMax2D, y: onp.ToFloatStrict2D, /, *, method: _CCDFMethod = None) -> _Float3D: ... + @overload # self: 1-d, x: >=1-d, y?: >=0-d + def ccdf( + self: _Self1, x: onp.ToFloatND, y: _ToFloat0ND | None = None, /, *, method: _CCDFMethod = None + ) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 1-d, x: >=0-d, y: >=1-d + def ccdf(self: _Self1, x: _ToFloat0ND, y: onp.ToFloatND, /, *, method: _CCDFMethod = None) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 2-d, x: 1-d, y?: <=1-d + def ccdf( + self: _Self2, x: onp.ToFloatStrict1D, y: _ToFloatMax1D | None = None, /, *, method: _CCDFMethod = None + ) -> _Float3D: ... + @overload # self: 2-d, x: <=1-d, y: 1-d + def ccdf(self: _Self2, x: _ToFloatMax1D, y: onp.ToFloatStrict1D, /, *, method: _CCDFMethod = None) -> _Float3D: ... + @overload # self: 2-d, x: >=1-d, y?: >=0-d + def ccdf( + self: _Self2, x: onp.ToFloatND, y: _ToFloat0ND | None = None, /, *, method: _CCDFMethod = None + ) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 2-d, x: >=0-d, y: >=1-d + def ccdf(self: _Self2, x: _ToFloat0ND, y: onp.ToFloatND, /, *, method: _CCDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 3-d, x: >=0-d, y?: >=0-d + def ccdf( + self: _Self3, x: _ToFloat0ND, y: _ToFloat0ND | None = None, /, *, method: _CCDFMethod = None + ) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: >=1-d, x: >=0-d, y?: >=0-d + def ccdf(self: _Self1_, x: _ToFloat0ND, y: _ToFloat0ND | None = None, /, *, method: _CCDFMethod = None) -> _FloatND: ... + + # + @overload # self: T1-d, x: 0-d, y?: 0-d + def logccdf( + self: _Self[Any, _ShapeT], x: onp.ToFloat, y: onp.ToFloat | None = None, /, *, method: _CCDFMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: 0-d, y?: 0-d + def logccdf(self: _Self0, x: onp.ToFloat, y: onp.ToFloat | None = None, /, *, method: _CCDFMethod = None) -> _Float: ... + @overload # self: 0-d, x: 1-d, y?: <=1-d + def logccdf( + self: _Self0, x: onp.ToFloatStrict1D, y: _ToFloatMax1D | None = None, /, *, method: _CCDFMethod = None + ) -> _Float1D: ... + @overload # self: 0-d, x: <=1-d, y: 1-d + def logccdf(self: _Self0, x: _ToFloatMax1D, y: onp.ToFloatStrict1D, /, *, method: _CCDFMethod = None) -> _Float1D: ... + @overload # self: 0-d, x: 2-d, y?: <=2-d + def logccdf( + self: _Self0, x: onp.ToFloatStrict2D, y: _ToFloatMax2D | None = None, /, *, method: _CCDFMethod = None + ) -> _Float2D: ... + @overload # self: 0-d, x: <=2-d, y: 2-d + def logccdf(self: _Self0, x: _ToFloatMax2D, y: onp.ToFloatStrict2D, /, *, method: _CCDFMethod = None) -> _Float2D: ... + @overload # self: 0-d, x: 3-d, y?: <=3-d + def logccdf( + self: _Self0, x: onp.ToFloatStrict3D, y: _ToFloatMax3D | None = None, /, *, method: _CCDFMethod = None + ) -> _Float3D: ... + @overload # self: 0-d, x: <=3-d, y: 3-d + def logccdf(self: _Self0, x: _ToFloatMax3D, y: onp.ToFloatStrict3D, /, *, method: _CCDFMethod = None) -> _Float3D: ... + @overload # self: 0-d, x: T1-d, y?: T1-d | <=1-d + def logccdf( + self: _Self0, x: _ToFloatND[_ShapeT], y: _ToFloatMax1D | None = None, /, *, method: _CCDFMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: T1-d | <=1-d, y: T1-d + def logccdf( + self: _Self0, x: _ToFloatMaxND[_ShapeT], y: _ToFloatND[_ShapeT], /, *, method: _CCDFMethod = None + ) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, x: >=1-d, y?: >=0-d + def logccdf( # first union type is needed on `numpy<2.1` + self: _Self0, x: _ToFloatND[_ShapeT] | onp.ToFloatND, y: _ToFloat0ND | None = None, /, *, method: _CCDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 0-d, x: >=0-d, y: >=1-d + def logccdf( # first union type is needed on `numpy<2.1` + self: _Self0, x: _ToFloat0ND, y: _ToFloatND[_ShapeT] | onp.ToFloatND, /, *, method: _CCDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 1-d, x: 1-d, y?: <=1-d + def logccdf( + self: _Self1, x: onp.ToFloatStrict1D, y: _ToFloatMax1D | None = None, /, *, method: _CCDFMethod = None + ) -> _Float2D: ... + @overload # self: 1-d, x: <=1-d, y: 1-d + def logccdf(self: _Self1, x: _ToFloatMax1D, y: onp.ToFloatStrict1D, /, *, method: _CCDFMethod = None) -> _Float2D: ... + @overload # self: 1-d, x: 2-d, y?: <=2-d + def logccdf( + self: _Self1, x: onp.ToFloatStrict2D, y: _ToFloatMax2D | None = None, /, *, method: _CCDFMethod = None + ) -> _Float3D: ... + @overload # self: 1-d, x: <=2-d, y: 2-d + def logccdf(self: _Self1, x: _ToFloatMax2D, y: onp.ToFloatStrict2D, /, *, method: _CCDFMethod = None) -> _Float3D: ... + @overload # self: 1-d, x: >=1-d, y?: >=0-d + def logccdf( + self: _Self1, x: onp.ToFloatND, y: _ToFloat0ND | None = None, /, *, method: _CCDFMethod = None + ) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 1-d, x: >=0-d, y: >=1-d + def logccdf(self: _Self1, x: _ToFloat0ND, y: onp.ToFloatND, /, *, method: _CCDFMethod = None) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 2-d, x: 1-d, y?: <=1-d + def logccdf( + self: _Self2, x: onp.ToFloatStrict1D, y: _ToFloatMax1D | None = None, /, *, method: _CCDFMethod = None + ) -> _Float3D: ... + @overload # self: 2-d, x: <=1-d, y: 1-d + def logccdf(self: _Self2, x: _ToFloatMax1D, y: onp.ToFloatStrict1D, /, *, method: _CCDFMethod = None) -> _Float3D: ... + @overload # self: 2-d, x: >=1-d, y?: >=0-d + def logccdf( + self: _Self2, x: onp.ToFloatND, y: _ToFloat0ND | None = None, /, *, method: _CCDFMethod = None + ) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 2-d, x: >=0-d, y: >=1-d + def logccdf(self: _Self2, x: _ToFloat0ND, y: onp.ToFloatND, /, *, method: _CCDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 3-d, x: >=0-d, y?: >=0-d + def logccdf( + self: _Self3, x: _ToFloat0ND, y: _ToFloat0ND | None = None, /, *, method: _CCDFMethod = None + ) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: >=1-d, x: >=0-d, y?: >=0-d + def logccdf(self: _Self1_, x: _ToFloat0ND, y: _ToFloat0ND | None = None, /, *, method: _CCDFMethod = None) -> _FloatND: ... + + # NOTE: Apart from the `method` type, the signatures of `i[log]cdf` and `i[log]ccdf` are equivalent to those of `[log]pdf` + @overload # self: T1-d, p: 0-d + def icdf(self: _Self[Any, _ShapeT], p: onp.ToFloat, /, *, method: _ICDFMethod = None) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, p: 0-d + def icdf(self: _Self0, p: onp.ToFloat, /, *, method: _ICDFMethod = None) -> _Float: ... + @overload # self: 0-d, p: 1-d + def icdf(self: _Self0, p: onp.ToFloatStrict1D, /, *, method: _ICDFMethod = None) -> _Float1D: ... + @overload # self: 0-d, p: 2-d + def icdf(self: _Self0, p: onp.ToFloatStrict2D, /, *, method: _ICDFMethod = None) -> _Float2D: ... + @overload # self: 0-d, p: 3-d + def icdf(self: _Self0, p: onp.ToFloatStrict3D, /, *, method: _ICDFMethod = None) -> _Float3D: ... + @overload # self: 0-d, p: T1-d + def icdf(self: _Self0, p: _ToFloatND[_ShapeT], /, *, method: _ICDFMethod = None) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, p: >=1-d + def icdf( # first union type is needed on `numpy<2.1` + self: _Self0, p: _ToFloatND[_ShapeT] | onp.ToFloatND, /, *, method: _ICDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 1-d, p: 1-d + def icdf(self: _Self1, p: onp.ToFloatStrict1D, /, *, method: _ICDFMethod = None) -> _Float2D: ... + @overload # self: 1-d, p: 2-d + def icdf(self: _Self1, p: onp.ToFloatStrict2D, /, *, method: _ICDFMethod = None) -> _Float3D: ... + @overload # self: 1-d, p: >=-d + def icdf(self: _Self1, p: onp.ToFloatND, /, *, method: _ICDFMethod = None) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 2-d, p: 1-d + def icdf(self: _Self2, p: onp.ToFloatStrict1D, /, *, method: _ICDFMethod = None) -> _Float3D: ... + @overload # self: 2-d, p: >=1-d + def icdf(self: _Self2, p: onp.ToFloatND, /, *, method: _ICDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 3-d, p: >=1-d + def icdf(self: _Self3, p: onp.ToFloatND, /, *, method: _ICDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: >=1-d + def icdf(self: _Self1_, p: _ToFloat0ND, /, *, method: _ICDFMethod = None) -> _FloatND: ... + # + @overload # self: T1-d, logp: 0-d + def ilogcdf(self: _Self[Any, _ShapeT], logp: onp.ToFloat, /, *, method: _ICDFMethod = None) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, logp: 0-d + def ilogcdf(self: _Self0, logp: onp.ToFloat, /, *, method: _ICDFMethod = None) -> _Float: ... + @overload # self: 0-d, logp: 1-d + def ilogcdf(self: _Self0, logp: onp.ToFloatStrict1D, /, *, method: _ICDFMethod = None) -> _Float1D: ... + @overload # self: 0-d, logp: 2-d + def ilogcdf(self: _Self0, logp: onp.ToFloatStrict2D, /, *, method: _ICDFMethod = None) -> _Float2D: ... + @overload # self: 0-d, logp: 3-d + def ilogcdf(self: _Self0, logp: onp.ToFloatStrict3D, /, *, method: _ICDFMethod = None) -> _Float3D: ... + @overload # self: 0-d, logp: T1-d + def ilogcdf(self: _Self0, logp: _ToFloatND[_ShapeT], /, *, method: _ICDFMethod = None) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, p: >=1-d + def ilogcdf( # first union type is needed on `numpy<2.1` + self: _Self0, logp: _ToFloatND[_ShapeT] | onp.ToFloatND, /, *, method: _ICDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 1-d, logp: 1-d + def ilogcdf(self: _Self1, logp: onp.ToFloatStrict1D, /, *, method: _ICDFMethod = None) -> _Float2D: ... + @overload # self: 1-d, logp: 2-d + def ilogcdf(self: _Self1, logp: onp.ToFloatStrict2D, /, *, method: _ICDFMethod = None) -> _Float3D: ... + @overload # self: 1-d, logp: >=-d + def ilogcdf(self: _Self1, logp: onp.ToFloatND, /, *, method: _ICDFMethod = None) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 2-d, logp: 1-ds + def ilogcdf(self: _Self2, logp: onp.ToFloatStrict1D, /, *, method: _ICDFMethod = None) -> _Float3D: ... + @overload # self: 2-d, logp: >=1-d + def ilogcdf(self: _Self2, logp: onp.ToFloatND, /, *, method: _ICDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 3-d, logp: >=1-d + def ilogcdf(self: _Self3, logp: onp.ToFloatND, /, *, method: _ICDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: >=1-d + def ilogcdf(self: _Self1_, logp: _ToFloat0ND, /, *, method: _ICDFMethod = None) -> _FloatND: ... + + # + @overload # self: T1-d, p: 0-d + def iccdf(self: _Self[Any, _ShapeT], p: onp.ToFloat, /, *, method: _ICDFMethod = None) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, p: 0-d + def iccdf(self: _Self0, p: onp.ToFloat, /, *, method: _ICDFMethod = None) -> _Float: ... + @overload # self: 0-d, p: 1-d + def iccdf(self: _Self0, p: onp.ToFloatStrict1D, /, *, method: _ICDFMethod = None) -> _Float1D: ... + @overload # self: 0-d, p: 2-d + def iccdf(self: _Self0, p: onp.ToFloatStrict2D, /, *, method: _ICDFMethod = None) -> _Float2D: ... + @overload # self: 0-d, p: 3-d + def iccdf(self: _Self0, p: onp.ToFloatStrict3D, /, *, method: _ICDFMethod = None) -> _Float3D: ... + @overload # self: 0-d, p: T1-d + def iccdf(self: _Self0, p: _ToFloatND[_ShapeT], /, *, method: _ICDFMethod = None) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, p: >=1-d + def iccdf( # first union type is needed on `numpy<2.1` + self: _Self0, p: _ToFloatND[_ShapeT] | onp.ToFloatND, /, *, method: _ICDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 1-d, p: 1-d + def iccdf(self: _Self1, p: onp.ToFloatStrict1D, /, *, method: _ICDFMethod = None) -> _Float2D: ... + @overload # self: 1-d, p: 2-d + def iccdf(self: _Self1, p: onp.ToFloatStrict2D, /, *, method: _ICDFMethod = None) -> _Float3D: ... + @overload # self: 1-d, p: >=-d + def iccdf(self: _Self1, p: onp.ToFloatND, /, *, method: _ICDFMethod = None) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 2-d, p: 1-d + def iccdf(self: _Self2, p: onp.ToFloatStrict1D, /, *, method: _ICDFMethod = None) -> _Float3D: ... + @overload # self: 2-d, p: >=1-d + def iccdf(self: _Self2, p: onp.ToFloatND, /, *, method: _ICDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 3-d, p: >=1-d + def iccdf(self: _Self3, p: onp.ToFloatND, /, *, method: _ICDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: >=1-d + def iccdf(self: _Self1_, p: _ToFloat0ND, /, *, method: _ICDFMethod = None) -> _FloatND: ... + # + @overload # self: T1-d, logp: 0-d + def ilogccdf(self: _Self[Any, _ShapeT], logp: onp.ToFloat, /, *, method: _ICDFMethod = None) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, logp: 0-d + def ilogccdf(self: _Self0, logp: onp.ToFloat, /, *, method: _ICDFMethod = None) -> _Float: ... + @overload # self: 0-d, logp: 1-d + def ilogccdf(self: _Self0, logp: onp.ToFloatStrict1D, /, *, method: _ICDFMethod = None) -> _Float1D: ... + @overload # self: 0-d, logp: 2-d + def ilogccdf(self: _Self0, logp: onp.ToFloatStrict2D, /, *, method: _ICDFMethod = None) -> _Float2D: ... + @overload # self: 0-d, logp: 3-d + def ilogccdf(self: _Self0, logp: onp.ToFloatStrict3D, /, *, method: _ICDFMethod = None) -> _Float3D: ... + @overload # self: 0-d, logp: T1-d + def ilogccdf(self: _Self0, logp: _ToFloatND[_ShapeT], /, *, method: _ICDFMethod = None) -> _FloatND[_ShapeT]: ... + @overload # self: 0-d, q: >=1-d + def ilogccdf( # first union type is needed on `numpy<2.1` + self: _Self0, logp: _ToFloatND[_ShapeT] | onp.ToFloatND, /, *, method: _ICDFMethod = None + ) -> _FloatND[_ShapeT] | _FloatND[onp.AtLeast1D]: ... + @overload # self: 1-d, logp: 1-d + def ilogccdf(self: _Self1, logp: onp.ToFloatStrict1D, /, *, method: _ICDFMethod = None) -> _Float2D: ... + @overload # self: 1-d, logp: 2-d + def ilogccdf(self: _Self1, logp: onp.ToFloatStrict2D, /, *, method: _ICDFMethod = None) -> _Float3D: ... + @overload # self: 1-d, logp: >=-d + def ilogccdf(self: _Self1, logp: onp.ToFloatND, /, *, method: _ICDFMethod = None) -> _FloatND[onp.AtLeast2D]: ... + @overload # self: 2-d, logp: 1-d + def ilogccdf(self: _Self2, logp: onp.ToFloatStrict1D, /, *, method: _ICDFMethod = None) -> _Float3D: ... + @overload # self: 2-d, logp: >=1-d + def ilogccdf(self: _Self2, logp: onp.ToFloatND, /, *, method: _ICDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: 3-d, logp: >=1-d + def ilogccdf(self: _Self3, logp: onp.ToFloatND, /, *, method: _ICDFMethod = None) -> _FloatND[onp.AtLeast3D]: ... + @overload # self: >=1-d + def ilogccdf(self: _Self1_, logp: _ToFloat0ND, /, *, method: _ICDFMethod = None) -> _FloatND: ... diff --git a/tox.toml b/tox.toml index c1613b21..a56c20ee 100644 --- a/tox.toml +++ b/tox.toml @@ -75,18 +75,7 @@ commands = [ [env.basedpyright] description = "basedpyright" dependency_groups = ["typecheck"] -commands = [ - [ - "uv", - "pip", - "freeze", - ], - [ - "basedpyright", - "scipy-stubs", - "codegen", - ], -] +commands = [["uv", "pip", "freeze"], ["basedpyright", "scipy-stubs", "codegen"]] [env.min-versions-test] description = "min versions tests" @@ -140,7 +129,6 @@ commands = [ "stubtest", "--mypy-config-file=pyproject.toml", "--allowlist=.mypyignore", - "--allowlist=.mypyignore-todo", "--ignore-unused-allowlist", "scipy", ], @@ -168,19 +156,7 @@ commands = [ [env.pyright] description = "Run pyright" dependency_groups = ["typecheck"] -commands = [ - [ - "uv", - "pip", - "freeze", - ], - [ - "uv", - "run", - "--no-sync", - "basedpyright", - ], -] +commands = [["uv", "pip", "freeze"], ["uv", "run", "--no-sync", "basedpyright"]] [env.typetest] description = "Run all type tests"