diff --git a/scipy-stubs/linalg/_basic.pyi b/scipy-stubs/linalg/_basic.pyi index 49f48ff9..2a88708f 100644 --- a/scipy-stubs/linalg/_basic.pyi +++ b/scipy-stubs/linalg/_basic.pyi @@ -1,5 +1,8 @@ +# mypy: disable-error-code=overload-overlap + from typing import Final, Literal, TypeAlias, TypeVar, overload +import numpy as np import optype as op import optype.numpy as onp import optype.numpy.compat as npc @@ -22,6 +25,7 @@ __all__ = [ _T = TypeVar("_T") _Tuple2: TypeAlias = tuple[_T, _T] +_COrCR: TypeAlias = _T | _Tuple2[_T] _Float: TypeAlias = npc.floating _Float0D: TypeAlias = onp.Array0D[_Float] @@ -29,11 +33,23 @@ _Float1D: TypeAlias = onp.Array1D[_Float] _Float2D: TypeAlias = onp.Array2D[_Float] _FloatND: TypeAlias = onp.ArrayND[_Float] -_Complex: TypeAlias = npc.inexact # float and complex input types are near impossible to distinguish -_Complex0D: TypeAlias = onp.Array0D[_Complex] -_Complex1D: TypeAlias = onp.Array1D[_Complex] -_Complex2D: TypeAlias = onp.Array2D[_Complex] -_ComplexND: TypeAlias = onp.ArrayND[_Complex] +_Inexact: TypeAlias = npc.inexact +_Inexact0D: TypeAlias = onp.Array0D[_Inexact] +_Inexact1D: TypeAlias = onp.Array1D[_Inexact] +_Inexact2D: TypeAlias = onp.Array2D[_Inexact] +_InexactND: TypeAlias = onp.ArrayND[_Inexact] + +_InputFloat: TypeAlias = onp.ToArrayND[float, np.float64 | np.longdouble | npc.integer | np.bool_] +_InputFloatStrict1D: TypeAlias = onp.ToArrayStrict1D[float, np.float64 | np.longdouble | npc.integer | np.bool_] +_InputFloatStrict2D: TypeAlias = onp.ToArrayStrict2D[float, np.float64 | np.longdouble | npc.integer | np.bool_] + +_InputF64: TypeAlias = onp.ToArrayND[float, np.float64 | npc.integer | np.bool_] +_InputF64Strict1D: TypeAlias = onp.ToArrayStrict1D[float, np.float64 | npc.integer | np.bool_] +_InputF64Strict2D: TypeAlias = onp.ToArrayStrict2D[float, np.float64 | npc.integer | np.bool_] + +_InputComplex: TypeAlias = onp.ToArrayND[op.JustComplex, np.complex128 | np.clongdouble] +_InputComplexStrict1D: TypeAlias = onp.ToArrayStrict1D[op.JustComplex, np.complex128 | np.clongdouble] +_InputComplexStrict2D: TypeAlias = onp.ToArrayStrict2D[op.JustComplex, np.complex128 | np.clongdouble] _AssumeA: TypeAlias = Literal[ "diagonal", @@ -54,262 +70,961 @@ _LapackDriver: TypeAlias = Literal["gelsd", "gelsy", "gelss"] lapack_cast_dict: Final[dict[str, str]] = ... -@overload # floating, 2d, 2d +@overload # 2D ~float64, +float64 +def solve( + a: _InputFloatStrict2D, + b: onp.ToFloatStrict1D | onp.ToFloatStrict2D, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, + assume_a: _AssumeA | None = None, + transposed: bool = False, +) -> onp.Array2D[np.float64]: ... +@overload # Nd ~float64, +float64 +def solve( + a: _InputFloat, + b: onp.ToFloatND, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, + assume_a: _AssumeA | None = None, + transposed: bool = False, +) -> onp.ArrayND[np.float64]: ... +@overload # 2d +float64, ~float64 def solve( a: onp.ToFloatStrict2D, - b: onp.ToFloatStrict2D, - lower: onp.ToBool = False, - overwrite_a: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, + b: _InputFloatStrict1D | _InputFloatStrict2D, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, assume_a: _AssumeA | None = None, - transposed: onp.ToBool = False, -) -> _Float2D: ... -@overload # floating + transposed: bool = False, +) -> onp.Array2D[np.float64]: ... +@overload # Nd +float64, ~float64 +def solve( + a: onp.ToFloatND, + b: _InputFloat, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, + assume_a: _AssumeA | None = None, + transposed: bool = False, +) -> onp.ArrayND[np.float64]: ... +@overload # 2d ~complex128, +complex128 +def solve( + a: _InputComplexStrict2D, + b: onp.ToComplexStrict1D | onp.ToComplexStrict2D, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, + assume_a: _AssumeA | None = None, + transposed: bool = False, +) -> onp.Array2D[np.complex128]: ... +@overload # Nd ~complex128, +complex128 +def solve( + a: _InputComplex, + b: onp.ToComplexND, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, + assume_a: _AssumeA | None = None, + transposed: bool = False, +) -> onp.ArrayND[np.complex128]: ... +@overload # 2d +complex128, ~complex128 +def solve( + a: onp.ToComplexStrict2D, + b: _InputComplexStrict1D | _InputComplexStrict2D, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, + assume_a: _AssumeA | None = None, + transposed: bool = False, +) -> onp.Array2D[np.complex128]: ... +@overload # Nd +complex128, ~complex128 +def solve( + a: onp.ToComplexND, + b: _InputComplex, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, + assume_a: _AssumeA | None = None, + transposed: bool = False, +) -> onp.ArrayND[np.complex128]: ... +@overload # 2d +floating, +floating +def solve( + a: onp.ToFloatStrict2D, + b: onp.ToFloatStrict1D | onp.ToFloatStrict2D, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, + assume_a: _AssumeA | None = None, + transposed: bool = False, +) -> onp.Array2D[np.float32 | np.float64]: ... +@overload # Nd +floating, +floating def solve( a: onp.ToFloatND, b: onp.ToFloatND, - lower: onp.ToBool = False, - overwrite_a: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, assume_a: _AssumeA | None = None, - transposed: onp.ToBool = False, -) -> _FloatND: ... -@overload # complexfloating 2d, 2d + transposed: bool = False, +) -> onp.ArrayND[np.float32 | np.float64]: ... +@overload # 2d +complexfloating, ~complexfloating def solve( a: onp.ToComplexStrict2D, - b: onp.ToComplexStrict2D, - lower: onp.ToBool = False, - overwrite_a: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, + b: onp.ToJustComplexStrict1D | onp.ToJustComplexStrict2D, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, assume_a: _AssumeA | None = None, - transposed: onp.ToBool = False, -) -> _Complex2D: ... -@overload # complexfloating + transposed: bool = False, +) -> onp.Array2D[np.complex64 | np.complex128]: ... +@overload # Nd +complexfloating, ~complexfloating +def solve( + a: onp.ToComplexND, + b: onp.ToJustComplexND, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, + assume_a: _AssumeA | None = None, + transposed: bool = False, +) -> onp.ArrayND[np.complex64 | np.complex128]: ... +@overload # Nd +complexfloating, +complexfloating def solve( a: onp.ToComplexND, b: onp.ToComplexND, - lower: onp.ToBool = False, - overwrite_a: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, + lower: bool = False, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, assume_a: _AssumeA | None = None, - transposed: onp.ToBool = False, -) -> _ComplexND: ... + transposed: bool = False, +) -> onp.ArrayND[np.float32 | np.float64 | np.complex64 | np.complex128]: ... # -@overload # floating 2d, 1d +@overload # 1D ~float64, +float64 +def solve_triangular( + a: _InputFloatStrict2D, + b: onp.ToFloatStrict1D, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.float64]: ... +@overload # 2D ~float64, +float64 +def solve_triangular( + a: _InputFloatStrict2D, + b: onp.ToFloatStrict2D, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.float64]: ... +@overload # Nd ~float64, +float64 +def solve_triangular( + a: _InputFloat, + b: onp.ToFloatND, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.float64]: ... +@overload # 1d +float64, ~float64 +def solve_triangular( + a: onp.ToFloatStrict2D, + b: _InputFloatStrict1D, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.float64]: ... +@overload # 2d +float64, ~float64 +def solve_triangular( + a: onp.ToFloatStrict2D, + b: _InputFloatStrict2D, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.float64]: ... +@overload # Nd +float64, ~float64 +def solve_triangular( + a: onp.ToFloatND, + b: _InputFloat, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.float64]: ... +@overload # 1d ~complex128, +complex128 +def solve_triangular( + a: _InputComplexStrict2D, + b: onp.ToComplexStrict1D, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.complex128]: ... +@overload # 2d ~complex128, +complex128 +def solve_triangular( + a: _InputComplexStrict2D, + b: onp.ToComplexStrict2D, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.complex128]: ... +@overload # Nd ~complex128, +complex128 +def solve_triangular( + a: _InputComplex, + b: onp.ToComplexND, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.complex128]: ... +@overload # 1d +complex128, ~complex128 +def solve_triangular( + a: onp.ToComplexStrict2D, + b: _InputComplexStrict1D, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.complex128]: ... +@overload # 2d +complex128, ~complex128 +def solve_triangular( + a: onp.ToComplexStrict2D, + b: _InputComplexStrict2D, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.complex128]: ... +@overload # Nd +complex128, ~complex128 +def solve_triangular( + a: onp.ToComplexND, + b: _InputComplex, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.complex128]: ... +@overload # 1d +floating, +floating def solve_triangular( a: onp.ToFloatStrict2D, b: onp.ToFloatStrict1D, trans: _TransSystem = 0, - lower: onp.ToBool = False, - unit_diagonal: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, -) -> _Float1D: ... -@overload # floating + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.float32 | np.float64]: ... +@overload # 2d +floating, +floating +def solve_triangular( + a: onp.ToFloatStrict2D, + b: onp.ToFloatStrict2D, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.float32 | np.float64]: ... +@overload # Nd +floating, +floating def solve_triangular( a: onp.ToFloatND, b: onp.ToFloatND, trans: _TransSystem = 0, - lower: onp.ToBool = False, - unit_diagonal: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, -) -> _FloatND: ... -@overload # complexfloating 2d, 1d + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.float32 | np.float64]: ... +@overload # 1d +complexfloating, ~complexfloating def solve_triangular( a: onp.ToComplexStrict2D, - b: onp.ToComplexStrict1D, + b: onp.ToJustComplexStrict1D, trans: _TransSystem = 0, - lower: onp.ToBool = False, - unit_diagonal: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, -) -> _Complex1D: ... -@overload # complexfloating + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.complex64 | np.complex128]: ... +@overload # 2d +complexfloating, ~complexfloating +def solve_triangular( + a: onp.ToComplexStrict2D, + b: onp.ToJustComplexStrict2D, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.complex64 | np.complex128]: ... +@overload # Nd +complexfloating, ~complexfloating +def solve_triangular( + a: onp.ToComplexND, + b: onp.ToJustComplexND, + trans: _TransSystem = 0, + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.complex64 | np.complex128]: ... +@overload # Nd +complexfloating, +complexfloating def solve_triangular( a: onp.ToComplexND, b: onp.ToComplexND, trans: _TransSystem = 0, - lower: onp.ToBool = False, - unit_diagonal: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, -) -> _ComplexND: ... + lower: bool = False, + unit_diagonal: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.float32 | np.float64 | np.complex64 | np.complex128]: ... -# -@overload # floating 2d, 1d +# NOTE: keep overload structure consistent with `solveh_banded` below +@overload # 1D ~float64, +float64 +def solve_banded( + l_and_u: tuple[int, int], + ab: _InputFloatStrict2D, + b: onp.ToFloatStrict1D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.float64]: ... +@overload # 2D ~float64, +float64 +def solve_banded( + l_and_u: tuple[int, int], + ab: _InputFloatStrict2D, + b: onp.ToFloatStrict2D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.float64]: ... +@overload # Nd ~float64, +float64 +def solve_banded( + l_and_u: tuple[int, int], + ab: _InputFloat, + b: onp.ToFloatND, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.float64]: ... +@overload # 1d +float64, ~float64 +def solve_banded( + l_and_u: tuple[int, int], + ab: onp.ToFloatStrict2D, + b: _InputFloatStrict1D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.float64]: ... +@overload # 2d +float64, ~float64 def solve_banded( - l_and_u: _Tuple2[onp.ToJustInt], + l_and_u: tuple[int, int], + ab: onp.ToFloatStrict2D, + b: _InputFloatStrict2D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.float64]: ... +@overload # Nd +float64, ~float64 +def solve_banded( + l_and_u: tuple[int, int], + ab: onp.ToFloatND, + b: _InputFloat, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.float64]: ... +@overload # 1d ~complex128, +complex128 +def solve_banded( + l_and_u: tuple[int, int], + ab: _InputComplexStrict2D, + b: onp.ToComplexStrict1D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.complex128]: ... +@overload # 2d ~complex128, +complex128 +def solve_banded( + l_and_u: tuple[int, int], + ab: _InputComplexStrict2D, + b: onp.ToComplexStrict2D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.complex128]: ... +@overload # Nd ~complex128, +complex128 +def solve_banded( + l_and_u: tuple[int, int], + ab: _InputComplex, + b: onp.ToComplexND, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.complex128]: ... +@overload # 1d +complex128, ~complex128 +def solve_banded( + l_and_u: tuple[int, int], + ab: onp.ToComplexStrict2D, + b: _InputComplexStrict1D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.complex128]: ... +@overload # 2d +complex128, ~complex128 +def solve_banded( + l_and_u: tuple[int, int], + ab: onp.ToComplexStrict2D, + b: _InputComplexStrict2D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.complex128]: ... +@overload # Nd +complex128, ~complex128 +def solve_banded( + l_and_u: tuple[int, int], + ab: onp.ToComplexND, + b: _InputComplex, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.complex128]: ... +@overload # 1d +floating, +floating +def solve_banded( + l_and_u: tuple[int, int], ab: onp.ToFloatStrict2D, b: onp.ToFloatStrict1D, - overwrite_ab: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, -) -> _Float1D: ... -@overload # floating + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.float32 | np.float64]: ... +@overload # 2d +floating, +floating def solve_banded( - l_and_u: _Tuple2[onp.ToJustInt], + l_and_u: tuple[int, int], + ab: onp.ToFloatStrict2D, + b: onp.ToFloatStrict2D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.float32 | np.float64]: ... +@overload # Nd +floating, +floating +def solve_banded( + l_and_u: tuple[int, int], ab: onp.ToFloatND, b: onp.ToFloatND, - overwrite_ab: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, -) -> _FloatND: ... -@overload # complexfloating 2d, 1d + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.float32 | np.float64]: ... +@overload # 1d +complexfloating, ~complexfloating def solve_banded( - l_and_u: _Tuple2[onp.ToJustInt], + l_and_u: tuple[int, int], ab: onp.ToComplexStrict2D, - b: onp.ToComplexStrict1D, - overwrite_ab: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, -) -> _Complex1D: ... -@overload # complexfloating + b: onp.ToJustComplexStrict1D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.complex64 | np.complex128]: ... +@overload # 2d +complexfloating, ~complexfloating +def solve_banded( + l_and_u: tuple[int, int], + ab: onp.ToComplexStrict2D, + b: onp.ToJustComplexStrict2D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.complex64 | np.complex128]: ... +@overload # Nd +complexfloating, ~complexfloating def solve_banded( - l_and_u: _Tuple2[onp.ToJustInt], + l_and_u: tuple[int, int], + ab: onp.ToComplexND, + b: onp.ToJustComplexND, + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.complex64 | np.complex128]: ... +@overload # Nd +complexfloating, +complexfloating +def solve_banded( + l_and_u: tuple[int, int], ab: onp.ToComplexND, b: onp.ToComplexND, - overwrite_ab: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, -) -> _ComplexND: ... + overwrite_ab: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.float32 | np.float64 | np.complex64 | np.complex128]: ... -# -@overload # floating 2d, 1d +# NOTE: keep overload structure consistent with `solve_banded` above +@overload # 1D ~float64, +float64 +def solveh_banded( + ab: _InputFloatStrict2D, + b: onp.ToFloatStrict1D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.float64]: ... +@overload # 2D ~float64, +float64 +def solveh_banded( + ab: _InputFloatStrict2D, + b: onp.ToFloatStrict2D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.float64]: ... +@overload # Nd ~float64, +float64 +def solveh_banded( + ab: _InputFloat, + b: onp.ToFloatND, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.float64]: ... +@overload # 1d +float64, ~float64 +def solveh_banded( + ab: onp.ToFloatStrict2D, + b: _InputFloatStrict1D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.float64]: ... +@overload # 2d +float64, ~float64 +def solveh_banded( + ab: onp.ToFloatStrict2D, + b: _InputFloatStrict2D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.float64]: ... +@overload # Nd +float64, ~float64 +def solveh_banded( + ab: onp.ToFloatND, + b: _InputFloat, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.float64]: ... +@overload # 1d ~complex128, +complex128 +def solveh_banded( + ab: _InputComplexStrict2D, + b: onp.ToComplexStrict1D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.complex128]: ... +@overload # 2d ~complex128, +complex128 +def solveh_banded( + ab: _InputComplexStrict2D, + b: onp.ToComplexStrict2D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.complex128]: ... +@overload # Nd ~complex128, +complex128 +def solveh_banded( + ab: _InputComplex, + b: onp.ToComplexND, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.complex128]: ... +@overload # 1d +complex128, ~complex128 +def solveh_banded( + ab: onp.ToComplexStrict2D, + b: _InputComplexStrict1D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.complex128]: ... +@overload # 2d +complex128, ~complex128 +def solveh_banded( + ab: onp.ToComplexStrict2D, + b: _InputComplexStrict2D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.complex128]: ... +@overload # Nd +complex128, ~complex128 +def solveh_banded( + ab: onp.ToComplexND, + b: _InputComplex, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.complex128]: ... +@overload # 1d +floating, +floating def solveh_banded( ab: onp.ToFloatStrict2D, b: onp.ToFloatStrict1D, - overwrite_ab: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - lower: onp.ToBool = False, - check_finite: onp.ToBool = True, -) -> _Float1D: ... -@overload # floating + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.float32 | np.float64]: ... +@overload # 2d +floating, +floating +def solveh_banded( + ab: onp.ToFloatStrict2D, + b: onp.ToFloatStrict2D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.float32 | np.float64]: ... +@overload # Nd +floating, +floating def solveh_banded( ab: onp.ToFloatND, b: onp.ToFloatND, - overwrite_ab: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - lower: onp.ToBool = False, - check_finite: onp.ToBool = True, -) -> _FloatND: ... -@overload # complexfloating 2d, 1d + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.float32 | np.float64]: ... +@overload # 1d +complexfloating, ~complexfloating def solveh_banded( ab: onp.ToComplexStrict2D, - b: onp.ToComplexStrict1D, - overwrite_ab: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - lower: onp.ToBool = False, - check_finite: onp.ToBool = True, -) -> _Complex1D: ... -@overload # complexfloating + b: onp.ToJustComplexStrict1D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.Array1D[np.complex64 | np.complex128]: ... +@overload # 2d +complexfloating, ~complexfloating +def solveh_banded( + ab: onp.ToComplexStrict2D, + b: onp.ToJustComplexStrict2D, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.Array2D[np.complex64 | np.complex128]: ... +@overload # Nd +complexfloating, ~complexfloating +def solveh_banded( + ab: onp.ToComplexND, + b: onp.ToJustComplexND, + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.complex64 | np.complex128]: ... +@overload # Nd +complexfloating, +complexfloating def solveh_banded( ab: onp.ToComplexND, b: onp.ToComplexND, - overwrite_ab: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - lower: onp.ToBool = False, - check_finite: onp.ToBool = True, -) -> _ComplexND: ... + overwrite_ab: bool = False, + overwrite_b: bool = False, + lower: bool = False, + check_finite: bool = True, +) -> onp.ArrayND[np.float32 | np.float64 | np.complex64 | np.complex128]: ... # -@overload # floating 1d +@overload # 1d +float, +float def solve_toeplitz( - c_or_cr: onp.ToFloatStrict1D | _Tuple2[onp.ToFloatStrict1D], b: onp.ToFloat1D, check_finite: onp.ToBool = True -) -> _Float1D: ... -@overload # floating + c_or_cr: _COrCR[onp.ToFloatStrict1D], b: onp.ToFloatStrict1D, check_finite: bool = True +) -> onp.Array1D[np.float64]: ... +@overload # 2d +float, +float def solve_toeplitz( - c_or_cr: onp.ToFloatND | _Tuple2[onp.ToFloatND], b: onp.ToFloatND, check_finite: onp.ToBool = True -) -> _FloatND: ... -@overload # complexfloating 1d + c_or_cr: _COrCR[onp.ToFloatStrict1D], b: onp.ToFloatStrict2D, check_finite: bool = True +) -> onp.Array2D[np.float64]: ... +@overload # Nd +float, +float +def solve_toeplitz(c_or_cr: _COrCR[onp.ToFloatND], b: onp.ToFloatND, check_finite: bool = True) -> onp.ArrayND[np.float64]: ... +@overload # 1d ~complex, +complex def solve_toeplitz( - c_or_cr: onp.ToComplexStrict1D | _Tuple2[onp.ToComplexStrict1D], b: onp.ToComplex1D, check_finite: onp.ToBool = True -) -> _Complex1D: ... -@overload # complexfloating + c_or_cr: _COrCR[onp.ToJustComplexStrict1D], b: onp.ToComplexStrict1D, check_finite: bool = True +) -> onp.Array1D[np.complex128]: ... +@overload # 2d ~complex, +complex +def solve_toeplitz( + c_or_cr: _COrCR[onp.ToJustComplexStrict1D], b: onp.ToComplexStrict2D, check_finite: bool = True +) -> onp.Array2D[np.complex128]: ... +@overload # Nd ~complex, +complex +def solve_toeplitz( + c_or_cr: _COrCR[onp.ToJustComplexND], b: onp.ToComplexND, check_finite: bool = True +) -> onp.ArrayND[np.complex128]: ... +@overload # 1d +complex, ~complex +def solve_toeplitz( + c_or_cr: _COrCR[onp.ToComplexStrict1D], b: onp.ToJustComplexStrict1D, check_finite: bool = True +) -> onp.Array1D[np.complex128]: ... +@overload # 2d +complex, ~complex +def solve_toeplitz( + c_or_cr: _COrCR[onp.ToComplexStrict1D], b: onp.ToJustComplexStrict2D, check_finite: bool = True +) -> onp.Array2D[np.complex128]: ... +@overload # Nd +complex, ~complex def solve_toeplitz( - c_or_cr: onp.ToComplexND | _Tuple2[onp.ToComplexND], b: onp.ToComplexND, check_finite: onp.ToBool = True -) -> _ComplexND: ... + c_or_cr: _COrCR[onp.ToComplexND], b: onp.ToJustComplexND, check_finite: bool = True +) -> onp.ArrayND[np.complex128]: ... +@overload # 1d +complex, +complex +def solve_toeplitz( + c_or_cr: _COrCR[onp.ToComplexStrict1D], b: onp.ToComplexStrict1D, check_finite: bool = True +) -> onp.Array1D[np.float64 | np.complex128]: ... +@overload # 2d +complex, +complex +def solve_toeplitz( + c_or_cr: _COrCR[onp.ToComplexStrict1D], b: onp.ToComplexStrict2D, check_finite: bool = True +) -> onp.Array2D[np.float64 | np.complex128]: ... +@overload # Nd +complex, +complex +def solve_toeplitz( + c_or_cr: _COrCR[onp.ToComplexND], b: onp.ToComplexND, check_finite: bool = True +) -> onp.ArrayND[np.float64 | np.complex128]: ... # -@overload # floating 2d, 2d +@overload # 1D ~float64, +float64 +def solve_circulant( + c: _InputF64Strict1D, + b: onp.ToFloat64Strict1D, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.Array1D[np.float64]: ... +@overload # 2D ~float64, +float64 +def solve_circulant( + c: _InputF64Strict1D, + b: onp.ToFloat64Strict2D, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.Array2D[np.float64]: ... +@overload # Nd ~float64, +float64 def solve_circulant( - c: onp.ToFloatStrict2D, + c: _InputF64, + b: onp.ToFloat64_ND, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.ArrayND[np.float64]: ... +@overload # 1d +float64, ~float64 +def solve_circulant( + c: onp.ToFloat64Strict1D, + b: _InputF64Strict1D, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.Array1D[np.float64]: ... +@overload # 2d +float64, ~float64 +def solve_circulant( + c: onp.ToFloat64Strict1D, + b: _InputF64Strict2D, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.Array2D[np.float64]: ... +@overload # Nd +float64, ~float64 +def solve_circulant( + c: onp.ToFloatND, + b: _InputF64, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.ArrayND[np.float64]: ... +@overload # 1d ~complex128, +complex128 +def solve_circulant( + c: onp.ToJustComplex128Strict1D, + b: onp.ToComplex128Strict1D, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.Array1D[np.complex128]: ... +@overload # 2d ~complex128, +complex128 +def solve_circulant( + c: onp.ToJustComplex128Strict1D, + b: onp.ToComplex128Strict2D, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.Array2D[np.complex128]: ... +@overload # Nd ~complex128, +complex128 +def solve_circulant( + c: onp.ToJustComplex128_ND, + b: onp.ToComplex128_ND, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.ArrayND[np.complex128]: ... +@overload # 1d +complex128, ~complex128 +def solve_circulant( + c: onp.ToComplex128Strict1D, + b: onp.ToJustComplex128Strict1D, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.Array1D[np.complex128]: ... +@overload # 2d +complex128, ~complex128 +def solve_circulant( + c: onp.ToComplex128Strict1D, + b: onp.ToJustComplex128Strict2D, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.Array2D[np.complex128]: ... +@overload # Nd +complex128, ~complex128 +def solve_circulant( + c: onp.ToComplex128_ND, + b: onp.ToJustComplex128_ND, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.ArrayND[np.complex128]: ... +@overload # 1d +floating, +floating +def solve_circulant( + c: onp.ToFloatStrict1D, + b: onp.ToFloatStrict1D, + singular: _Singular = "raise", + tol: onp.ToFloat | None = None, + caxis: op.CanIndex = -1, + baxis: op.CanIndex = 0, + outaxis: op.CanIndex = 0, +) -> onp.Array1D[npc.floating]: ... +@overload # 2d +floating, +floating +def solve_circulant( + c: onp.ToFloatStrict1D, b: onp.ToFloatStrict2D, singular: _Singular = "raise", tol: onp.ToFloat | None = None, caxis: op.CanIndex = -1, baxis: op.CanIndex = 0, outaxis: op.CanIndex = 0, -) -> _Float1D: ... -@overload # floating +) -> onp.Array2D[npc.floating]: ... +@overload # Nd +floating, +floating def solve_circulant( c: onp.ToFloatND, b: onp.ToFloatND, singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.ArrayND[npc.floating]: ... +@overload # 1d +complexfloating, ~complexfloating +def solve_circulant( + c: onp.ToComplexStrict1D, + b: onp.ToJustComplexStrict1D, + singular: _Singular = "raise", tol: onp.ToFloat | None = None, caxis: op.CanIndex = -1, baxis: op.CanIndex = 0, outaxis: op.CanIndex = 0, -) -> _FloatND: ... -@overload # complexfloating 2d, 2d +) -> onp.Array1D[npc.complexfloating]: ... +@overload # 2d +complexfloating, ~complexfloating def solve_circulant( - c: onp.ToComplexStrict2D, - b: onp.ToComplexStrict2D, + c: onp.ToComplexStrict1D, + b: onp.ToJustComplexStrict2D, singular: _Singular = "raise", tol: onp.ToFloat | None = None, caxis: op.CanIndex = -1, baxis: op.CanIndex = 0, outaxis: op.CanIndex = 0, -) -> _Complex1D: ... -@overload # complexfloating +) -> onp.Array2D[npc.complexfloating]: ... +@overload # Nd +complexfloating, ~complexfloating +def solve_circulant( + c: onp.ToComplexND, + b: onp.ToJustComplexND, + singular: _Singular = "raise", + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.ArrayND[npc.complexfloating]: ... +@overload # Nd +complexfloating, +complexfloating def solve_circulant( c: onp.ToComplexND, b: onp.ToComplexND, singular: _Singular = "raise", - tol: onp.ToFloat | None = None, - caxis: op.CanIndex = -1, - baxis: op.CanIndex = 0, - outaxis: op.CanIndex = 0, -) -> _ComplexND: ... + tol: float | None = None, + caxis: int = -1, + baxis: int = 0, + outaxis: int = 0, +) -> onp.ArrayND[npc.inexact]: ... -# +# TODO(jorenham): improve this @overload # floating 2d -def inv(a: onp.ToFloatStrict2D, overwrite_a: onp.ToBool = False, check_finite: onp.ToBool = True) -> _Float2D: ... +def inv(a: onp.ToFloatStrict2D, overwrite_a: bool = False, check_finite: bool = True) -> _Float2D: ... @overload # floating -def inv(a: onp.ToFloatND, overwrite_a: onp.ToBool = False, check_finite: onp.ToBool = True) -> _FloatND: ... +def inv(a: onp.ToFloatND, overwrite_a: bool = False, check_finite: bool = True) -> _FloatND: ... @overload # complexfloating 2d -def inv(a: onp.ToComplexStrict2D, overwrite_a: onp.ToBool = False, check_finite: onp.ToBool = True) -> _Complex2D: ... +def inv(a: onp.ToComplexStrict2D, overwrite_a: bool = False, check_finite: bool = True) -> _Inexact2D: ... @overload # complexfloating -def inv(a: onp.ToComplexND, overwrite_a: onp.ToBool = False, check_finite: onp.ToBool = True) -> _ComplexND: ... +def inv(a: onp.ToComplexND, overwrite_a: bool = False, check_finite: bool = True) -> _InexactND: ... -# +# TODO(jorenham): improve this @overload # floating 2d -def det(a: onp.ToFloatStrict2D, overwrite_a: onp.ToBool = False, check_finite: onp.ToBool = True) -> _Float: ... +def det(a: onp.ToFloatStrict2D, overwrite_a: bool = False, check_finite: bool = True) -> _Float: ... @overload # floating 3d -def det(a: onp.ToFloatStrict3D, overwrite_a: onp.ToBool = False, check_finite: onp.ToBool = True) -> _Float1D: ... +def det(a: onp.ToFloatStrict3D, overwrite_a: bool = False, check_finite: bool = True) -> _Float1D: ... @overload # floating -def det(a: onp.ToFloatND, overwrite_a: onp.ToBool = False, check_finite: onp.ToBool = True) -> _Float | _FloatND: ... +def det(a: onp.ToFloatND, overwrite_a: bool = False, check_finite: bool = True) -> _Float | _FloatND: ... @overload # complexfloating 2d -def det(a: onp.ToJustComplexStrict2D, overwrite_a: onp.ToBool = False, check_finite: onp.ToBool = True) -> _Complex1D: ... +def det(a: onp.ToJustComplexStrict2D, overwrite_a: bool = False, check_finite: bool = True) -> _Inexact1D: ... @overload # complexfloating 3d -def det(a: onp.ToJustComplexStrict3D, overwrite_a: onp.ToBool = False, check_finite: onp.ToBool = True) -> _ComplexND: ... +def det(a: onp.ToJustComplexStrict3D, overwrite_a: bool = False, check_finite: bool = True) -> _InexactND: ... @overload # complexfloating -def det(a: onp.ToComplexND, overwrite_a: onp.ToBool = False, check_finite: onp.ToBool = True) -> _Complex | _ComplexND: ... +def det(a: onp.ToComplexND, overwrite_a: bool = False, check_finite: bool = True) -> _Inexact | _InexactND: ... -# +# TODO(jorenham): improve this @overload # (float[:, :], float[:]) -> (float[:], float[], ...) def lstsq( a: onp.ToFloatStrict2D, b: onp.ToFloatStrict1D, cond: onp.ToFloat | None = None, - overwrite_a: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, lapack_driver: _LapackDriver | None = None, ) -> tuple[_Float1D, _Float0D, int, _Float1D | None]: ... @overload # (float[:, :], float[:, :]) -> (float[:, :], float[:], ...) @@ -317,9 +1032,9 @@ def lstsq( a: onp.ToFloatND, b: onp.ToFloatStrict2D, cond: onp.ToFloat | None = None, - overwrite_a: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, lapack_driver: _LapackDriver | None = None, ) -> tuple[_FloatND, _FloatND, int, _FloatND | None]: ... @overload # (float[:, :], float[:, :?]) -> (float[:, :?], float[:?], ...) @@ -327,9 +1042,9 @@ def lstsq( a: onp.ToFloatND, b: onp.ToFloatND, cond: onp.ToFloat | None = None, - overwrite_a: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, lapack_driver: _LapackDriver | None = None, ) -> tuple[_FloatND, _Float0D | _FloatND, int, _FloatND | None]: ... @overload # (complex[:, :], complex[:, :?]) -> (complex[:, :?], complex[:?], ...) @@ -337,13 +1052,13 @@ def lstsq( a: onp.ToComplexND, b: onp.ToComplexND, cond: onp.ToFloat | None = None, - overwrite_a: onp.ToBool = False, - overwrite_b: onp.ToBool = False, - check_finite: onp.ToBool = True, + overwrite_a: bool = False, + overwrite_b: bool = False, + check_finite: bool = True, lapack_driver: _LapackDriver | None = None, -) -> tuple[_ComplexND, _Complex0D | _ComplexND, int, _ComplexND | None]: ... +) -> tuple[_InexactND, _Inexact0D | _InexactND, int, _InexactND | None]: ... -# +# TODO(jorenham): improve this @overload def pinv( # (float[:, :], return_rank=False) -> float[:, :] a: onp.ToFloatND, @@ -351,7 +1066,7 @@ def pinv( # (float[:, :], return_rank=False) -> float[:, :] atol: onp.ToFloat | None = None, rtol: onp.ToFloat | None = None, return_rank: onp.ToFalse = False, - check_finite: onp.ToBool = True, + check_finite: bool = True, ) -> _FloatND: ... @overload # (float[:, :], return_rank=True) -> (float[:, :], int) def pinv( @@ -360,7 +1075,7 @@ def pinv( atol: onp.ToFloat | None = None, rtol: onp.ToFloat | None = None, return_rank: onp.ToTrue, - check_finite: onp.ToBool = True, + check_finite: bool = True, ) -> tuple[_FloatND, int]: ... @overload # (complex[:, :], return_rank=False) -> complex[:, :] def pinv( @@ -369,8 +1084,8 @@ def pinv( atol: onp.ToFloat | None = None, rtol: onp.ToFloat | None = None, return_rank: onp.ToFalse = False, - check_finite: onp.ToBool = True, -) -> _ComplexND: ... + check_finite: bool = True, +) -> _InexactND: ... @overload # (complex[:, :], return_rank=True) -> (complex[:, :], int) def pinv( a: onp.ToComplexND, @@ -378,88 +1093,83 @@ def pinv( atol: onp.ToFloat | None = None, rtol: onp.ToFloat | None = None, return_rank: onp.ToTrue, - check_finite: onp.ToBool = True, -) -> tuple[_ComplexND, int]: ... + check_finite: bool = True, +) -> tuple[_InexactND, int]: ... -# +# TODO(jorenham): improve this @overload # (float[:, :], return_rank=False) -> float[:, :] def pinvh( a: onp.ToFloatND, atol: onp.ToFloat | None = None, rtol: onp.ToFloat | None = None, - lower: onp.ToBool = True, + lower: bool = True, return_rank: onp.ToFalse = False, - check_finite: onp.ToBool = True, + check_finite: bool = True, ) -> _FloatND: ... @overload # (float[:, :], return_rank=True, /) -> (float[:, :], int) def pinvh( a: onp.ToFloatND, atol: onp.ToFloat | None, rtol: onp.ToFloat | None, - lower: onp.ToBool, + lower: bool, return_rank: onp.ToTrue, - check_finite: onp.ToBool = True, + check_finite: bool = True, ) -> tuple[_FloatND, int]: ... @overload # (float[:, :], *, return_rank=True) -> (float[:, :], int) def pinvh( a: onp.ToFloatND, atol: onp.ToFloat | None = None, rtol: onp.ToFloat | None = None, - lower: onp.ToBool = True, + lower: bool = True, *, return_rank: onp.ToTrue, - check_finite: onp.ToBool = True, + check_finite: bool = True, ) -> tuple[_FloatND, int]: ... @overload # (complex[:, :], return_rank=False) -> complex[:, :] def pinvh( a: onp.ToComplexND, atol: onp.ToFloat | None = None, rtol: onp.ToFloat | None = None, - lower: onp.ToBool = True, + lower: bool = True, return_rank: onp.ToFalse = False, - check_finite: onp.ToBool = True, -) -> _ComplexND: ... + check_finite: bool = True, +) -> _InexactND: ... @overload # (complex[:, :], return_rank=True, /) -> (complex[:, :], int) def pinvh( a: onp.ToComplexND, atol: onp.ToFloat | None, rtol: onp.ToFloat | None, - lower: onp.ToBool, + lower: bool, return_rank: onp.ToTrue, - check_finite: onp.ToBool = True, -) -> tuple[_ComplexND, int]: ... + check_finite: bool = True, +) -> tuple[_InexactND, int]: ... @overload # (complex[:, :], *, return_rank=True) -> (complex[:, :], int) def pinvh( a: onp.ToComplexND, atol: onp.ToFloat | None = None, rtol: onp.ToFloat | None = None, - lower: onp.ToBool = True, + lower: bool = True, *, return_rank: onp.ToTrue, - check_finite: onp.ToBool = True, -) -> tuple[_ComplexND, int]: ... + check_finite: bool = True, +) -> tuple[_InexactND, int]: ... -# +# TODO(jorenham): improve this @overload # (float[:, :], separate=True) -> (float[:, :], float[:, :]) def matrix_balance( A: onp.ToFloatND, permute: onp.ToBool = True, scale: onp.ToBool = True, separate: onp.ToFalse = False, - overwrite_a: onp.ToBool = False, + overwrite_a: bool = False, ) -> _Tuple2[_FloatND]: ... @overload # (float[:, :], separate=False, /) -> (float[:, :], (float[:], float[:])) def matrix_balance( - A: onp.ToFloatND, permute: onp.ToBool, scale: onp.ToBool, separate: onp.ToTrue, overwrite_a: onp.ToBool = False + A: onp.ToFloatND, permute: onp.ToBool, scale: onp.ToBool, separate: onp.ToTrue, overwrite_a: bool = False ) -> tuple[_FloatND, _Tuple2[_FloatND]]: ... @overload # (float[:, :], *, separate=False) -> (float[:, :], (float[:], float[:])) def matrix_balance( - A: onp.ToFloatND, - permute: onp.ToBool = True, - scale: onp.ToBool = True, - *, - separate: onp.ToTrue, - overwrite_a: onp.ToBool = False, + A: onp.ToFloatND, permute: onp.ToBool = True, scale: onp.ToBool = True, *, separate: onp.ToTrue, overwrite_a: bool = False ) -> tuple[_FloatND, _Tuple2[_FloatND]]: ... @overload # (complex[:, :], separate=True) -> (complex[:, :], complex[:, :]) def matrix_balance( @@ -467,48 +1177,43 @@ def matrix_balance( permute: onp.ToBool = True, scale: onp.ToBool = True, separate: onp.ToFalse = False, - overwrite_a: onp.ToBool = False, -) -> _Tuple2[_ComplexND]: ... + overwrite_a: bool = False, +) -> _Tuple2[_InexactND]: ... @overload # (complex[:, :], separate=False, /) -> (complex[:, :], (complex[:], complex[:])) def matrix_balance( - A: onp.ToComplexND, permute: onp.ToBool, scale: onp.ToBool, separate: onp.ToTrue, overwrite_a: onp.ToBool = False -) -> tuple[_ComplexND, _Tuple2[_ComplexND]]: ... + A: onp.ToComplexND, permute: onp.ToBool, scale: onp.ToBool, separate: onp.ToTrue, overwrite_a: bool = False +) -> tuple[_InexactND, _Tuple2[_InexactND]]: ... @overload # (complex[:, :], *, separate=False) -> (complex[:, :], (complex[:], complex[:])) def matrix_balance( - A: onp.ToComplexND, - permute: onp.ToBool = True, - scale: onp.ToBool = True, - *, - separate: onp.ToTrue, - overwrite_a: onp.ToBool = False, -) -> tuple[_ComplexND, _Tuple2[_ComplexND]]: ... + A: onp.ToComplexND, permute: onp.ToBool = True, scale: onp.ToBool = True, *, separate: onp.ToTrue, overwrite_a: bool = False +) -> tuple[_InexactND, _Tuple2[_InexactND]]: ... -# +# TODO(jorenham): improve this @overload # floating 1d, 1d def matmul_toeplitz( c_or_cr: onp.ToFloatStrict1D | _Tuple2[onp.ToFloatStrict1D], x: onp.ToFloatStrict1D, - check_finite: onp.ToBool = False, + check_finite: bool = False, workers: onp.ToJustInt | None = None, ) -> _Float1D: ... @overload # floating def matmul_toeplitz( c_or_cr: onp.ToFloatND | _Tuple2[onp.ToFloatND], x: onp.ToFloatND, - check_finite: onp.ToBool = False, + check_finite: bool = False, workers: onp.ToJustInt | None = None, ) -> _FloatND: ... @overload # complexfloating 1d, 1d def matmul_toeplitz( c_or_cr: onp.ToComplexStrict1D | _Tuple2[onp.ToComplexStrict1D], x: onp.ToComplexStrict1D, - check_finite: onp.ToBool = False, + check_finite: bool = False, workers: onp.ToJustInt | None = None, -) -> _Complex1D: ... +) -> _Inexact1D: ... @overload # complexfloating def matmul_toeplitz( c_or_cr: onp.ToComplexND | _Tuple2[onp.ToComplexND], x: onp.ToComplexND, - check_finite: onp.ToBool = False, + check_finite: bool = False, workers: onp.ToJustInt | None = None, -) -> _ComplexND: ... +) -> _InexactND: ... diff --git a/tests/linalg/test__basic.pyi b/tests/linalg/test__basic.pyi new file mode 100644 index 00000000..e4f22a8f --- /dev/null +++ b/tests/linalg/test__basic.pyi @@ -0,0 +1,317 @@ +# type-tests for `linalg/_basic.pyi` + +from typing import assert_type + +import numpy as np +import optype.numpy as onp +import optype.numpy.compat as npc + +from scipy.linalg import solve, solve_banded, solve_circulant, solve_toeplitz, solve_triangular + +i8_1d: onp.Array1D[np.int8] +i8_2d: onp.Array2D[np.int8] +i8_3d: onp.Array3D[np.int8] + +f16_1d: onp.Array1D[np.float16] +f16_2d: onp.Array2D[np.float16] +f16_3d: onp.Array3D[np.float16] + +f32_1d: onp.Array1D[np.float32] +f32_2d: onp.Array2D[np.float32] +f32_3d: onp.Array3D[np.float32] + +f64_1d: onp.Array1D[np.float64] +f64_2d: onp.Array2D[np.float64] +f64_3d: onp.Array3D[np.float64] + +f80_1d: onp.Array1D[np.longdouble] +f80_2d: onp.Array2D[np.longdouble] +f80_3d: onp.Array3D[np.longdouble] + +c64_1d: onp.Array1D[np.complex64] +c64_2d: onp.Array2D[np.complex64] +c64_3d: onp.Array3D[np.complex64] + +c128_1d: onp.Array1D[np.complex128] +c128_2d: onp.Array2D[np.complex128] +c128_3d: onp.Array3D[np.complex128] + +c160_1d: onp.Array1D[np.clongdouble] +c160_2d: onp.Array2D[np.clongdouble] +c160_3d: onp.Array3D[np.clongdouble] + +py_f_1d: list[float] +py_f_2d: list[list[float]] +py_f_3d: list[list[list[float]]] + +py_c_1d: list[complex] +py_c_2d: list[list[complex]] +py_c_3d: list[list[list[complex]]] + +### +# solve + +assert_type(solve(i8_2d, i8_1d), onp.Array2D[np.float64]) +assert_type(solve(i8_2d, i8_2d), onp.Array2D[np.float64]) +assert_type(solve(i8_2d, i8_3d), onp.ArrayND[np.float64]) +assert_type(solve(i8_3d, i8_1d), onp.ArrayND[np.float64]) + +assert_type(solve(f16_2d, f16_1d), onp.Array2D[np.float32 | np.float64]) +assert_type(solve(f16_2d, f16_2d), onp.Array2D[np.float32 | np.float64]) +assert_type(solve(f16_2d, f16_3d), onp.ArrayND[np.float32 | np.float64]) +assert_type(solve(f16_3d, f16_1d), onp.ArrayND[np.float32 | np.float64]) + +assert_type(solve(f32_2d, f32_1d), onp.Array2D[np.float32 | np.float64]) +assert_type(solve(f32_2d, f32_2d), onp.Array2D[np.float32 | np.float64]) +assert_type(solve(f32_2d, f32_3d), onp.ArrayND[np.float32 | np.float64]) +assert_type(solve(f32_3d, f32_1d), onp.ArrayND[np.float32 | np.float64]) + +assert_type(solve(f64_2d, f64_1d), onp.Array2D[np.float64]) +assert_type(solve(f64_2d, f64_2d), onp.Array2D[np.float64]) +assert_type(solve(f64_2d, f64_3d), onp.ArrayND[np.float64]) +assert_type(solve(f64_3d, f64_1d), onp.ArrayND[np.float64]) + +assert_type(solve(f80_2d, f80_1d), onp.Array2D[np.float64]) +assert_type(solve(f80_2d, f80_2d), onp.Array2D[np.float64]) +assert_type(solve(f80_2d, f80_3d), onp.ArrayND[np.float64]) +assert_type(solve(f80_3d, f80_1d), onp.ArrayND[np.float64]) + +assert_type(solve(c64_2d, c64_1d), onp.Array2D[np.complex64 | np.complex128]) +assert_type(solve(c64_2d, c64_2d), onp.Array2D[np.complex64 | np.complex128]) +assert_type(solve(c64_2d, c64_3d), onp.ArrayND[np.complex64 | np.complex128]) +assert_type(solve(c64_3d, c64_1d), onp.ArrayND[np.complex64 | np.complex128]) + +assert_type(solve(c128_2d, c128_1d), onp.Array2D[np.complex128]) +assert_type(solve(c128_2d, c128_2d), onp.Array2D[np.complex128]) +assert_type(solve(c128_2d, c128_3d), onp.ArrayND[np.complex128]) +assert_type(solve(c128_3d, c128_1d), onp.ArrayND[np.complex128]) + +assert_type(solve(c160_2d, c160_1d), onp.Array2D[np.complex128]) +assert_type(solve(c160_2d, c160_2d), onp.Array2D[np.complex128]) +assert_type(solve(c160_2d, c160_3d), onp.ArrayND[np.complex128]) +assert_type(solve(c160_3d, c160_1d), onp.ArrayND[np.complex128]) + +assert_type(solve(py_f_2d, py_f_1d), onp.Array2D[np.float64]) +assert_type(solve(py_f_2d, py_f_2d), onp.Array2D[np.float64]) +assert_type(solve(py_f_2d, py_f_3d), onp.ArrayND[np.float64]) +assert_type(solve(py_f_3d, py_f_1d), onp.ArrayND[np.float64]) + +assert_type(solve(py_c_2d, py_c_1d), onp.Array2D[np.complex128]) +assert_type(solve(py_c_2d, py_c_2d), onp.Array2D[np.complex128]) +assert_type(solve(py_c_2d, py_c_3d), onp.ArrayND[np.complex128]) +assert_type(solve(py_c_3d, py_c_1d), onp.ArrayND[np.complex128]) + +### +# solve_triangular + +assert_type(solve_triangular(i8_2d, i8_1d), onp.Array1D[np.float64]) +assert_type(solve_triangular(i8_2d, i8_2d), onp.Array2D[np.float64]) +assert_type(solve_triangular(i8_2d, i8_3d), onp.ArrayND[np.float64]) +assert_type(solve_triangular(i8_3d, i8_1d), onp.ArrayND[np.float64]) + +assert_type(solve_triangular(f16_2d, f16_1d), onp.Array1D[np.float32 | np.float64]) +assert_type(solve_triangular(f16_2d, f16_2d), onp.Array2D[np.float32 | np.float64]) +assert_type(solve_triangular(f16_2d, f16_3d), onp.ArrayND[np.float32 | np.float64]) +assert_type(solve_triangular(f16_3d, f16_1d), onp.ArrayND[np.float32 | np.float64]) + +assert_type(solve_triangular(f32_2d, f32_1d), onp.Array1D[np.float32 | np.float64]) +assert_type(solve_triangular(f32_2d, f32_2d), onp.Array2D[np.float32 | np.float64]) +assert_type(solve_triangular(f32_2d, f32_3d), onp.ArrayND[np.float32 | np.float64]) +assert_type(solve_triangular(f32_3d, f32_1d), onp.ArrayND[np.float32 | np.float64]) + +assert_type(solve_triangular(f64_2d, f64_1d), onp.Array1D[np.float64]) +assert_type(solve_triangular(f64_2d, f64_2d), onp.Array2D[np.float64]) +assert_type(solve_triangular(f64_2d, f64_3d), onp.ArrayND[np.float64]) +assert_type(solve_triangular(f64_3d, f64_1d), onp.ArrayND[np.float64]) + +assert_type(solve_triangular(f80_2d, f80_1d), onp.Array1D[np.float64]) +assert_type(solve_triangular(f80_2d, f80_2d), onp.Array2D[np.float64]) +assert_type(solve_triangular(f80_2d, f80_3d), onp.ArrayND[np.float64]) +assert_type(solve_triangular(f80_3d, f80_1d), onp.ArrayND[np.float64]) + +assert_type(solve_triangular(c64_2d, c64_1d), onp.Array1D[np.complex64 | np.complex128]) +assert_type(solve_triangular(c64_2d, c64_2d), onp.Array2D[np.complex64 | np.complex128]) +assert_type(solve_triangular(c64_2d, c64_3d), onp.ArrayND[np.complex64 | np.complex128]) +assert_type(solve_triangular(c64_3d, c64_1d), onp.ArrayND[np.complex64 | np.complex128]) + +assert_type(solve_triangular(c128_2d, c128_1d), onp.Array1D[np.complex128]) +assert_type(solve_triangular(c128_2d, c128_2d), onp.Array2D[np.complex128]) +assert_type(solve_triangular(c128_2d, c128_3d), onp.ArrayND[np.complex128]) +assert_type(solve_triangular(c128_3d, c128_1d), onp.ArrayND[np.complex128]) + +assert_type(solve_triangular(c160_2d, c160_1d), onp.Array1D[np.complex128]) +assert_type(solve_triangular(c160_2d, c160_2d), onp.Array2D[np.complex128]) +assert_type(solve_triangular(c160_2d, c160_3d), onp.ArrayND[np.complex128]) +assert_type(solve_triangular(c160_3d, c160_1d), onp.ArrayND[np.complex128]) + +assert_type(solve_triangular(py_f_2d, py_f_1d), onp.Array1D[np.float64]) +assert_type(solve_triangular(py_f_2d, py_f_2d), onp.Array2D[np.float64]) +assert_type(solve_triangular(py_f_2d, py_f_3d), onp.ArrayND[np.float64]) +assert_type(solve_triangular(py_f_3d, py_f_1d), onp.ArrayND[np.float64]) + +assert_type(solve_triangular(py_c_2d, py_c_1d), onp.Array1D[np.complex128]) +assert_type(solve_triangular(py_c_2d, py_c_2d), onp.Array2D[np.complex128]) +assert_type(solve_triangular(py_c_2d, py_c_3d), onp.ArrayND[np.complex128]) +assert_type(solve_triangular(py_c_3d, py_c_1d), onp.ArrayND[np.complex128]) + +### +# solve_banded (equivalent overload structure to `solveh_banded`) + +assert_type(solve_banded((1, 2), i8_2d, i8_1d), onp.Array1D[np.float64]) +assert_type(solve_banded((1, 2), i8_2d, i8_2d), onp.Array2D[np.float64]) +assert_type(solve_banded((1, 2), i8_2d, i8_3d), onp.ArrayND[np.float64]) +assert_type(solve_banded((1, 2), i8_3d, i8_1d), onp.ArrayND[np.float64]) + +assert_type(solve_banded((1, 2), f16_2d, f16_1d), onp.Array1D[np.float32 | np.float64]) +assert_type(solve_banded((1, 2), f16_2d, f16_2d), onp.Array2D[np.float32 | np.float64]) +assert_type(solve_banded((1, 2), f16_2d, f16_3d), onp.ArrayND[np.float32 | np.float64]) +assert_type(solve_banded((1, 2), f16_3d, f16_1d), onp.ArrayND[np.float32 | np.float64]) + +assert_type(solve_banded((1, 2), f32_2d, f32_1d), onp.Array1D[np.float32 | np.float64]) +assert_type(solve_banded((1, 2), f32_2d, f32_2d), onp.Array2D[np.float32 | np.float64]) +assert_type(solve_banded((1, 2), f32_2d, f32_3d), onp.ArrayND[np.float32 | np.float64]) +assert_type(solve_banded((1, 2), f32_3d, f32_1d), onp.ArrayND[np.float32 | np.float64]) + +assert_type(solve_banded((1, 2), f64_2d, f64_1d), onp.Array1D[np.float64]) +assert_type(solve_banded((1, 2), f64_2d, f64_2d), onp.Array2D[np.float64]) +assert_type(solve_banded((1, 2), f64_2d, f64_3d), onp.ArrayND[np.float64]) +assert_type(solve_banded((1, 2), f64_3d, f64_1d), onp.ArrayND[np.float64]) + +assert_type(solve_banded((1, 2), f80_2d, f80_1d), onp.Array1D[np.float64]) +assert_type(solve_banded((1, 2), f80_2d, f80_2d), onp.Array2D[np.float64]) +assert_type(solve_banded((1, 2), f80_2d, f80_3d), onp.ArrayND[np.float64]) +assert_type(solve_banded((1, 2), f80_3d, f80_1d), onp.ArrayND[np.float64]) + +assert_type(solve_banded((1, 2), c64_2d, c64_1d), onp.Array1D[np.complex64 | np.complex128]) +assert_type(solve_banded((1, 2), c64_2d, c64_2d), onp.Array2D[np.complex64 | np.complex128]) +assert_type(solve_banded((1, 2), c64_2d, c64_3d), onp.ArrayND[np.complex64 | np.complex128]) +assert_type(solve_banded((1, 2), c64_3d, c64_1d), onp.ArrayND[np.complex64 | np.complex128]) + +assert_type(solve_banded((1, 2), c128_2d, c128_1d), onp.Array1D[np.complex128]) +assert_type(solve_banded((1, 2), c128_2d, c128_2d), onp.Array2D[np.complex128]) +assert_type(solve_banded((1, 2), c128_2d, c128_3d), onp.ArrayND[np.complex128]) +assert_type(solve_banded((1, 2), c128_3d, c128_1d), onp.ArrayND[np.complex128]) + +assert_type(solve_banded((1, 2), c160_2d, c160_1d), onp.Array1D[np.complex128]) +assert_type(solve_banded((1, 2), c160_2d, c160_2d), onp.Array2D[np.complex128]) +assert_type(solve_banded((1, 2), c160_2d, c160_3d), onp.ArrayND[np.complex128]) +assert_type(solve_banded((1, 2), c160_3d, c160_1d), onp.ArrayND[np.complex128]) + +assert_type(solve_banded((1, 2), py_f_2d, py_f_1d), onp.Array1D[np.float64]) +assert_type(solve_banded((1, 2), py_f_2d, py_f_2d), onp.Array2D[np.float64]) +assert_type(solve_banded((1, 2), py_f_2d, py_f_3d), onp.ArrayND[np.float64]) +assert_type(solve_banded((1, 2), py_f_3d, py_f_1d), onp.ArrayND[np.float64]) + +assert_type(solve_banded((1, 2), py_c_2d, py_c_1d), onp.Array1D[np.complex128]) +assert_type(solve_banded((1, 2), py_c_2d, py_c_2d), onp.Array2D[np.complex128]) +assert_type(solve_banded((1, 2), py_c_2d, py_c_3d), onp.ArrayND[np.complex128]) +assert_type(solve_banded((1, 2), py_c_3d, py_c_1d), onp.ArrayND[np.complex128]) + +### +# solve_toeplitz + +assert_type(solve_toeplitz(i8_1d, i8_1d), onp.Array1D[np.float64]) +assert_type(solve_toeplitz(i8_1d, i8_2d), onp.Array2D[np.float64]) +assert_type(solve_toeplitz(i8_1d, i8_3d), onp.ArrayND[np.float64]) +assert_type(solve_toeplitz(i8_2d, i8_1d), onp.ArrayND[np.float64]) + +assert_type(solve_toeplitz(f16_1d, f16_1d), onp.Array1D[np.float64]) +assert_type(solve_toeplitz(f16_1d, f16_2d), onp.Array2D[np.float64]) +assert_type(solve_toeplitz(f16_1d, f16_3d), onp.ArrayND[np.float64]) +assert_type(solve_toeplitz(f16_2d, f16_1d), onp.ArrayND[np.float64]) + +assert_type(solve_toeplitz(f32_1d, f32_1d), onp.Array1D[np.float64]) +assert_type(solve_toeplitz(f32_1d, f32_2d), onp.Array2D[np.float64]) +assert_type(solve_toeplitz(f32_1d, f32_3d), onp.ArrayND[np.float64]) +assert_type(solve_toeplitz(f32_2d, f32_1d), onp.ArrayND[np.float64]) + +assert_type(solve_toeplitz(f64_1d, f64_1d), onp.Array1D[np.float64]) +assert_type(solve_toeplitz(f64_1d, f64_2d), onp.Array2D[np.float64]) +assert_type(solve_toeplitz(f64_1d, f64_3d), onp.ArrayND[np.float64]) +assert_type(solve_toeplitz(f64_2d, f64_1d), onp.ArrayND[np.float64]) + +assert_type(solve_toeplitz(f80_1d, f80_1d), onp.Array1D[np.float64]) +assert_type(solve_toeplitz(f80_1d, f80_2d), onp.Array2D[np.float64]) +assert_type(solve_toeplitz(f80_1d, f80_3d), onp.ArrayND[np.float64]) +assert_type(solve_toeplitz(f80_2d, f80_1d), onp.ArrayND[np.float64]) + +assert_type(solve_toeplitz(c64_1d, c64_1d), onp.Array1D[np.complex128]) +assert_type(solve_toeplitz(c64_1d, c64_2d), onp.Array2D[np.complex128]) +assert_type(solve_toeplitz(c64_1d, c64_3d), onp.ArrayND[np.complex128]) +assert_type(solve_toeplitz(c64_2d, c64_1d), onp.ArrayND[np.complex128]) + +assert_type(solve_toeplitz(c128_1d, c128_1d), onp.Array1D[np.complex128]) +assert_type(solve_toeplitz(c128_1d, c128_2d), onp.Array2D[np.complex128]) +assert_type(solve_toeplitz(c128_1d, c128_3d), onp.ArrayND[np.complex128]) +assert_type(solve_toeplitz(c128_2d, c128_1d), onp.ArrayND[np.complex128]) + +assert_type(solve_toeplitz(c160_1d, c160_1d), onp.Array1D[np.complex128]) +assert_type(solve_toeplitz(c160_1d, c160_2d), onp.Array2D[np.complex128]) +assert_type(solve_toeplitz(c160_1d, c160_3d), onp.ArrayND[np.complex128]) +assert_type(solve_toeplitz(c160_2d, c160_1d), onp.ArrayND[np.complex128]) + +assert_type(solve_toeplitz(py_f_1d, py_f_1d), onp.Array1D[np.float64]) +assert_type(solve_toeplitz(py_f_1d, py_f_2d), onp.Array2D[np.float64]) +assert_type(solve_toeplitz(py_f_1d, py_f_3d), onp.ArrayND[np.float64]) +assert_type(solve_toeplitz(py_f_2d, py_f_1d), onp.ArrayND[np.float64]) + +assert_type(solve_toeplitz(py_c_1d, py_c_1d), onp.Array1D[np.complex128]) +assert_type(solve_toeplitz(py_c_1d, py_c_2d), onp.Array2D[np.complex128]) +assert_type(solve_toeplitz(py_c_1d, py_c_3d), onp.ArrayND[np.complex128]) +assert_type(solve_toeplitz(py_c_2d, py_c_1d), onp.ArrayND[np.complex128]) + +### +# solve_circulant + +assert_type(solve_circulant(i8_1d, i8_1d), onp.Array1D[np.float64]) +assert_type(solve_circulant(i8_1d, i8_2d), onp.Array2D[np.float64]) +assert_type(solve_circulant(i8_1d, i8_3d), onp.ArrayND[np.float64]) +assert_type(solve_circulant(i8_2d, i8_1d), onp.ArrayND[np.float64]) + +assert_type(solve_circulant(f16_1d, f16_1d), onp.Array1D[npc.floating]) +assert_type(solve_circulant(f16_1d, f16_2d), onp.Array2D[npc.floating]) +assert_type(solve_circulant(f16_1d, f16_3d), onp.ArrayND[npc.floating]) +assert_type(solve_circulant(f16_2d, f16_1d), onp.ArrayND[npc.floating]) + +assert_type(solve_circulant(f32_1d, f32_1d), onp.Array1D[npc.floating]) +assert_type(solve_circulant(f32_1d, f32_2d), onp.Array2D[npc.floating]) +assert_type(solve_circulant(f32_1d, f32_3d), onp.ArrayND[npc.floating]) +assert_type(solve_circulant(f32_2d, f32_1d), onp.ArrayND[npc.floating]) + +assert_type(solve_circulant(f64_1d, f64_1d), onp.Array1D[np.float64]) +assert_type(solve_circulant(f64_1d, f64_2d), onp.Array2D[np.float64]) +assert_type(solve_circulant(f64_1d, f64_3d), onp.ArrayND[np.float64]) +assert_type(solve_circulant(f64_2d, f64_1d), onp.ArrayND[np.float64]) + +assert_type(solve_circulant(f80_1d, f80_1d), onp.Array1D[npc.floating]) +assert_type(solve_circulant(f80_1d, f80_2d), onp.Array2D[npc.floating]) +assert_type(solve_circulant(f80_1d, f80_3d), onp.ArrayND[npc.floating]) +assert_type(solve_circulant(f80_2d, f80_1d), onp.ArrayND[npc.floating]) + +assert_type(solve_circulant(c64_1d, c64_1d), onp.Array1D[npc.complexfloating]) +assert_type(solve_circulant(c64_1d, c64_2d), onp.Array2D[npc.complexfloating]) +assert_type(solve_circulant(c64_1d, c64_3d), onp.ArrayND[npc.complexfloating]) +assert_type(solve_circulant(c64_2d, c64_1d), onp.ArrayND[npc.complexfloating]) + +assert_type(solve_circulant(c128_1d, c128_1d), onp.Array1D[np.complex128]) +assert_type(solve_circulant(c128_1d, c128_2d), onp.Array2D[np.complex128]) +assert_type(solve_circulant(c128_1d, c128_3d), onp.ArrayND[np.complex128]) +assert_type(solve_circulant(c128_2d, c128_1d), onp.ArrayND[np.complex128]) + +assert_type(solve_circulant(c160_1d, c160_1d), onp.Array1D[npc.complexfloating]) +assert_type(solve_circulant(c160_1d, c160_2d), onp.Array2D[npc.complexfloating]) +assert_type(solve_circulant(c160_1d, c160_3d), onp.ArrayND[npc.complexfloating]) +assert_type(solve_circulant(c160_2d, c160_1d), onp.ArrayND[npc.complexfloating]) + +assert_type(solve_circulant(py_f_1d, py_f_1d), onp.Array1D[np.float64]) +assert_type(solve_circulant(py_f_1d, py_f_2d), onp.Array2D[np.float64]) +assert_type(solve_circulant(py_f_1d, py_f_3d), onp.ArrayND[np.float64]) +assert_type(solve_circulant(py_f_2d, py_f_1d), onp.ArrayND[np.float64]) + +assert_type(solve_circulant(py_c_1d, py_c_1d), onp.Array1D[np.complex128]) +assert_type(solve_circulant(py_c_1d, py_c_2d), onp.Array2D[np.complex128]) +assert_type(solve_circulant(py_c_1d, py_c_3d), onp.ArrayND[np.complex128]) +assert_type(solve_circulant(py_c_2d, py_c_1d), onp.ArrayND[np.complex128]) + +### +# TODO(jorenham): inv, pinv, pinvh, det, lstsq, matrix_balance, matmul_toeplitz