Skip to content

Commit 3d816bf

Browse files
authored
🐛✨ sparse.linalg: fix and improve ARPACK eigs and eigsh return dtypes (#831)
2 parents caaeb1f + cd50df2 commit 3d816bf

File tree

1 file changed

+76
-33
lines changed

1 file changed

+76
-33
lines changed

scipy-stubs/sparse/linalg/_eigen/arpack/arpack.pyi

Lines changed: 76 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,22 @@ import numpy as np
55
import optype.numpy as onp
66
import optype.numpy.compat as npc
77

8-
from scipy.sparse._base import _spbase
8+
from scipy.sparse import sparray, spmatrix
99
from scipy.sparse.linalg import LinearOperator
1010

1111
__all__ = ["ArpackError", "ArpackNoConvergence", "eigs", "eigsh"]
1212

1313
_KT = TypeVar("_KT")
14+
_SCT = TypeVar("_SCT", bound=_Numeric, default=_Numeric)
1415

15-
_ToRealMatrix: TypeAlias = onp.ToFloat2D | LinearOperator[npc.floating | npc.integer] | _spbase
16-
_ToComplexMatrix: TypeAlias = onp.ToComplex2D | LinearOperator | _spbase
16+
_Numeric: TypeAlias = npc.number | np.bool_
17+
_ToFloat: TypeAlias = npc.floating | npc.integer | np.bool_
18+
19+
_MatrixOperator: TypeAlias = spmatrix[_SCT] | sparray[_SCT, tuple[int, int]] | LinearOperator[_SCT]
20+
21+
_ToRealMatrix: TypeAlias = onp.ToFloat2D | _MatrixOperator[_ToFloat]
22+
_ToJustComplexMatrix: TypeAlias = onp.ToJustComplex2D | _MatrixOperator[npc.complexfloating]
23+
_ToComplexMatrix: TypeAlias = onp.ToComplex2D | _MatrixOperator
1724

1825
_Which_eigs: TypeAlias = Literal["LM", "SM", "LR", "SR", "LI", "SI"]
1926
_Which_eigsh: TypeAlias = Literal["LM", "SM", "LA", "SA", "BE"]
@@ -27,69 +34,73 @@ class ArpackError(RuntimeError):
2734

2835
class ArpackNoConvergence(ArpackError):
2936
eigenvalues: Final[onp.Array1D[np.float64 | np.complex128]]
30-
eigenvectors: Final[onp.Array2D[np.float64]]
37+
eigenvectors: Final[onp.Array2D[np.float64 | np.complex128]]
3138
def __init__(
32-
self, /, msg: str, eigenvalues: onp.Array1D[np.float64 | np.complex128], eigenvectors: onp.Array2D[np.float64]
39+
self,
40+
/,
41+
msg: str,
42+
eigenvalues: onp.Array1D[np.float64 | np.complex128],
43+
eigenvectors: onp.Array2D[np.float64 | np.complex128],
3344
) -> None: ...
3445

3546
#
3647
@overload # returns_eigenvectors: truthy (default)
3748
def eigs(
3849
A: _ToComplexMatrix,
3950
k: int = 6,
40-
M: _ToRealMatrix | None = None,
51+
M: _ToComplexMatrix | None = None,
4152
sigma: onp.ToComplex | None = None,
4253
which: _Which_eigs = "LM",
43-
v0: onp.ToFloat1D | None = None,
54+
v0: onp.ToComplex1D | None = None,
4455
ncv: int | None = None,
4556
maxiter: int | None = None,
4657
tol: float = 0,
4758
return_eigenvectors: onp.ToTrue = True,
48-
Minv: _ToRealMatrix | None = None,
49-
OPinv: _ToRealMatrix | None = None,
59+
Minv: _ToComplexMatrix | None = None,
60+
OPinv: _ToComplexMatrix | None = None,
5061
OPpart: _OPpart | None = None,
51-
) -> tuple[onp.Array1D[np.complex128], onp.Array2D[np.float64]]: ...
62+
) -> tuple[onp.Array1D[np.complex128], onp.Array2D[np.complex128]]: ...
5263
@overload # returns_eigenvectors: falsy (positional)
5364
def eigs(
5465
A: _ToComplexMatrix,
5566
k: int,
56-
M: _ToRealMatrix | None,
67+
M: _ToComplexMatrix | None,
5768
sigma: onp.ToComplex | None,
5869
which: _Which_eigs,
59-
v0: onp.ToFloat1D | None,
70+
v0: onp.ToComplex1D | None,
6071
ncv: int | None,
6172
maxiter: int | None,
6273
tol: float,
6374
return_eigenvectors: onp.ToFalse,
64-
Minv: _ToRealMatrix | None = None,
65-
OPinv: _ToRealMatrix | None = None,
75+
Minv: _ToComplexMatrix | None = None,
76+
OPinv: _ToComplexMatrix | None = None,
6677
OPpart: _OPpart | None = None,
6778
) -> onp.Array1D[np.complex128]: ...
6879
@overload # returns_eigenvectors: falsy (keyword)
6980
def eigs(
7081
A: _ToComplexMatrix,
7182
k: int = 6,
72-
M: _ToRealMatrix | None = None,
83+
M: _ToComplexMatrix | None = None,
7384
sigma: onp.ToComplex | None = None,
7485
which: _Which_eigs = "LM",
75-
v0: onp.ToFloat1D | None = None,
86+
v0: onp.ToComplex1D | None = None,
7687
ncv: int | None = None,
7788
maxiter: int | None = None,
7889
tol: float = 0,
7990
*,
8091
return_eigenvectors: onp.ToFalse,
81-
Minv: _ToRealMatrix | None = None,
82-
OPinv: _ToRealMatrix | None = None,
92+
Minv: _ToComplexMatrix | None = None,
93+
OPinv: _ToComplexMatrix | None = None,
8394
OPpart: _OPpart | None = None,
8495
) -> onp.Array1D[np.complex128]: ...
8596

8697
#
87-
@overload # returns_eigenvectors: truthy (default)
98+
@overload # real, returns_eigenvectors: truthy (default)
8899
def eigsh(
89-
A: _ToComplexMatrix,
100+
A: _ToRealMatrix,
90101
k: int = 6,
91102
M: _ToRealMatrix | None = None,
92-
sigma: onp.ToComplex | None = None,
103+
sigma: onp.ToFloat | None = None,
93104
which: _Which_eigsh = "LM",
94105
v0: onp.ToFloat1D | None = None,
95106
ncv: int | None = None,
@@ -100,36 +111,68 @@ def eigsh(
100111
OPinv: _ToRealMatrix | None = None,
101112
mode: _Mode = "normal",
102113
) -> tuple[onp.Array1D[np.float64], onp.Array2D[np.float64]]: ...
103-
@overload # returns_eigenvectors: falsy (positional)
114+
@overload # complex, returns_eigenvectors: truthy (default)
115+
def eigsh(
116+
A: _ToJustComplexMatrix,
117+
k: int = 6,
118+
M: _ToComplexMatrix | None = None,
119+
sigma: onp.ToFloat | None = None,
120+
which: _Which_eigsh = "LM",
121+
v0: onp.ToComplex1D | None = None,
122+
ncv: int | None = None,
123+
maxiter: int | None = None,
124+
tol: float = 0,
125+
return_eigenvectors: onp.ToTrue = True,
126+
Minv: _ToComplexMatrix | None = None,
127+
OPinv: _ToComplexMatrix | None = None,
128+
mode: _Mode = "normal",
129+
) -> tuple[onp.Array1D[np.float64], onp.Array2D[np.complex128]]: ...
130+
@overload # real or complex (catch-all), returns_eigenvectors: truthy (default)
131+
def eigsh(
132+
A: _ToComplexMatrix,
133+
k: int = 6,
134+
M: _ToComplexMatrix | None = None,
135+
sigma: onp.ToFloat | None = None,
136+
which: _Which_eigsh = "LM",
137+
v0: onp.ToComplex1D | None = None,
138+
ncv: int | None = None,
139+
maxiter: int | None = None,
140+
tol: float = 0,
141+
return_eigenvectors: onp.ToTrue = True,
142+
Minv: _ToComplexMatrix | None = None,
143+
OPinv: _ToComplexMatrix | None = None,
144+
mode: _Mode = "normal",
145+
) -> tuple[onp.Array1D[np.float64], onp.Array2D[np.float64 | np.complex128]]: ...
146+
@overload # real or complex, returns_eigenvectors: falsy (positional)
104147
def eigsh(
105148
A: _ToComplexMatrix,
106149
k: int,
107-
M: _ToRealMatrix | None,
108-
sigma: onp.ToComplex | None,
150+
M: _ToComplexMatrix | None,
151+
sigma: onp.ToFloat | None,
109152
which: _Which_eigsh,
110-
v0: onp.ToFloat1D | None,
153+
v0: onp.ToComplex1D | None,
111154
ncv: int | None,
112155
maxiter: int | None,
113156
tol: float,
114157
return_eigenvectors: onp.ToFalse,
115-
Minv: _ToRealMatrix | None = None,
116-
OPinv: _ToRealMatrix | None = None,
158+
Minv: _ToComplexMatrix | None = None,
159+
OPinv: _ToComplexMatrix | None = None,
117160
mode: _Mode = "normal",
118161
) -> onp.Array1D[np.float64]: ...
119-
@overload # returns_eigenvectors: falsy (keyword)
162+
@overload # real or complex, returns_eigenvectors: falsy (keyword)
120163
def eigsh(
121164
A: _ToComplexMatrix,
122165
k: int = 6,
123-
M: _ToRealMatrix | None = None,
124-
sigma: onp.ToComplex | None = None,
166+
M: _ToComplexMatrix | None = None,
167+
sigma: onp.ToFloat | None = None,
125168
which: _Which_eigsh = "LM",
126-
v0: onp.ToFloat1D | None = None,
169+
v0: onp.ToComplex1D | None = None,
127170
ncv: int | None = None,
128171
maxiter: int | None = None,
129172
tol: float = 0,
130173
*,
131174
return_eigenvectors: onp.ToFalse,
132-
Minv: _ToRealMatrix | None = None,
133-
OPinv: _ToRealMatrix | None = None,
175+
Minv: _ToComplexMatrix | None = None,
176+
OPinv: _ToComplexMatrix | None = None,
134177
mode: _Mode = "normal",
135178
) -> onp.Array1D[np.float64]: ...

0 commit comments

Comments
 (0)