From 3958afb40c4ee33c64ce52b5e045bfe907a40895 Mon Sep 17 00:00:00 2001 From: jorenham Date: Thu, 10 Jul 2025 00:47:12 +0200 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20`stats`:=20improved=20`[differe?= =?UTF-8?q?ntial=5F]entropy`=20anntations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scipy-stubs/stats/_entropy.pyi | 565 ++++++++++++++++++++++++++++++++- 1 file changed, 551 insertions(+), 14 deletions(-) diff --git a/scipy-stubs/stats/_entropy.pyi b/scipy-stubs/stats/_entropy.pyi index 4d68b4a8a..e91b74c40 100644 --- a/scipy-stubs/stats/_entropy.pyi +++ b/scipy-stubs/stats/_entropy.pyi @@ -1,6 +1,7 @@ -from typing import Literal +from typing import Literal, TypeAlias, overload +from typing_extensions import TypeAliasType, TypeVar -import optype as op +import numpy as np import optype.numpy as onp import optype.numpy.compat as npc @@ -8,22 +9,558 @@ from ._typing import NanPolicy __all__ = ["differential_entropy", "entropy"] +_InexactT = TypeVar("_InexactT", bound=npc.inexact) +_ScalarT = TypeVar("_ScalarT", bound=npc.number | np.bool_) +_PyScalarT = TypeVar("_PyScalarT") + +_AsF32: TypeAlias = np.float16 | np.float32 +_AsF64: TypeAlias = np.float64 | npc.integer | np.bool_ + +_DifferentialMethod: TypeAlias = Literal["vasicek", "van es", "ebrahimi", "correa", "auto"] + +_ToArrayMaxND = TypeAliasType( + "_ToArrayMaxND", onp.ToArrayND[_PyScalarT, _ScalarT] | _PyScalarT | _ScalarT, type_params=(_ScalarT, _PyScalarT) +) +_ToArrayMax1D = TypeAliasType( + "_ToArrayMax1D", onp.ToArrayStrict1D[_PyScalarT, _ScalarT] | _PyScalarT | _ScalarT, type_params=(_ScalarT, _PyScalarT) +) +_ToArrayMax2D = TypeAliasType( + "_ToArrayMax2D", + onp.ToArrayStrict2D[_PyScalarT, _ScalarT] | _ToArrayMax1D[_ScalarT, _PyScalarT], + type_params=(_ScalarT, _PyScalarT), +) +_ToArrayMax3D = TypeAliasType( + "_ToArrayMax3D", + onp.ToArrayStrict3D[_PyScalarT, _ScalarT] | _ToArrayMax2D[_ScalarT, _PyScalarT], + type_params=(_ScalarT, _PyScalarT), +) + +### + +# NOTE: The (many) [overload-overlap] mypy errors in `entropy` are false positives, so we instead rely on pyright for this. +# mypy: disable-error-code=overload-overlap + +@overload # nd float64 | int, axis=None (positional) -> 0d float64 +def entropy( + pk: _ToArrayMaxND[_AsF64, float], + qk: onp.ToFloat64_ND | onp.ToFloat64 | None, + base: float | None, + axis: None, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.float64: ... +@overload +def entropy( + pk: onp.ToFloat64_ND | onp.ToFloat64, + qk: _ToArrayMaxND[_AsF64, float], + base: float | None, + axis: None, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.float64: ... +@overload # nd float64 | int, axis=None (keyword) -> 0d float64 +def entropy( + pk: _ToArrayMaxND[_AsF64, float], + qk: onp.ToFloat64_ND | onp.ToFloat64 | None = None, + base: float | None = None, + *, + axis: None, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.float64: ... +@overload +def entropy( + pk: onp.ToFloat64_ND | onp.ToFloat64, + qk: _ToArrayMaxND[_AsF64, float], + base: float | None = None, + *, + axis: None, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.float64: ... +@overload # 0d or 1d float64 | int -> 0d float64 +def entropy( + pk: _ToArrayMax1D[_AsF64, float], + qk: onp.ToFloat64Strict1D | onp.ToFloat64 | None = None, + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.float64: ... +@overload +def entropy( + pk: onp.ToFloat64 | onp.ToFloat64Strict1D, + qk: _ToArrayMax1D[_AsF64, float], + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.float64: ... +@overload # 2d float64 | int -> 1d float64 +def entropy( + pk: onp.ToArrayStrict2D[float, _AsF64], + qk: onp.ToFloat64Strict2D | onp.ToFloat64Strict1D | onp.ToFloat64 | None = None, + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array1D[np.float64]: ... +@overload +def entropy( + pk: onp.ToFloat64Strict2D | onp.ToFloat64Strict1D | onp.ToFloat64, + qk: onp.ToArrayStrict2D[float, _AsF64], + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array1D[np.float64]: ... +@overload +def entropy( + pk: _ToArrayMax2D[_AsF64, float], + qk: onp.ToFloat64Strict2D, + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array1D[np.float64]: ... +@overload +def entropy( + pk: onp.ToFloat64Strict2D, + qk: _ToArrayMax2D[_AsF64, float], + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array1D[np.float64]: ... +@overload # 3d float64 | int -> 2d float64 +def entropy( + pk: onp.ToArrayStrict3D[float, _AsF64], + qk: onp.ToFloat64Strict3D | onp.ToFloat64Strict2D | onp.ToFloat64Strict1D | onp.ToFloat64 | None = None, + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array2D[np.float64]: ... +@overload +def entropy( + pk: onp.ToFloat64Strict3D | onp.ToFloat64Strict2D | onp.ToFloat64Strict1D | onp.ToFloat64, + qk: onp.ToArrayStrict3D[float, _AsF64], + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array2D[np.float64]: ... +@overload +def entropy( + pk: _ToArrayMax3D[_AsF64, float], + qk: onp.ToFloat64Strict3D, + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array2D[np.float64]: ... +@overload +def entropy( + pk: onp.ToFloat64Strict3D, + qk: _ToArrayMax3D[_AsF64, float], + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array2D[np.float64]: ... +@overload # Nd float64 | int, keepdims=True -> Nd float64 +def entropy( + pk: _ToArrayMaxND[_AsF64, float], + qk: onp.ToFloat64_ND | onp.ToFloat64 | None = None, + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[True], +) -> onp.ArrayND[np.float64]: ... +@overload +def entropy( + pk: onp.ToFloat64_ND | onp.ToFloat64, + qk: _ToArrayMaxND[_AsF64, float], + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[True], +) -> onp.ArrayND[np.float64]: ... +@overload # Nd float64 | int -> 0d float64 | Nd float64 +def entropy( + pk: _ToArrayMaxND[_AsF64, float], + qk: onp.ToFloat64_ND | onp.ToFloat64 | None = None, + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: bool = False, +) -> np.float64 | onp.ArrayND[np.float64]: ... +@overload +def entropy( + pk: onp.ToFloat64_ND | onp.ToFloat64, + qk: _ToArrayMaxND[_AsF64, float], + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: bool = False, +) -> np.float64 | onp.ArrayND[np.float64]: ... +@overload # Nd float32 | float16, axis=None (positional) -> 0d float32 +def entropy( + pk: _ToArrayMaxND[_AsF32, np.float32], + qk: _ToArrayMaxND[_AsF32, np.float32] | None, + base: float | None, + axis: None, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.float32: ... +@overload # Nd float32 | float16, axis=None (keyword) -> 0d float32 +def entropy( + pk: _ToArrayMaxND[_AsF32, np.float32], + qk: _ToArrayMaxND[_AsF32, np.float32] | None = None, + base: float | None = None, + *, + axis: None, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.float32: ... +@overload # 1d float32 | float16 -> 0d float32 +def entropy( + pk: _ToArrayMax1D[_AsF32, np.float32], + qk: _ToArrayMax1D[_AsF32, np.float32] | None = None, + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.float32: ... +@overload # 2d float32 | float16 -> 1d float32 +def entropy( + pk: onp.ToArrayStrict2D[np.float32, _AsF32], + qk: _ToArrayMax2D[_AsF32, np.float32] | None = None, + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array1D[np.float32]: ... +@overload +def entropy( + pk: _ToArrayMax2D[_AsF32, np.float32], + qk: onp.ToArrayStrict2D[np.float32, _AsF32], + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array1D[np.float32]: ... +@overload # 3d float32 | float16 -> 2d float32 +def entropy( + pk: onp.ToArrayStrict3D[np.float32, _AsF32], + qk: _ToArrayMax3D[_AsF32, np.float32] | None = None, + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array2D[np.float32]: ... +@overload +def entropy( + pk: _ToArrayMax3D[_AsF32, np.float32], + qk: onp.ToArrayStrict3D[np.float32, _AsF32], + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array2D[np.float32]: ... +@overload # Nd float32 | float16, keepdims=True -> Nd float32 +def entropy( + pk: _ToArrayMaxND[_AsF32, np.float32], + qk: _ToArrayMaxND[_AsF32, np.float32] | None = None, + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: Literal[True], +) -> onp.ArrayND[np.float32]: ... +@overload # Nd float32 | float16 -> 0d float32 | Nd float32 +def entropy( + pk: _ToArrayMaxND[_AsF32, np.float32], + qk: _ToArrayMaxND[_AsF32, np.float32] | None = None, + base: float | None = None, + axis: int = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: bool = False, +) -> np.float32 | onp.ArrayND[np.float32]: ... +@overload # fallback def entropy( - pk: onp.ToFloatND, - qk: onp.ToFloatND | None = None, - base: onp.ToFloat | None = None, + pk: onp.ToFloat64 | onp.ToFloat64_ND, + qk: onp.ToFloat64 | onp.ToFloat64_ND | None = None, + base: float | None = None, + axis: int | None = 0, + *, + nan_policy: NanPolicy = "propagate", + keepdims: bool = False, +) -> npc.floating | onp.ArrayND[npc.floating]: ... + +# +@overload # Nd known inexact dtype, axis=None +def differential_entropy( + values: _ToArrayMaxND[_InexactT, _InexactT], + *, + window_length: int | None = None, + base: float | None = None, + axis: None, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> _InexactT: ... +@overload # 0d or 1d known inexact dtype +def differential_entropy( + values: _ToArrayMax1D[_InexactT, _InexactT], + *, + window_length: int | None = None, + base: float | None = None, axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> _InexactT: ... +@overload # 2d known inexact dtype +def differential_entropy( + values: onp.ToArrayStrict2D[_InexactT, _InexactT], + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array1D[_InexactT]: ... +@overload # 2d known inexact dtype +def differential_entropy( + values: onp.ToArrayStrict3D[_InexactT, _InexactT], + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array2D[_InexactT]: ... +@overload # Nd known inexact dtype, keepdims=True +def differential_entropy( + values: onp.ToArrayND[_InexactT, _InexactT], + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[True], +) -> onp.ArrayND[_InexactT]: ... +@overload # Nd known inexact dtype +def differential_entropy( + values: onp.ToArrayND[_InexactT, _InexactT], + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: bool = False, +) -> _InexactT | onp.ArrayND[_InexactT]: ... +@overload # Nd float64 | +integer, axis=None +def differential_entropy( + values: _ToArrayMaxND[_AsF64, float], + *, + window_length: int | None = None, + base: float | None = None, + axis: None, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.float64: ... +@overload # 0d or 1d float64 | +integer +def differential_entropy( + values: _ToArrayMax1D[_AsF64, float], + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.float64: ... +@overload # 2d float64 | +integer +def differential_entropy( + values: onp.ToArrayStrict2D[float, _AsF64], + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array1D[np.float64]: ... +@overload # 3d float64 | +integer +def differential_entropy( + values: onp.ToArrayStrict3D[float, _AsF64], + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array2D[np.float64]: ... +@overload # Nd float64 | +integer, keepdims=True +def differential_entropy( + values: _ToArrayMaxND[_AsF64, float], + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[True], +) -> onp.ArrayND[np.float64]: ... +@overload # Nd float64 | +integer +def differential_entropy( + values: _ToArrayMaxND[_AsF64, float], + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: bool = False, +) -> np.float64 | onp.ArrayND[np.float64]: ... +@overload # Nd ~complex, axis=None +def differential_entropy( + values: onp.ToJustComplex128_ND | onp.ToJustComplex128, + *, + window_length: int | None = None, + base: float | None = None, + axis: None, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.complex128: ... +@overload # 0d or 1d ~complex +def differential_entropy( + values: onp.ToJustComplex128Strict1D | onp.ToJustComplex128, + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> np.complex128: ... +@overload # 2d ~complex +def differential_entropy( + values: onp.ToJustComplex128Strict2D, + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array1D[np.complex128]: ... +@overload # 3d ~complex +def differential_entropy( + values: onp.ToJustComplex128Strict3D, + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[False] = False, +) -> onp.Array2D[np.complex128]: ... +@overload # Nd ~complex, keepdims=True +def differential_entropy( + values: onp.ToJustComplex128_ND | onp.ToJustComplex128, + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[True], +) -> onp.ArrayND[np.complex128]: ... +@overload # Nd ~complex +def differential_entropy( + values: onp.ToJustComplex128_ND | onp.ToJustComplex128, + *, + window_length: int | None = None, + base: float | None = None, + axis: int = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: bool = False, +) -> np.complex128 | onp.ArrayND[np.complex128]: ... +@overload # floating fallback, keepdims=True +def differential_entropy( + values: onp.ToFloatND | onp.ToFloat, + *, + window_length: int | None = None, + base: float | None = None, + axis: int | None = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: Literal[True], +) -> onp.ArrayND[npc.floating]: ... +@overload # floating fallback +def differential_entropy( + values: onp.ToFloatND | onp.ToFloat, + *, + window_length: int | None = None, + base: float | None = None, + axis: int | None = 0, + method: _DifferentialMethod = "auto", + nan_policy: NanPolicy = "propagate", + keepdims: bool = False, +) -> npc.floating | onp.ArrayND[npc.floating]: ... +@overload # inexact fallback, keepdims=True +def differential_entropy( + values: onp.ToComplexND | onp.ToComplex, *, + window_length: int | None = None, + base: float | None = None, + axis: int | None = 0, + method: _DifferentialMethod = "auto", nan_policy: NanPolicy = "propagate", - keepdims: onp.ToBool = False, -) -> float | npc.floating | onp.ArrayND[npc.floating]: ... + keepdims: Literal[True], +) -> onp.ArrayND[npc.inexact]: ... +@overload # inexact fallback def differential_entropy( - values: onp.ToFloatND, + values: onp.ToComplexND | onp.ToComplex, *, - window_length: onp.ToInt | None = None, - base: onp.ToFloat | None = None, - axis: op.CanIndex = 0, - method: Literal["vasicek", "van es", "ebrahimi", "correa", "auto"] = "auto", + window_length: int | None = None, + base: float | None = None, + axis: int | None = 0, + method: _DifferentialMethod = "auto", nan_policy: NanPolicy = "propagate", - keepdims: onp.ToBool = False, -) -> float | npc.floating | onp.ArrayND[npc.floating]: ... + keepdims: bool = False, +) -> npc.inexact | onp.ArrayND[npc.inexact]: ... From 1e7141a089f87f2e624508750b48f5c0ac01060a Mon Sep 17 00:00:00 2001 From: jorenham Date: Thu, 10 Jul 2025 01:07:20 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=85=20`stats`:=20type-tests=20for=20`?= =?UTF-8?q?[differential=5F]entropy`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/stats/test__entropy.pyi | 227 ++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 tests/stats/test__entropy.pyi diff --git a/tests/stats/test__entropy.pyi b/tests/stats/test__entropy.pyi new file mode 100644 index 000000000..4dc568937 --- /dev/null +++ b/tests/stats/test__entropy.pyi @@ -0,0 +1,227 @@ +# type-tests for `stats/_entropy.pyi` + +from typing import assert_type + +import numpy as np +import optype.numpy as onp + +from scipy.stats import differential_entropy, entropy + +i8_0d: np.int8 +i8_1d: onp.Array1D[np.int8] +i8_2d: onp.Array2D[np.int8] +i8_3d: onp.Array3D[np.int8] +i8_nd: onp.ArrayND[np.int8, tuple[int, ...]] + +f16_0d: np.float16 +f16_1d: onp.Array1D[np.float16] +f16_2d: onp.Array2D[np.float16] +f16_3d: onp.Array3D[np.float16] +f16_nd: onp.ArrayND[np.float16, tuple[int, ...]] + +f32_0d: np.float32 +f32_1d: onp.Array1D[np.float32] +f32_2d: onp.Array2D[np.float32] +f32_3d: onp.Array3D[np.float32] +f32_nd: onp.ArrayND[np.float32, tuple[int, ...]] + +f64_0d: np.float64 +f64_1d: onp.Array1D[np.float64] +f64_2d: onp.Array2D[np.float64] +f64_3d: onp.Array3D[np.float64] +f64_nd: onp.ArrayND[np.float64, tuple[int, ...]] + +f80_0d: np.longdouble +f80_1d: onp.Array1D[np.longdouble] +f80_2d: onp.Array2D[np.longdouble] +f80_3d: onp.Array3D[np.longdouble] +f80_nd: onp.ArrayND[np.longdouble, tuple[int, ...]] + +c64_0d: np.complex64 +c64_1d: onp.Array1D[np.complex64] +c64_2d: onp.Array2D[np.complex64] +c64_3d: onp.Array3D[np.complex64] +c64_nd: onp.ArrayND[np.complex64, tuple[int, ...]] + +py_f_0d: float +py_f_1d: list[float] +py_f_2d: list[list[float]] +py_f_3d: list[list[list[float]]] +py_f_nd: list[list[list[list[list[list[float]]]]]] + +py_c_0d: complex +py_c_1d: list[complex] +py_c_2d: list[list[complex]] +py_c_3d: list[list[list[complex]]] +py_c_nd: list[list[list[list[list[list[complex]]]]]] + +### +# entropy + +assert_type(entropy(i8_0d), np.float64) +assert_type(entropy(i8_1d), np.float64) +assert_type(entropy(i8_2d), onp.Array1D[np.float64]) +assert_type(entropy(i8_3d), onp.Array2D[np.float64]) +assert_type(entropy(i8_nd), np.float64 | onp.ArrayND[np.float64]) +assert_type(entropy(i8_nd, keepdims=True), onp.ArrayND[np.float64]) +assert_type(entropy(i8_nd, axis=None), np.float64) +assert_type(entropy(f16_0d), np.float32) +assert_type(entropy(f16_1d), np.float32) +assert_type(entropy(f16_2d), onp.Array1D[np.float32]) +assert_type(entropy(f16_3d), onp.Array2D[np.float32]) +assert_type(entropy(f16_nd), np.float32 | onp.ArrayND[np.float32]) +assert_type(entropy(f16_nd, keepdims=True), onp.ArrayND[np.float32]) +assert_type(entropy(f16_nd, axis=None), np.float32) +assert_type(entropy(f32_0d), np.float32) +assert_type(entropy(f32_1d), np.float32) +assert_type(entropy(f32_2d), onp.Array1D[np.float32]) +assert_type(entropy(f32_3d), onp.Array2D[np.float32]) +assert_type(entropy(f32_nd), np.float32 | onp.ArrayND[np.float32]) +assert_type(entropy(f32_nd, keepdims=True), onp.ArrayND[np.float32]) +assert_type(entropy(f32_nd, axis=None), np.float32) +assert_type(entropy(f64_0d), np.float64) +assert_type(entropy(f64_1d), np.float64) +assert_type(entropy(f64_2d), onp.Array1D[np.float64]) +assert_type(entropy(f64_3d), onp.Array2D[np.float64]) +assert_type(entropy(f64_nd), np.float64 | onp.ArrayND[np.float64]) +assert_type(entropy(f64_nd, keepdims=True), onp.ArrayND[np.float64]) +assert_type(entropy(f64_nd, axis=None), np.float64) +assert_type(entropy(py_f_0d), np.float64) +assert_type(entropy(py_f_1d), np.float64) +assert_type(entropy(py_f_2d), onp.Array1D[np.float64]) +assert_type(entropy(py_f_3d), onp.Array2D[np.float64]) +assert_type(entropy(py_f_nd), np.float64 | onp.ArrayND[np.float64]) +assert_type(entropy(py_f_nd, keepdims=True), onp.ArrayND[np.float64]) +assert_type(entropy(py_f_nd, axis=None), np.float64) + +assert_type(entropy(i8_0d, f16_0d), np.float64) +assert_type(entropy(i8_1d, f16_0d), np.float64) +assert_type(entropy(i8_2d, f16_0d), onp.Array1D[np.float64]) +assert_type(entropy(i8_3d, f16_0d), onp.Array2D[np.float64]) +assert_type(entropy(i8_nd, f16_0d), np.float64 | onp.ArrayND[np.float64]) +assert_type(entropy(i8_nd, f16_0d, keepdims=True), onp.ArrayND[np.float64]) +assert_type(entropy(i8_nd, f16_0d, axis=None), np.float64) +assert_type(entropy(f16_0d, f16_0d), np.float32) +assert_type(entropy(f16_1d, f16_0d), np.float32) +assert_type(entropy(f16_2d, f16_0d), onp.Array1D[np.float32]) +assert_type(entropy(f16_3d, f16_0d), onp.Array2D[np.float32]) +assert_type(entropy(f16_nd, f16_0d), np.float32 | onp.ArrayND[np.float32]) +assert_type(entropy(f16_nd, f16_0d, keepdims=True), onp.ArrayND[np.float32]) +assert_type(entropy(f16_nd, f16_0d, axis=None), np.float32) +assert_type(entropy(f32_0d, f16_0d), np.float32) +assert_type(entropy(f32_1d, f16_0d), np.float32) +assert_type(entropy(f32_2d, f16_0d), onp.Array1D[np.float32]) +assert_type(entropy(f32_3d, f16_0d), onp.Array2D[np.float32]) +assert_type(entropy(f32_nd, f16_0d), np.float32 | onp.ArrayND[np.float32]) +assert_type(entropy(f32_nd, f16_0d, keepdims=True), onp.ArrayND[np.float32]) +assert_type(entropy(f32_nd, f16_0d, axis=None), np.float32) +assert_type(entropy(f64_0d, f16_0d), np.float64) +assert_type(entropy(f64_1d, f16_0d), np.float64) +assert_type(entropy(f64_2d, f16_0d), onp.Array1D[np.float64]) +assert_type(entropy(f64_3d, f16_0d), onp.Array2D[np.float64]) +assert_type(entropy(f64_nd, f16_0d), np.float64 | onp.ArrayND[np.float64]) +assert_type(entropy(f64_nd, f16_0d, keepdims=True), onp.ArrayND[np.float64]) +assert_type(entropy(f64_nd, f16_0d, axis=None), np.float64) +assert_type(entropy(py_f_0d, f16_0d), np.float64) +assert_type(entropy(py_f_1d, f16_0d), np.float64) +assert_type(entropy(py_f_2d, f16_0d), onp.Array1D[np.float64]) +assert_type(entropy(py_f_3d, f16_0d), onp.Array2D[np.float64]) +assert_type(entropy(py_f_nd, f16_0d), np.float64 | onp.ArrayND[np.float64]) +assert_type(entropy(py_f_nd, f16_0d, keepdims=True), onp.ArrayND[np.float64]) +assert_type(entropy(py_f_nd, f16_0d, axis=None), np.float64) + +assert_type(entropy(i8_0d, py_f_0d), np.float64) +assert_type(entropy(i8_1d, py_f_0d), np.float64) +assert_type(entropy(i8_2d, py_f_0d), onp.Array1D[np.float64]) +assert_type(entropy(i8_3d, py_f_0d), onp.Array2D[np.float64]) +assert_type(entropy(i8_nd, py_f_0d), np.float64 | onp.ArrayND[np.float64]) +assert_type(entropy(i8_nd, py_f_0d, keepdims=True), onp.ArrayND[np.float64]) +assert_type(entropy(i8_nd, py_f_0d, axis=None), np.float64) +assert_type(entropy(f16_0d, py_f_0d), np.float64) +assert_type(entropy(f16_1d, py_f_0d), np.float64) +assert_type(entropy(f16_2d, py_f_0d), onp.Array1D[np.float64]) +assert_type(entropy(f16_3d, py_f_0d), onp.Array2D[np.float64]) +assert_type(entropy(f16_nd, py_f_0d), np.float64 | onp.ArrayND[np.float64]) +assert_type(entropy(f16_nd, py_f_0d, keepdims=True), onp.ArrayND[np.float64]) +assert_type(entropy(f16_nd, py_f_0d, axis=None), np.float64) +assert_type(entropy(f32_0d, py_f_0d), np.float64) +assert_type(entropy(f32_1d, py_f_0d), np.float64) +assert_type(entropy(f32_2d, py_f_0d), onp.Array1D[np.float64]) +assert_type(entropy(f32_3d, py_f_0d), onp.Array2D[np.float64]) +assert_type(entropy(f32_nd, py_f_0d), np.float64 | onp.ArrayND[np.float64]) +assert_type(entropy(f32_nd, py_f_0d, keepdims=True), onp.ArrayND[np.float64]) +assert_type(entropy(f32_nd, py_f_0d, axis=None), np.float64) +assert_type(entropy(f64_0d, py_f_0d), np.float64) +assert_type(entropy(f64_1d, py_f_0d), np.float64) +assert_type(entropy(f64_2d, py_f_0d), onp.Array1D[np.float64]) +assert_type(entropy(f64_3d, py_f_0d), onp.Array2D[np.float64]) +assert_type(entropy(f64_nd, py_f_0d), np.float64 | onp.ArrayND[np.float64]) +assert_type(entropy(f64_nd, py_f_0d, keepdims=True), onp.ArrayND[np.float64]) +assert_type(entropy(f64_nd, py_f_0d, axis=None), np.float64) +assert_type(entropy(py_f_0d, py_f_0d), np.float64) +assert_type(entropy(py_f_1d, py_f_0d), np.float64) +assert_type(entropy(py_f_2d, py_f_0d), onp.Array1D[np.float64]) +assert_type(entropy(py_f_3d, py_f_0d), onp.Array2D[np.float64]) +assert_type(entropy(py_f_nd, py_f_0d), np.float64 | onp.ArrayND[np.float64]) +assert_type(entropy(py_f_nd, py_f_0d, keepdims=True), onp.ArrayND[np.float64]) +assert_type(entropy(py_f_nd, py_f_0d, axis=None), np.float64) + +### +# differential_entropy + +assert_type(differential_entropy(i8_0d), np.float64) +assert_type(differential_entropy(i8_1d), np.float64) +assert_type(differential_entropy(i8_2d), onp.Array1D[np.float64]) +assert_type(differential_entropy(i8_3d), onp.Array2D[np.float64]) +assert_type(differential_entropy(i8_nd), np.float64 | onp.ArrayND[np.float64]) +assert_type(differential_entropy(i8_nd, keepdims=True), onp.ArrayND[np.float64]) +assert_type(differential_entropy(i8_nd, axis=None), np.float64) +assert_type(differential_entropy(f16_0d), np.float16) +assert_type(differential_entropy(f16_1d), np.float16) +assert_type(differential_entropy(f16_2d), onp.Array1D[np.float16]) +assert_type(differential_entropy(f16_3d), onp.Array2D[np.float16]) +assert_type(differential_entropy(f16_nd), np.float16 | onp.ArrayND[np.float16]) +assert_type(differential_entropy(f16_nd, keepdims=True), onp.ArrayND[np.float16]) +assert_type(differential_entropy(f16_nd, axis=None), np.float16) +assert_type(differential_entropy(f32_0d), np.float32) +assert_type(differential_entropy(f32_1d), np.float32) +assert_type(differential_entropy(f32_2d), onp.Array1D[np.float32]) +assert_type(differential_entropy(f32_3d), onp.Array2D[np.float32]) +assert_type(differential_entropy(f32_nd), np.float32 | onp.ArrayND[np.float32]) +assert_type(differential_entropy(f32_nd, keepdims=True), onp.ArrayND[np.float32]) +assert_type(differential_entropy(f32_nd, axis=None), np.float32) +assert_type(differential_entropy(f64_0d), np.float64) +assert_type(differential_entropy(f64_1d), np.float64) +assert_type(differential_entropy(f64_2d), onp.Array1D[np.float64]) +assert_type(differential_entropy(f64_3d), onp.Array2D[np.float64]) +assert_type(differential_entropy(f64_nd), np.float64 | onp.ArrayND[np.float64]) +assert_type(differential_entropy(f64_nd, keepdims=True), onp.ArrayND[np.float64]) +assert_type(differential_entropy(f64_nd, axis=None), np.float64) +assert_type(differential_entropy(f80_0d), np.longdouble) +assert_type(differential_entropy(f80_1d), np.longdouble) +assert_type(differential_entropy(f80_2d), onp.Array1D[np.longdouble]) +assert_type(differential_entropy(f80_3d), onp.Array2D[np.longdouble]) +assert_type(differential_entropy(f80_nd), np.longdouble | onp.ArrayND[np.longdouble]) +assert_type(differential_entropy(f80_nd, keepdims=True), onp.ArrayND[np.longdouble]) +assert_type(differential_entropy(f80_nd, axis=None), np.longdouble) +assert_type(differential_entropy(c64_0d), np.complex64) +assert_type(differential_entropy(c64_1d), np.complex64) +assert_type(differential_entropy(c64_2d), onp.Array1D[np.complex64]) +assert_type(differential_entropy(c64_3d), onp.Array2D[np.complex64]) +assert_type(differential_entropy(c64_nd), np.complex64 | onp.ArrayND[np.complex64]) +assert_type(differential_entropy(c64_nd, keepdims=True), onp.ArrayND[np.complex64]) +assert_type(differential_entropy(c64_nd, axis=None), np.complex64) +assert_type(differential_entropy(py_f_0d), np.float64) +assert_type(differential_entropy(py_f_1d), np.float64) +assert_type(differential_entropy(py_f_2d), onp.Array1D[np.float64]) +assert_type(differential_entropy(py_f_3d), onp.Array2D[np.float64]) +assert_type(differential_entropy(py_f_nd), np.float64 | onp.ArrayND[np.float64]) +assert_type(differential_entropy(py_f_nd, keepdims=True), onp.ArrayND[np.float64]) +assert_type(differential_entropy(py_f_nd, axis=None), np.float64) +assert_type(differential_entropy(py_c_0d), np.complex128) +assert_type(differential_entropy(py_c_1d), np.complex128) +assert_type(differential_entropy(py_c_2d), onp.Array1D[np.complex128]) +assert_type(differential_entropy(py_c_3d), onp.Array2D[np.complex128]) +assert_type(differential_entropy(py_c_nd), np.complex128 | onp.ArrayND[np.complex128]) +assert_type(differential_entropy(py_c_nd, keepdims=True), onp.ArrayND[np.complex128]) +assert_type(differential_entropy(py_c_nd, axis=None), np.complex128)