Skip to content

Commit e116f8d

Browse files
authored
signal: complete _ltisys.* (#385)
2 parents 5ffe837 + 960fb36 commit e116f8d

File tree

4 files changed

+601
-133
lines changed

4 files changed

+601
-133
lines changed

README.md

+2-9
Original file line numberDiff line numberDiff line change
@@ -188,15 +188,8 @@ But if you find that this isn't the case, then don't hesitate to open an issue o
188188
The entire public API of `scipy` is **fully annotated** and **verifiably valid**.
189189
For the most part, this can also be said about `scipy`'s private API and other internal machinery.
190190

191-
### `Untyped`
192-
193-
A small portion of the stubs uses the `Untyped` type (an alias of `Any`) as a "placeholder" or "to-do" annotation.
194-
In those cases static type-checkers won't do any type-checking, and won't bother you with errors or warnings, so you probably
195-
won't even notice it.
196-
The current goal of `scipy-stubs` is to replace all `Untyped` annotations with more meaningful ones.
197-
198-
At the moment, out of the 21 `scipy.*` subpackages, the only one that still has (some) `Untyped` annotations, is `scipy.signal`.
199-
See [scipy-stubs#99](https://github.com/jorenham/scipy-stubs/issues/99) for an overview.
191+
Note that this does not mean that all annotations are optimal, and some might even be incorrect. If you encounter this, it would
192+
help a lot if you could open an issue or a PR for it.
200193

201194
## Contributing
202195

scipy-stubs/_typing.pyi

+1-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# NOTE: This private(!) module only exists in `if typing.TYPE_CHECKING: ...` and in `.pyi` stubs
22

33
from os import PathLike
4-
from collections.abc import Callable, Sequence
4+
from collections.abc import Sequence
55
from types import TracebackType
66
from typing import IO, Any, Literal, Protocol, TypeAlias, type_check_only
77
from typing_extensions import LiteralString, Self, TypeVar
@@ -28,12 +28,6 @@ __all__ = [
2828
"OrderCF",
2929
"OrderKACF",
3030
"ToRNG",
31-
"Untyped",
32-
"UntypedArray",
33-
"UntypedCallable",
34-
"UntypedDict",
35-
"UntypedList",
36-
"UntypedTuple",
3731
"_FortranFunction",
3832
]
3933

@@ -63,14 +57,6 @@ class _FortranFunction(Protocol):
6357
def typecode(self, /) -> LiteralString: ...
6458
def __call__(self, /, *args: object, **kwargs: object) -> object: ...
6559

66-
# placeholders for missing annotations
67-
Untyped: TypeAlias = Any
68-
UntypedTuple: TypeAlias = tuple[Untyped, ...]
69-
UntypedList: TypeAlias = list[Untyped]
70-
UntypedDict: TypeAlias = dict[Untyped, Untyped]
71-
UntypedCallable: TypeAlias = Callable[..., Untyped]
72-
UntypedArray: TypeAlias = onp.Array[Any, np.generic]
73-
7460
# I/O
7561
_ByteSOrStr = TypeVar("_ByteSOrStr", bytes, str)
7662
FileName: TypeAlias = str | PathLike[str]
+84-19
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,112 @@
1-
from typing import Any, Literal, TypeAlias
1+
from typing import Literal, TypeAlias, TypeVar, overload
22

33
import numpy as np
44
import optype.numpy as onp
5-
from ._ltisys import lti
5+
import optype.numpy.compat as npc
6+
from ._ltisys import dlti, lti
67

78
__all__ = ["abcd_normalize", "cont2discrete", "ss2tf", "ss2zpk", "tf2ss", "zpk2ss"]
89

10+
###
11+
912
_ToSystemTF: TypeAlias = tuple[onp.ToComplex2D, onp.ToComplex1D] # (num, den)
10-
_InSystemZPK: TypeAlias = tuple[onp.ToComplex1D, onp.ToComplex1D, onp.ToFloat] # (z, p, k)
11-
_InSystemSS: TypeAlias = tuple[onp.ToComplex2D, onp.ToComplex2D, onp.ToComplex2D, onp.ToComplex2D] # (A, B, C, D)
13+
_ToSystemZPK: TypeAlias = tuple[onp.ToComplex1D, onp.ToComplex1D, onp.ToFloat] # (z, p, k)
14+
_ToSystemSS: TypeAlias = tuple[onp.ToComplex2D, onp.ToComplex2D, onp.ToComplex2D, onp.ToComplex2D] # (A, B, C, D)
1215

13-
_Inexact1D: TypeAlias = onp.Array1D[np.inexact[Any]]
14-
_Inexact2D: TypeAlias = onp.Array2D[np.inexact[Any]]
16+
_InexactT = TypeVar("_InexactT", bound=npc.inexact, default=npc.inexact)
17+
_Inexact1D: TypeAlias = onp.Array1D[_InexactT]
18+
_Inexact2D: TypeAlias = onp.Array2D[_InexactT]
1519

16-
_SystemTF: TypeAlias = tuple[_Inexact2D, _Inexact1D]
17-
_SystemZPK: TypeAlias = tuple[_Inexact1D, _Inexact1D, float]
18-
_SystemSS: TypeAlias = tuple[_Inexact2D, _Inexact2D, _Inexact2D, _Inexact2D]
20+
_SystemTF: TypeAlias = tuple[_Inexact2D[_InexactT], _Inexact1D[_InexactT]]
21+
_SystemZPK: TypeAlias = tuple[_Inexact1D[_InexactT], _Inexact1D[_InexactT], float | np.float64]
22+
_SystemSS: TypeAlias = tuple[_Inexact2D[_InexactT], _Inexact2D[_InexactT], _Inexact2D[_InexactT], _Inexact2D[_InexactT]]
1923

20-
_Method: TypeAlias = Literal["gbt", "bilinear", "euler", "backward_diff", "foh", "impulse", "zoh"]
24+
_DiscretizeMethod: TypeAlias = Literal["gbt", "bilinear", "euler", "backward_diff", "foh", "impulse", "zoh"]
2125

26+
###
27+
@overload
28+
def abcd_normalize(
29+
A: onp.ToFloat2D | None = None,
30+
B: onp.ToFloat2D | None = None,
31+
C: onp.ToFloat2D | None = None,
32+
D: onp.ToFloat2D | None = None,
33+
) -> _SystemTF[npc.floating]: ...
34+
@overload
2235
def abcd_normalize(
2336
A: onp.ToComplex2D | None = None,
2437
B: onp.ToComplex2D | None = None,
2538
C: onp.ToComplex2D | None = None,
2639
D: onp.ToComplex2D | None = None,
2740
) -> _SystemTF: ...
41+
42+
#
43+
@overload
44+
def tf2ss(num: onp.ToFloat2D, den: onp.ToFloat1D) -> _SystemSS[npc.floating]: ...
45+
@overload
2846
def tf2ss(num: onp.ToComplex2D, den: onp.ToComplex1D) -> _SystemSS: ...
29-
def zpk2ss(z: onp.ToComplex1D, p: onp.ToComplex1D, k: onp.ToFloat) -> _SystemSS: ...
47+
48+
#
49+
@overload
50+
def ss2tf(
51+
A: onp.ToFloat2D,
52+
B: onp.ToFloat2D,
53+
C: onp.ToFloat2D,
54+
D: onp.ToFloat2D,
55+
input: onp.ToInt = 0,
56+
) -> _SystemTF[npc.floating]: ...
57+
@overload
3058
def ss2tf(A: onp.ToComplex2D, B: onp.ToComplex2D, C: onp.ToComplex2D, D: onp.ToComplex2D, input: onp.ToInt = 0) -> _SystemTF: ...
59+
60+
#
61+
@overload
62+
def zpk2ss(z: onp.ToFloat1D, p: onp.ToFloat1D, k: onp.ToFloat) -> _SystemSS[npc.floating]: ...
63+
@overload
64+
def zpk2ss(z: onp.ToComplex1D, p: onp.ToComplex1D, k: onp.ToFloat) -> _SystemSS: ...
65+
66+
#
67+
@overload
68+
def ss2zpk(
69+
A: onp.ToFloat2D,
70+
B: onp.ToFloat2D,
71+
C: onp.ToFloat2D,
72+
D: onp.ToFloat2D,
73+
input: onp.ToInt = 0,
74+
) -> _SystemZPK[npc.floating]: ...
75+
@overload
3176
def ss2zpk(
3277
A: onp.ToComplex2D,
3378
B: onp.ToComplex2D,
3479
C: onp.ToComplex2D,
3580
D: onp.ToComplex2D,
3681
input: onp.ToInt = 0,
3782
) -> _SystemZPK: ...
83+
84+
# TODO: overload on lti subclasses
85+
@overload
86+
def cont2discrete(
87+
system: lti,
88+
dt: float,
89+
method: _DiscretizeMethod = "zoh",
90+
alpha: onp.ToJustFloat | None = None,
91+
) -> dlti: ...
92+
@overload
93+
def cont2discrete(
94+
system: _ToSystemTF,
95+
dt: float,
96+
method: _DiscretizeMethod = "zoh",
97+
alpha: onp.ToJustFloat | None = None,
98+
) -> tuple[_Inexact2D[_InexactT], _Inexact1D[_InexactT], float]: ...
99+
@overload
100+
def cont2discrete(
101+
system: _ToSystemZPK,
102+
dt: float,
103+
method: _DiscretizeMethod = "zoh",
104+
alpha: onp.ToJustFloat | None = None,
105+
) -> tuple[_Inexact1D[_InexactT], _Inexact1D[_InexactT], float, float]: ...
106+
@overload
38107
def cont2discrete(
39-
system: lti | _ToSystemTF | _InSystemZPK | _InSystemSS,
108+
system: _ToSystemSS,
40109
dt: float,
41-
method: _Method = "zoh",
42-
alpha: onp.ToFloat | None = None,
43-
) -> (
44-
tuple[_Inexact2D, _Inexact1D, float]
45-
| tuple[_Inexact1D, _Inexact1D, float, float]
46-
| tuple[_Inexact2D, _Inexact2D, _Inexact2D, _Inexact2D, float]
47-
): ...
110+
method: _DiscretizeMethod = "zoh",
111+
alpha: onp.ToJustFloat | None = None,
112+
) -> tuple[_Inexact2D[_InexactT], _Inexact2D[_InexactT], _Inexact2D[_InexactT], _Inexact2D[_InexactT], float]: ...

0 commit comments

Comments
 (0)