diff --git a/scipy-stubs/optimize/_shgo_lib/_complex.pyi b/scipy-stubs/optimize/_shgo_lib/_complex.pyi index e25bed5b..9d254a70 100644 --- a/scipy-stubs/optimize/_shgo_lib/_complex.pyi +++ b/scipy-stubs/optimize/_shgo_lib/_complex.pyi @@ -1,97 +1,104 @@ -from collections.abc import Generator, Sequence -from typing import Any, TypeAlias +from collections.abc import Callable, Generator, Sequence +from typing import Any, Concatenate, Final, Generic, TypeAlias +from typing_extensions import TypeVar import numpy as np import optype as op import optype.numpy as onp -from scipy._typing import Untyped, UntypedCallable, UntypedTuple +from scipy.optimize._typing import Constraints from ._vertex import VertexBase, VertexCacheBase -_Location: TypeAlias = Sequence[float] -_Bounds: TypeAlias = Sequence[tuple[float, float]] -_Constraints: TypeAlias = dict[str, object] | Sequence[dict[str, object]] # TODO: TypedDict -_Symmetry: TypeAlias = op.CanGetitem[int, op.CanIndex] -_CyclicProduct: TypeAlias = Generator[tuple[float, ...], None, tuple[float, ...]] +_Floats: TypeAlias = onp.ToFloat +_Float1D: TypeAlias = onp.Array1D[np.float64] +_FloatingND: TypeAlias = onp.ArrayND[np.floating[Any] | np.integer[Any]] + +_Fun0D: TypeAlias = Callable[Concatenate[_Float1D, ...], onp.ToFloat] +_Fun1D: TypeAlias = Callable[Concatenate[_Float1D, ...], onp.ToFloat1D] + +_Location: TypeAlias = _FloatingND | Sequence[float] +_Bounds: TypeAlias = _FloatingND | Sequence[tuple[onp.ToFloat, onp.ToFloat]] +_Symmetry: TypeAlias = onp.ArrayND[np.integer[Any]] | op.CanGetitem[int, op.CanIndex] + +_HT = TypeVar("_HT", bound=VertexCacheBase, default=VertexCacheBase) + +### + +class Complex(Generic[_HT]): # undocumented + dim: Final[int] + domain: Final[_Bounds] + bounds: Final[_Bounds] + symmetry: Final[_Symmetry] + sfield: _Fun0D + sfield_args: tuple[object, ...] + min_cons: Constraints # only set if `constraints` is not None + g_cons: Final[Sequence[_Fun1D]] + g_args: Final[tuple[object, ...]] -class Complex: - dim: int - domain: _Bounds - bounds: _Bounds - symmetry: _Symmetry - sfield: UntypedCallable - sfield_args: UntypedTuple - min_cons: _Constraints # only set if `constraints` is not None - g_cons: UntypedTuple | None - g_args: UntypedTuple | None gen: int perm_cycle: int - H: list[Untyped] - V: VertexCacheBase - V_non_symm: list[VertexBase] + H: list[_HT] # readonly + V: Final[VertexCacheBase] + V_non_symm: Final[list[VertexBase]] origin: list[float] supremum: list[float] - cp: _CyclicProduct - triangulated_vectors: list[tuple[tuple[float, ...], tuple[float, ...]]] - rls: Untyped + triangulated_vectors: list[tuple[_Floats, _Floats]] + + cp: Generator[_Floats, None, _Floats] + rls: Generator[VertexBase | _Floats] + def __init__( self, /, dim: int, domain: _Bounds | None = None, - sfield: UntypedCallable | None = None, - sfield_args: UntypedTuple = (), + sfield: _Fun0D | None = None, + sfield_args: tuple[object, ...] = (), symmetry: _Symmetry | None = None, - constraints: _Constraints | None = None, + constraints: Constraints | None = None, workers: int = 1, ) -> None: ... - def __call__(self, /) -> Untyped: ... + def __call__(self, /) -> list[_HT]: ... def cyclic_product( self, /, bounds: _Bounds, origin: _Location, supremum: _Location, - centroid: bool = True, - ) -> _CyclicProduct: ... + centroid: onp.ToFloat = True, + ) -> Generator[_Floats, None, _Floats]: ... def triangulate( self, /, n: int | None = None, symmetry: _Symmetry | None = None, - centroid: bool = True, - printout: bool = False, + centroid: onp.ToFloat = True, + printout: onp.ToFloat = False, ) -> None: ... def refine(self, /, n: int = 1) -> None: ... - def refine_all(self, /, centroids: bool = True) -> None: ... + def refine_all(self, /, centroids: onp.ToBool = True) -> None: ... def refine_local_space( self, /, origin: _Location, supremum: _Location, bounds: _Bounds, - centroid: int = 1, - ) -> Generator[VertexBase | tuple[float, ...], None, None]: ... + centroid: onp.ToBool = 1, + ) -> Generator[VertexBase | _Floats]: ... def refine_star(self, /, v: VertexBase) -> None: ... def split_edge(self, /, v1: VertexBase, v2: VertexBase) -> VertexBase: ... def vpool(self, /, origin: _Location, supremum: _Location) -> set[VertexBase]: ... - def vf_to_vv(self, /, vertices: Sequence[VertexBase], simplices: Sequence[Untyped]) -> None: ... + def vf_to_vv( + self, + /, + vertices: Sequence[VertexBase], + simplices: Sequence[tuple[onp.ToFloat1D, onp.ToFloat1D]], + ) -> None: ... def connect_vertex_non_symm( self, /, - v_x: tuple[float | np.floating[Any]] | onp.Array1D[np.floating[Any]], + v_x: onp.ToFloat1D, near: set[VertexBase] | list[VertexBase] | None = None, ) -> bool | None: ... - def in_simplex( - self, - /, - S: onp.ToFloat1D, - v_x: onp.Array1D[np.floating[Any]], - A_j0: onp.ArrayND[np.floating[Any]] | None = None, - ) -> Untyped: ... - def deg_simplex( - self, - /, - S: onp.ArrayND[np.floating[Any]], - proj: onp.ArrayND[np.floating[Any]] | None = None, - ) -> Untyped: ... + def in_simplex(self, /, S: onp.ToFloat1D, v_x: onp.ToFloat1D, A_j0: _FloatingND | None = None) -> bool: ... + def deg_simplex(self, /, S: _FloatingND, proj: _FloatingND | None = None) -> bool: ... diff --git a/scipy-stubs/optimize/_shgo_lib/_vertex.pyi b/scipy-stubs/optimize/_shgo_lib/_vertex.pyi index 1b7ba258..9e6e8c9d 100644 --- a/scipy-stubs/optimize/_shgo_lib/_vertex.pyi +++ b/scipy-stubs/optimize/_shgo_lib/_vertex.pyi @@ -1,135 +1,126 @@ import abc from collections import OrderedDict from collections.abc import Callable, Iterable, Iterator, Sequence -from typing import Any, Final, Generic, TypeAlias -from typing_extensions import Self, TypeVar, override +from typing import Concatenate, Final, Generic, TypeAlias, type_check_only +from typing_extensions import TypeVar import numpy as np import optype.numpy as onp -from scipy._lib._util import MapWrapper as MapWrapper -from scipy._typing import Untyped, UntypedTuple -_SCT = TypeVar("_SCT", bound=np.number[Any], default=np.floating[Any]) -_SCT_co = TypeVar("_SCT_co", bound=np.number[Any], covariant=True, default=np.floating[Any]) +_VT_co = TypeVar("_VT_co", bound=VertexBase, default=VertexBase, covariant=True) -_Vector: TypeAlias = onp.Array1D[_SCT] -_VectorLike: TypeAlias = tuple[float | _SCT, ...] | _Vector[_SCT] +_Float1D: TypeAlias = onp.Array1D[np.float64] +_Fun0D: TypeAlias = Callable[Concatenate[_Float1D, ...], onp.ToFloat] +_Fun1D: TypeAlias = Callable[Concatenate[_Float1D, ...], onp.ToFloat1D] -_ScalarField: TypeAlias = Callable[[_Vector[_SCT]], float | _SCT] -_VectorField: TypeAlias = Callable[[_Vector[_SCT]], _Vector[_SCT]] -_ScalarFieldCons: TypeAlias = Callable[[_Vector[_SCT]], Untyped] # TODO +@type_check_only +class _VertexMixin: + def connect(self, /, v: VertexBase) -> None: ... + def disconnect(self, /, v: VertexBase) -> None: ... -class VertexBase(Generic[_SCT_co], metaclass=abc.ABCMeta): - x: _VectorLike[_SCT_co] - x_a: _Vector[_SCT_co] # lazy +### + +class VertexBase(abc.ABC): + x: onp.ToFloat1D + x_a: _Float1D # lazy hash: Final[int] index: Final[int | None] - nn: set[Self] - - st: set[Self] # might not be set + nn: set[VertexBase] + st: set[VertexBase] # might not be set feasible: bool # might not be set - def __init__(self, /, x: _VectorLike[_SCT_co], nn: Iterable[Self] | None = None, index: int | None = None) -> None: ... + def __init__(self, /, x: onp.ToFloat1D, nn: Iterable[VertexBase] | None = None, index: int | None = None) -> None: ... @abc.abstractmethod - def connect(self, /, v: Self) -> None: ... + def connect(self, /, v: VertexBase) -> None: ... @abc.abstractmethod - def disconnect(self, /, v: Self) -> None: ... - def star(self, /) -> set[Self]: ... + def disconnect(self, /, v: VertexBase) -> None: ... + def star(self, /) -> set[VertexBase]: ... -class VertexScalarField(VertexBase[_SCT_co], Generic[_SCT_co]): +class VertexScalarField(_VertexMixin, VertexBase): check_min: bool check_max: bool - # TODO: Support non-empty `field_args` and `g_cons_args` + def __init__( self, /, - x: _VectorLike[_SCT_co], - field: _ScalarField[_SCT_co] | None = None, - nn: Iterable[Self] | None = None, + x: onp.ToFloat1D, + field: _Fun0D | None = None, + nn: Iterable[VertexBase] | None = None, index: int | None = None, - field_args: tuple[()] = (), - g_cons: _ScalarFieldCons[_SCT_co] | None = None, - g_cons_args: tuple[()] = (), + field_args: tuple[object, ...] = (), + g_cons: _Fun1D | None = None, + g_cons_args: tuple[object, ...] = (), ) -> None: ... - @override - def connect(self, /, v: Self) -> None: ... - @override - def disconnect(self, /, v: Self) -> None: ... + # def minimiser(self, /) -> bool: ... def maximiser(self, /) -> bool: ... -class VertexVectorField(VertexBase[_SCT_co], Generic[_SCT_co], metaclass=abc.ABCMeta): +class VertexVectorField(_VertexMixin, VertexBase): # NOTE: The implementaiton is a WIP - # TODO: Support non-empty `field_args`, `vfield_args`, and `g_cons_args` def __init__( self, /, - x: _VectorLike[_SCT_co], - sfield: _ScalarField[_SCT_co] | None = None, - vfield: _VectorField[_SCT_co] | None = None, - field_args: tuple[()] = (), - vfield_args: tuple[()] = (), - g_cons: _ScalarFieldCons[_SCT_co] | None = None, - g_cons_args: tuple[()] = (), - nn: Iterable[Self] | None = None, + x: onp.ToFloat1D, + sfield: _Fun0D | None = None, + vfield: _Fun1D | None = None, + field_args: tuple[object, ...] = (), + vfield_args: tuple[object, ...] = (), + g_cons: _Fun1D | None = None, + g_cons_args: tuple[object, ...] = (), + nn: Iterable[VertexBase] | None = None, index: int | None = None, ) -> None: ... - @override - def connect(self, /, v: Self) -> None: ... - @override - def disconnect(self, /, v: Self) -> None: ... - -class VertexCube(VertexBase[_SCT_co], Generic[_SCT_co]): - def __init__(self, /, x: _VectorLike[_SCT_co], nn: Iterable[Self] | None = None, index: int | None = None) -> None: ... - @override - def connect(self, /, v: Self) -> None: ... - @override - def disconnect(self, /, v: Self) -> None: ... - -_KT = TypeVar("_KT", default=Untyped) # TODO: Select a decent default -_VT = TypeVar("_VT", bound=VertexBase, default=VertexBase) - -class VertexCacheBase(Generic[_KT, _VT]): - cache: OrderedDict[_KT, _VT] + +class VertexCube(_VertexMixin, VertexBase): + def __init__(self, /, x: onp.ToFloat1D, nn: Iterable[VertexBase] | None = None, index: int | None = None) -> None: ... + +class VertexCacheBase(Generic[_VT_co]): + cache: OrderedDict[onp.ToFloat1D, _VT_co] nfev: int index: int + def __init__(self, /) -> None: ... - def __iter__(self, /) -> Iterator[_VT]: ... + def __iter__(self, /) -> Iterator[_VT_co]: ... def size(self, /) -> int: ... def print_out(self, /) -> None: ... -class VertexCacheIndex(VertexCacheBase[_KT, _VT], Generic[_KT, _VT]): - Vertex: type[_VT] - def __getitem__(self, x: _KT, /, nn: None = None) -> _VT: ... +class VertexCacheIndex(VertexCacheBase[VertexCube]): + Vertex: Final[type[VertexCube]] + + def __getitem__(self, x: onp.ToFloat1D, /, nn: None = None) -> VertexCube: ... -class VertexCacheField(VertexCacheBase[_KT, _VT], Generic[_KT, _VT, _SCT_co]): +class VertexCacheField(VertexCacheBase[VertexScalarField]): + Vertex: Final[type[VertexScalarField]] + + field: Final[_Fun0D] + field_args: Final[tuple[object, ...]] + wfield: Final[FieldWrapper] + fpool: Final[set[VertexScalarField]] + process_fpool: Final[Callable[[], None]] + + g_cons: Final[Sequence[_Fun1D]] + g_cons_args: Final[tuple[object, ...]] + wgcons: Final[ConstraintWrapper] + gpool: Final[set[VertexScalarField]] + process_gpool: Final[Callable[[], None]] + + workers: Final[int] index: int - Vertex: type[_VT] - field: _ScalarField[_SCT_co] - field_args: tuple[()] - wfield: FieldWrapper[_SCT_co] - g_cons: Sequence[_ScalarFieldCons[_SCT_co]] - g_cons_args: tuple[()] - wgcons: ConstraintWrapper[_SCT_co] - gpool: set[UntypedTuple] - fpool: set[UntypedTuple] sfc_lock: bool - workers: int - process_gpool: Callable[[], None] - process_fpool: Callable[[], None] + def __init__( self, /, - field: Untyped | None = None, - field_args: tuple[()] = (), - g_cons: Sequence[_ScalarFieldCons[_SCT_co]] | None = None, - g_cons_args: tuple[()] = (), + field: _Fun0D | _Fun1D | None = None, + field_args: tuple[object, ...] = (), + g_cons: Sequence[_Fun1D] | None = None, + g_cons_args: tuple[object, ...] = (), workers: int = 1, ) -> None: ... - def __getitem__(self, x: _KT, /, nn: Iterable[_VT] | None = None) -> _VT: ... + def __getitem__(self, x: onp.ToFloat1D, /, nn: Iterable[VertexBase] | None = None) -> VertexScalarField: ... def process_pools(self, /) -> None: ... - def feasibility_check(self, /, v: _VT) -> bool: ... - def compute_sfield(self, /, v: _VT) -> None: ... + def feasibility_check(self, /, v: VertexBase) -> bool: ... + def compute_sfield(self, /, v: VertexBase) -> None: ... def proc_gpool(self, /) -> None: ... def pproc_gpool(self, /) -> None: ... def proc_fpool_g(self, /) -> None: ... @@ -138,15 +129,16 @@ class VertexCacheField(VertexCacheBase[_KT, _VT], Generic[_KT, _VT, _SCT_co]): def pproc_fpool_nog(self, /) -> None: ... def proc_minimisers(self, /) -> None: ... -class ConstraintWrapper(Generic[_SCT]): - g_cons: Sequence[_ScalarFieldCons[_SCT]] - g_cons_args: Sequence[UntypedTuple] - def __init__(self, /, g_cons: Sequence[_ScalarFieldCons[_SCT]], g_cons_args: Sequence[UntypedTuple]) -> None: ... - def gcons(self, /, v_x_a: _Vector[_SCT]) -> bool: ... - -class FieldWrapper(Generic[_SCT]): - # TODO: Support non-empty `g_cons_args` - field: _ScalarField[_SCT] | _VectorField[_SCT] - field_args: tuple[()] - def __init__(self, /, field: _ScalarField[_SCT] | _VectorField[_SCT], field_args: tuple[()]) -> None: ... - def func(self, /, v_x_a: _Vector[_SCT]) -> _SCT: ... +class ConstraintWrapper: + g_cons: Sequence[_Fun1D] + g_cons_args: Sequence[tuple[object, ...]] + + def __init__(self, /, g_cons: Sequence[_Fun1D], g_cons_args: Sequence[tuple[object, ...]]) -> None: ... + def gcons(self, /, v_x_a: _Float1D) -> bool: ... + +class FieldWrapper: + field: _Fun0D | _Fun1D + field_args: tuple[object, ...] + + def __init__(self, /, field: _Fun0D | _Fun1D, field_args: tuple[object, ...]) -> None: ... + def func(self, /, v_x_a: _Float1D) -> onp.ToFloat | onp.ToFloat1D: ...