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

optimize: complete _shgo_lib (private) #228

Merged
merged 2 commits into from
Nov 29, 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
107 changes: 57 additions & 50 deletions scipy-stubs/optimize/_shgo_lib/_complex.pyi
Original file line number Diff line number Diff line change
@@ -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: ...
184 changes: 88 additions & 96 deletions scipy-stubs/optimize/_shgo_lib/_vertex.pyi
Original file line number Diff line number Diff line change
@@ -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: ...
Expand All @@ -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: ...