Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optype 0.7 #185

Merged
merged 3 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 2 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ packages = [{include = "scipy-stubs"}]
classifiers = [
"Development Status :: 4 - Beta",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Typing :: Stubs Only",
"Typing :: Typed",
]
Expand All @@ -32,8 +28,8 @@ Funding = "https://github.com/sponsors/jorenham"
scipy = ["scipy"]

[tool.poetry.dependencies]
python = "^3.10.1"
optype = "^0.6.1"
python = "^3.10"
optype = "^0.7.1"
scipy = {version = ">=1.10", optional = true}

[tool.poetry.group.dev.dependencies]
Expand Down
18 changes: 9 additions & 9 deletions scipy-stubs/_lib/_finite_differences.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@ from typing_extensions import TypeVar

import numpy as np
import numpy.typing as npt
from scipy._typing import AnyInt, AnyReal
import optype.numpy as onp

_T = TypeVar("_T", bound=np.floating[Any] | npt.NDArray[np.floating[Any]])

@overload
def _derivative(
func: Callable[Concatenate[float, ...], AnyReal],
func: Callable[Concatenate[float, ...], onp.ToFloat],
x0: float,
dx: AnyReal = 1.0,
n: AnyInt = 1,
dx: onp.ToFloat = 1.0,
n: onp.ToInt = 1,
args: tuple[object, ...] = (),
order: AnyInt = 3,
order: onp.ToInt = 3,
) -> np.float64: ...
@overload
def _derivative(
func: Callable[Concatenate[_T, ...], AnyReal],
func: Callable[Concatenate[_T, ...], onp.ToFloat],
x0: _T,
dx: AnyReal = 1.0,
n: AnyInt = 1,
dx: onp.ToFloat = 1.0,
n: onp.ToInt = 1,
args: tuple[object, ...] = (),
order: AnyInt = 3,
order: onp.ToInt = 3,
) -> _T: ...
14 changes: 0 additions & 14 deletions scipy-stubs/_typing.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@ __all__ = [
"RNG",
"Alternative",
"AnyBool",
"AnyChar",
"AnyComplex",
"AnyInt",
"AnyReal",
"AnyScalar",
"AnyShape",
"Array0D",
"ByteOrder",
"Casting",
"CorrelateMode",
Expand Down Expand Up @@ -68,16 +62,8 @@ FileLike: TypeAlias = IO[_ByteSOrStr] | FileName
FileModeRW: TypeAlias = Literal["r", "w"]
FileModeRWA: TypeAlias = Literal[FileModeRW, "a"]

_SCT = TypeVar("_SCT", bound=np.generic, default=np.generic)
Array0D: TypeAlias = np.ndarray[tuple[()], np.dtype[_SCT]]

# keep in sync with `numpy._typing._scalars`
AnyBool: TypeAlias = bool | np.bool_ | Literal[0, 1]
AnyInt: TypeAlias = int | np.integer[Any] | np.bool_
AnyReal: TypeAlias = int | float | np.floating[Any] | np.integer[Any] | np.bool_
AnyComplex: TypeAlias = int | float | complex | np.number[Any] | np.bool_
AnyChar: TypeAlias = str | bytes # `np.str_ <: builtins.str` and `np.bytes_ <: builtins.bytes`
AnyScalar: TypeAlias = int | float | complex | AnyChar | np.generic

# equivalent to `numpy._typing._shape._ShapeLike`
AnyShape: TypeAlias = op.CanIndex | Sequence[op.CanIndex]
Expand Down
92 changes: 44 additions & 48 deletions scipy-stubs/cluster/hierarchy.pyi
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from collections.abc import Callable, Sequence
from collections.abc import Callable
from types import ModuleType
from typing import Any, Literal, TypeAlias, TypedDict, overload
from typing_extensions import TypeVar, override

import numpy as np
import numpy.typing as npt
import optype.numpy as onp
from scipy._lib._disjoint_set import DisjointSet
from scipy.spatial.distance import _MetricCallback, _MetricKind
Expand Down Expand Up @@ -47,7 +46,7 @@ __all__ = [
_T = TypeVar("_T")
_SCT = TypeVar("_SCT", bound=np.number[Any], default=np.float64)
_LinkageMethod: TypeAlias = Literal["single", "complete", "average", "weighted", "centroid", "median", "ward"]
_LinkageArray: TypeAlias = onp.Array[tuple[int, int], _SCT]
_LinkageArray: TypeAlias = onp.Array2D[_SCT]
_ClusterCriterion: TypeAlias = Literal["inconsistent", "distance", "maxclust", "monocrit", "maxclust_monocrit"]
_SortOrder: TypeAlias = Literal["ascending", "descending"]

Expand All @@ -64,16 +63,16 @@ class _DendrogramResult(TypedDict):

class ClusterWarning(UserWarning): ...

def int_floor(arr: onp.AnyArray, xp: ModuleType) -> int: ...
def single(y: onp.AnyArray) -> _LinkageArray: ...
def complete(y: onp.AnyArray) -> _LinkageArray: ...
def average(y: onp.AnyArray) -> _LinkageArray: ...
def weighted(y: onp.AnyArray) -> _LinkageArray: ...
def centroid(y: onp.AnyArray) -> _LinkageArray: ...
def median(y: onp.AnyArray) -> _LinkageArray: ...
def ward(y: onp.AnyArray) -> _LinkageArray: ...
def int_floor(arr: onp.ToArrayND, xp: ModuleType) -> int: ...
def single(y: onp.ToArrayND) -> _LinkageArray: ...
def complete(y: onp.ToArrayND) -> _LinkageArray: ...
def average(y: onp.ToArrayND) -> _LinkageArray: ...
def weighted(y: onp.ToArrayND) -> _LinkageArray: ...
def centroid(y: onp.ToArrayND) -> _LinkageArray: ...
def median(y: onp.ToArrayND) -> _LinkageArray: ...
def ward(y: onp.ToArrayND) -> _LinkageArray: ...
def linkage(
y: onp.AnyArray,
y: onp.ToArrayND,
method: _LinkageMethod = "single",
metric: _MetricKind | _MetricCallback = "euclidean",
optimal_ordering: bool = False,
Expand Down Expand Up @@ -109,61 +108,58 @@ class ClusterNode:
def pre_order(self, /, func: Callable[[ClusterNode], _T]) -> list[_T]: ...

def cut_tree(
Z: onp.AnyArray,
n_clusters: Sequence[int] | npt.NDArray[np.integer[Any]] | None = None,
height: Sequence[float] | npt.NDArray[np.integer[Any] | np.floating[Any]] | None = None,
) -> onp.Array[tuple[int, int], np.int64]: ...
Z: onp.ToArray2D,
n_clusters: onp.ToInt1D | None = None,
height: onp.ToFloat1D | None = None,
) -> onp.Array2D[np.int64]: ...
@overload
def to_tree(Z: onp.AnyArray, rd: Literal[False] = False) -> ClusterNode: ...
def to_tree(Z: onp.ToArray2D, rd: Literal[False] = False) -> ClusterNode: ...
@overload
def to_tree(Z: onp.AnyArray, rd: Literal[True]) -> tuple[ClusterNode, list[ClusterNode]]: ...
def to_tree(Z: onp.ToArray2D, rd: Literal[True]) -> tuple[ClusterNode, list[ClusterNode]]: ...
def optimal_leaf_ordering(
Z: onp.AnyArray,
y: onp.AnyArray,
Z: onp.ToArray2D,
y: onp.ToArrayND,
metric: _MetricKind | _MetricCallback = "euclidean",
) -> _LinkageArray: ...
@overload
def cophenet(Z: onp.AnyArray, Y: None = None) -> onp.Array[tuple[int], np.float64]: ...
def cophenet(Z: onp.ToArray2D, Y: None = None) -> onp.Array1D[np.float64]: ...
@overload
def cophenet(
Z: onp.AnyArray,
Y: onp.AnyArray,
) -> tuple[onp.Array[tuple[int], np.float64], onp.Array[tuple[int], np.float64]]: ...
def inconsistent(Z: onp.AnyArray, d: int = 2) -> _LinkageArray: ...
def from_mlab_linkage(Z: onp.AnyArray) -> _LinkageArray: ...
def to_mlab_linkage(Z: onp.AnyArray) -> _LinkageArray: ...
def is_monotonic(Z: onp.AnyArray) -> bool: ...
def is_valid_im(R: onp.AnyArray, warning: bool = False, throw: bool = False, name: str | None = None) -> bool: ...
def is_valid_linkage(Z: onp.AnyArray, warning: bool = False, throw: bool = False, name: str | None = None) -> bool: ...
def num_obs_linkage(Z: onp.AnyArray) -> int: ...
def correspond(Z: onp.AnyArray, Y: onp.AnyArray) -> bool: ...
def cophenet(Z: onp.ToArray2D, Y: onp.ToArrayND) -> tuple[onp.Array1D[np.float64], onp.Array1D[np.float64]]: ...
def inconsistent(Z: onp.ToArray2D, d: int = 2) -> _LinkageArray: ...
def from_mlab_linkage(Z: onp.ToArray2D) -> _LinkageArray: ...
def to_mlab_linkage(Z: onp.ToArray2D) -> _LinkageArray: ...
def is_monotonic(Z: onp.ToArray2D) -> bool: ...
def is_valid_im(R: onp.ToArrayND, warning: bool = False, throw: bool = False, name: str | None = None) -> bool: ...
def is_valid_linkage(Z: onp.ToArray2D, warning: bool = False, throw: bool = False, name: str | None = None) -> bool: ...
def num_obs_linkage(Z: onp.ToArray2D) -> int: ...
def correspond(Z: onp.ToArray2D, Y: onp.ToArrayND) -> bool: ...
def fcluster(
Z: onp.AnyArray,
Z: onp.ToArray2D,
t: float | np.floating[Any] | np.integer[Any],
criterion: _ClusterCriterion = "inconsistent",
depth: int = 2,
R: onp.AnyArray | None = None,
monocrit: onp.AnyArray | None = None,
) -> onp.Array[tuple[int], np.int32]: ...
R: onp.ToArrayND | None = None,
monocrit: onp.ToArrayND | None = None,
) -> onp.Array1D[np.int32]: ...
def fclusterdata(
X: onp.AnyArray,
X: onp.ToArrayND,
t: float | np.floating[Any] | np.integer[Any],
criterion: _ClusterCriterion = "inconsistent",
metric: _MetricKind | _MetricCallback = "euclidean",
depth: int = 2,
method: _LinkageMethod = "single",
R: onp.AnyArray | None = None,
) -> onp.Array[tuple[int], np.int32]: ...
def leaves_list(Z: onp.AnyArray) -> onp.Array[tuple[int], np.int32]: ...
R: onp.ToArrayND | None = None,
) -> onp.Array1D[np.int32]: ...
def leaves_list(Z: onp.ToArray2D) -> onp.Array1D[np.int32]: ...
def set_link_color_palette(palette: list[str] | tuple[str, ...] | None) -> None: ...
def dendrogram(
Z: onp.AnyArray,
Z: onp.ToArray2D,
p: int = 30,
truncate_mode: Literal["lastp", "level"] | None = None,
color_threshold: float | np.floating[Any] | None = None,
get_leaves: bool = True,
orientation: Literal["top", "bottom", "left", "right"] = "top",
labels: onp.AnyArray | None = None,
labels: onp.ToArrayND | None = None,
count_sort: _SortOrder | bool = False,
distance_sort: _SortOrder | bool = False,
show_leaf_counts: bool = True,
Expand All @@ -177,8 +173,8 @@ def dendrogram(
ax: _MatplotlibAxes | None = None,
above_threshold_color: str = "C0",
) -> _DendrogramResult: ...
def is_isomorphic(T1: onp.AnyArray, T2: onp.AnyArray) -> bool: ...
def maxdists(Z: onp.AnyArray) -> onp.Array[tuple[int], np.float64]: ...
def maxinconsts(Z: onp.AnyArray, R: onp.AnyArray) -> onp.Array[tuple[int], np.float64]: ...
def maxRstat(Z: onp.AnyArray, R: onp.AnyArray, i: int) -> onp.Array[tuple[int], np.float64]: ...
def leaders(Z: onp.AnyArray, T: onp.AnyArray) -> tuple[onp.Array[tuple[int], np.int32], onp.Array[tuple[int], np.int32]]: ...
def is_isomorphic(T1: onp.ToArrayND, T2: onp.ToArrayND) -> bool: ...
def maxdists(Z: onp.ToArray2D) -> onp.Array1D[np.float64]: ...
def maxinconsts(Z: onp.ToArray2D, R: onp.ToArrayND) -> onp.Array1D[np.float64]: ...
def maxRstat(Z: onp.ToArray2D, R: onp.ToArrayND, i: int) -> onp.Array1D[np.float64]: ...
def leaders(Z: onp.ToArray2D, T: onp.ToArrayND) -> tuple[onp.Array1D[np.int32], onp.Array1D[np.int32]]: ...
40 changes: 22 additions & 18 deletions scipy-stubs/cluster/vq.pyi
Original file line number Diff line number Diff line change
@@ -1,50 +1,54 @@
from collections.abc import Sequence
from typing import Any, Literal, TypeAlias, overload
from typing import Any, Literal, overload
from typing_extensions import TypeVar

import numpy as np
import numpy.typing as npt
import optype.numpy as onp
from scipy._typing import Seed

__all__ = ["kmeans", "kmeans2", "vq", "whiten"]

_SCT_fc = TypeVar("_SCT_fc", bound=np.inexact[Any])
_ArrayLike_1d_fc: TypeAlias = onp.AnyNumberArray | Sequence[complex | np.number[Any]]
_ArrayLike_2d_fc: TypeAlias = onp.AnyNumberArray | Sequence[Sequence[complex | np.number[Any]]]

###

class ClusterError(Exception): ...

@overload
def whiten(obs: npt.NDArray[_SCT_fc], check_finite: bool = True) -> onp.Array[tuple[int, int], _SCT_fc]: ...
def whiten(obs: npt.NDArray[_SCT_fc], check_finite: bool = True) -> onp.Array2D[_SCT_fc]: ...
@overload
def whiten(obs: _ArrayLike_2d_fc, check_finite: bool = True) -> onp.Array[tuple[int, int], np.inexact[Any]]: ...
def whiten(obs: onp.ToComplex2D, check_finite: bool = True) -> onp.Array2D[np.inexact[Any]]: ...

#
def vq(
obs: _ArrayLike_2d_fc,
code_book: _ArrayLike_2d_fc,
obs: onp.ToComplex2D,
code_book: onp.ToComplex2D,
check_finite: bool = True,
) -> tuple[onp.Array[tuple[int], np.int32 | np.intp], onp.Array[tuple[int], _SCT_fc]]: ...
) -> tuple[onp.Array1D[np.int32 | np.intp], onp.Array1D[_SCT_fc]]: ...
def py_vq(
obs: _ArrayLike_2d_fc,
code_book: _ArrayLike_2d_fc,
obs: onp.ToComplex2D,
code_book: onp.ToComplex2D,
check_finite: bool = True,
) -> tuple[onp.Array[tuple[int], np.intp], onp.Array[tuple[int], _SCT_fc]]: ...
) -> tuple[onp.Array1D[np.intp], onp.Array1D[_SCT_fc]]: ...

#
def kmeans(
obs: _ArrayLike_2d_fc,
obs: onp.ToComplex2D,
k_or_guess: npt.ArrayLike,
iter: int = 20,
thresh: float = 1e-05,
check_finite: bool = True,
*,
seed: int | np.random.Generator | np.random.RandomState | None = None,
) -> tuple[onp.Array[tuple[int, int], np.inexact[Any]], float]: ...
seed: Seed | None = None,
) -> tuple[onp.Array2D[np.inexact[Any]], float]: ...
def kmeans2(
data: _ArrayLike_1d_fc | _ArrayLike_2d_fc,
data: onp.ToComplex1D | onp.ToComplex2D,
k: npt.ArrayLike,
iter: int = 10,
thresh: float = 1e-05,
minit: Literal["random", "points", "++", "matrix"] = "random",
missing: Literal["warn", "raise"] = "warn",
check_finite: bool = True,
*,
seed: int | np.random.Generator | np.random.RandomState | None = None,
) -> tuple[onp.Array[tuple[int, int], np.inexact[Any]], onp.Array[tuple[int], np.int32]]: ...
seed: Seed | None = None,
) -> tuple[onp.Array2D[np.inexact[Any]], onp.Array1D[np.int32]]: ...
Loading