|
1 |
| -from collections.abc import Callable, Mapping, Sequence |
2 |
| -from typing import Final, Literal, type_check_only |
| 1 | +from collections.abc import Callable, Sequence |
| 2 | +from typing import Final, Literal, TypeAlias, TypedDict, overload, type_check_only |
| 3 | +from typing_extensions import LiteralString, deprecated |
3 | 4 |
|
4 | 5 | import numpy as np
|
5 | 6 | import optype.numpy as onp
|
6 |
| -from ._optimize import OptimizeResult |
7 |
| -from ._typing import Bound, MethodLinprog |
| 7 | +import optype.numpy.compat as npc |
| 8 | +from ._optimize import OptimizeResult as _OptimizeResult |
| 9 | +from ._typing import Bound, MethodLinprog, MethodLinprogLegacy |
8 | 10 |
|
9 | 11 | __all__ = ["linprog", "linprog_terse_callback", "linprog_verbose_callback"]
|
10 | 12 |
|
| 13 | +### |
| 14 | + |
| 15 | +_Ignored: TypeAlias = object |
| 16 | +_Max3: TypeAlias = Literal[0, 1, 2, 3] |
| 17 | +_Max4: TypeAlias = Literal[_Max3, 4] |
| 18 | + |
| 19 | +_Int: TypeAlias = int | np.int32 | np.int64 |
| 20 | +_Float: TypeAlias = float | np.float64 |
| 21 | +_Float1D: TypeAlias = onp.Array1D[np.float64] |
| 22 | + |
| 23 | +@type_check_only |
| 24 | +class _OptionsCommon(TypedDict, total=False): |
| 25 | + maxiter: _Int # default: method-specific |
| 26 | + disp: onp.ToBool # default: False |
| 27 | + presolve: onp.ToBool # default: True |
| 28 | + |
| 29 | +# highs-ds |
11 | 30 | @type_check_only
|
12 |
| -class _OptimizeResult(OptimizeResult): |
13 |
| - x: onp.ArrayND[np.float64] |
14 |
| - fun: float |
15 |
| - slack: onp.ArrayND[np.float64] |
16 |
| - con: onp.ArrayND[np.float64] |
17 |
| - success: bool |
18 |
| - status: Literal[0, 1, 2, 3, 4] |
19 |
| - nit: int |
20 |
| - message: str |
| 31 | +class _OptionsHighsDS(_OptionsCommon, TypedDict, total=False): |
| 32 | + time_limit: _Float # default: np.finfo(float).max |
| 33 | + dual_feasibility_tolerance: _Float # default: 1e-7 |
| 34 | + primal_feasibility_tolerance: _Float # default: 1e-7 |
| 35 | + simplex_dual_edge_weight_strategy: Literal["dantzig", "devex", "steepest", "steepest-devex"] | None # default: None |
| 36 | + |
| 37 | +# highs-ips |
| 38 | +@type_check_only |
| 39 | +class _OptionsHighsIPM(_OptionsHighsDS, TypedDict, total=False): |
| 40 | + ipm_optimality_tolerance: _Float # default: 1e-8 |
| 41 | + |
| 42 | +# highs |
| 43 | +@type_check_only |
| 44 | +class _OptionsHighs(_OptionsHighsIPM, TypedDict, total=False): |
| 45 | + min_rel_gap: _Float | None # default: None |
| 46 | + |
| 47 | +@type_check_only |
| 48 | +class _OptionsCommonLegacy(_OptionsCommon, TypedDict, total=False): |
| 49 | + tol: _Float |
| 50 | + autoscale: onp.ToBool # default: False |
| 51 | + rr: onp.ToBool # default: True |
| 52 | + rr_method: Literal["SVD", "pivot", "ID", "None"] | None # default: None |
| 53 | + |
| 54 | +# interior-point (legacy, see https://github.com/scipy/scipy/issues/15707) |
| 55 | +@type_check_only |
| 56 | +class _OptionsInteriorPoint(_OptionsCommonLegacy, TypedDict, total=False): |
| 57 | + alpha0: _Float # default: 0.99995 |
| 58 | + beta: _Float # default: 0.1 |
| 59 | + sparse: onp.ToBool # default: False |
| 60 | + lstq: onp.ToBool # default: False |
| 61 | + sym_pos: onp.ToBool # default: True |
| 62 | + cholsky: onp.ToBool # default: True |
| 63 | + pc: onp.ToBool # default: True |
| 64 | + ip: onp.ToBool # default: False |
| 65 | + perm_spec: Literal["NATURAL", "MMD_ATA", "MMD_AT_PLUS_A", "COLAMD"] | None # default: "MMD_AT_PLUS_A" |
| 66 | + |
| 67 | +# revised simplex (legacy, see https://github.com/scipy/scipy/issues/15707) |
| 68 | +@type_check_only |
| 69 | +class _OptionsRevisedSimplex(_OptionsCommonLegacy, TypedDict, total=False): |
| 70 | + maxupdate: _Int # default: 10 |
| 71 | + mast: onp.ToBool # default: False |
| 72 | + pivot: Literal["mrc", "bland"] |
| 73 | + |
| 74 | +# simplex (legacy, see https://github.com/scipy/scipy/issues/15707) |
| 75 | +@type_check_only |
| 76 | +class _OptionsSimplex(_OptionsCommonLegacy, TypedDict, total=False): |
| 77 | + bland: onp.ToBool # default: False |
| 78 | + |
| 79 | +### |
| 80 | + |
| 81 | +__docformat__: Final = "restructuredtext en" # undocumented |
| 82 | +LINPROG_METHODS: Final[Sequence[MethodLinprog | MethodLinprogLegacy]] = ... # undocumented |
21 | 83 |
|
22 |
| -__docformat__: Final[str] = ... |
23 |
| -LINPROG_METHODS: Final[Sequence[MethodLinprog]] = ... |
| 84 | +class OptimizeResult(_OptimizeResult): |
| 85 | + x: _Float1D # minimizing decision variables w.r.t. the constraints |
| 86 | + fun: _Float # optimal objective function value |
| 87 | + slack: _Float1D # slack values; nominally positive |
| 88 | + con: _Float1D # residuals of equality constraints; nominally zero |
| 89 | + status: _Max4 |
| 90 | + message: LiteralString |
| 91 | + nit: int # >=0 |
| 92 | + success: bool # `success = status == 0` |
24 | 93 |
|
25 | 94 | def linprog_verbose_callback(res: _OptimizeResult) -> None: ...
|
26 | 95 | def linprog_terse_callback(res: _OptimizeResult) -> None: ...
|
27 | 96 |
|
28 | 97 | #
|
| 98 | +@overload # highs (default) |
| 99 | +def linprog( |
| 100 | + c: onp.ToFloat1D, |
| 101 | + A_ub: onp.ToFloat2D | None = None, |
| 102 | + b_ub: onp.ToFloat1D | None = None, |
| 103 | + A_eq: onp.ToFloat2D | None = None, |
| 104 | + b_eq: onp.ToFloat1D | None = None, |
| 105 | + bounds: Bound = (0, None), |
| 106 | + method: Literal["highs"] = "highs", |
| 107 | + callback: Callable[[_OptimizeResult], _Ignored] | None = None, |
| 108 | + options: _OptionsHighs | None = None, |
| 109 | + x0: onp.ToFloat1D | None = None, |
| 110 | + integrality: _Max3 | Sequence[_Max3] | onp.CanArrayND[npc.integer] | None = None, |
| 111 | +) -> _OptimizeResult: ... |
| 112 | +@overload # highs-ds |
| 113 | +def linprog( |
| 114 | + c: onp.ToFloat1D, |
| 115 | + A_ub: onp.ToFloat2D | None = None, |
| 116 | + b_ub: onp.ToFloat1D | None = None, |
| 117 | + A_eq: onp.ToFloat2D | None = None, |
| 118 | + b_eq: onp.ToFloat1D | None = None, |
| 119 | + bounds: Bound = (0, None), |
| 120 | + *, |
| 121 | + method: Literal["highs-ds"], |
| 122 | + callback: Callable[[_OptimizeResult], _Ignored] | None = None, |
| 123 | + options: _OptionsHighsDS | None = None, |
| 124 | + x0: onp.ToFloat1D | None = None, |
| 125 | + integrality: _Max3 | Sequence[_Max3] | onp.CanArrayND[npc.integer] | None = None, |
| 126 | +) -> _OptimizeResult: ... |
| 127 | +@overload # highs-ipm |
| 128 | +def linprog( |
| 129 | + c: onp.ToFloat1D, |
| 130 | + A_ub: onp.ToFloat2D | None = None, |
| 131 | + b_ub: onp.ToFloat1D | None = None, |
| 132 | + A_eq: onp.ToFloat2D | None = None, |
| 133 | + b_eq: onp.ToFloat1D | None = None, |
| 134 | + bounds: Bound = (0, None), |
| 135 | + *, |
| 136 | + method: Literal["highs-ipm"], |
| 137 | + callback: Callable[[_OptimizeResult], _Ignored] | None = None, |
| 138 | + options: _OptionsHighsIPM | None = None, |
| 139 | + x0: onp.ToFloat1D | None = None, |
| 140 | + integrality: _Max3 | Sequence[_Max3] | onp.CanArrayND[npc.integer] | None = None, |
| 141 | +) -> _OptimizeResult: ... |
| 142 | +@overload # interior-point (legacy, see https://github.com/scipy/scipy/issues/15707) |
| 143 | +@deprecated("`method='interior-point'` is deprecated and will be removed in SciPy 1.16.0. Please use one of the HIGHS solvers.") |
| 144 | +def linprog( |
| 145 | + c: onp.ToFloat1D, |
| 146 | + A_ub: onp.ToFloat2D | None = None, |
| 147 | + b_ub: onp.ToFloat1D | None = None, |
| 148 | + A_eq: onp.ToFloat2D | None = None, |
| 149 | + b_eq: onp.ToFloat1D | None = None, |
| 150 | + bounds: Bound = (0, None), |
| 151 | + *, |
| 152 | + method: Literal["interior-point"], |
| 153 | + callback: Callable[[_OptimizeResult], _Ignored] | None = None, |
| 154 | + options: _OptionsInteriorPoint | None = None, |
| 155 | + x0: onp.ToFloat1D | None = None, |
| 156 | + integrality: _Max3 | Sequence[_Max3] | onp.CanArrayND[npc.integer] | None = None, |
| 157 | +) -> _OptimizeResult: ... |
| 158 | +@overload # revised simplex (legacy, see https://github.com/scipy/scipy/issues/15707) |
| 159 | +@deprecated("`method='revised simplex'` is deprecated and will be removed in SciPy 1.16.0. Please use one of the HIGHS solvers.") |
| 160 | +def linprog( |
| 161 | + c: onp.ToFloat1D, |
| 162 | + A_ub: onp.ToFloat2D | None = None, |
| 163 | + b_ub: onp.ToFloat1D | None = None, |
| 164 | + A_eq: onp.ToFloat2D | None = None, |
| 165 | + b_eq: onp.ToFloat1D | None = None, |
| 166 | + bounds: Bound = (0, None), |
| 167 | + *, |
| 168 | + method: Literal["revised simplex"], |
| 169 | + callback: Callable[[_OptimizeResult], _Ignored] | None = None, |
| 170 | + options: _OptionsRevisedSimplex | None = None, |
| 171 | + x0: onp.ToFloat1D | None = None, |
| 172 | + integrality: _Max3 | Sequence[_Max3] | onp.CanArrayND[npc.integer] | None = None, |
| 173 | +) -> _OptimizeResult: ... |
| 174 | +@overload # simplex (legacy, see https://github.com/scipy/scipy/issues/15707) |
| 175 | +@deprecated("`method='simplex'` is deprecated and will be removed in SciPy 1.16.0. Please use one of the HIGHS solvers.") |
| 176 | +def linprog( |
| 177 | + c: onp.ToFloat1D, |
| 178 | + A_ub: onp.ToFloat2D | None = None, |
| 179 | + b_ub: onp.ToFloat1D | None = None, |
| 180 | + A_eq: onp.ToFloat2D | None = None, |
| 181 | + b_eq: onp.ToFloat1D | None = None, |
| 182 | + bounds: Bound = (0, None), |
| 183 | + *, |
| 184 | + method: Literal["simplex"], |
| 185 | + callback: Callable[[_OptimizeResult], _Ignored] | None = None, |
| 186 | + options: _OptionsSimplex | None = None, |
| 187 | + x0: onp.ToFloat1D | None = None, |
| 188 | + integrality: _Max3 | Sequence[_Max3] | onp.CanArrayND[npc.integer] | None = None, |
| 189 | +) -> _OptimizeResult: ... |
| 190 | +@overload # any "highs" |
29 | 191 | def linprog(
|
30 |
| - c: onp.ToScalar | onp.ToArrayND, |
31 |
| - A_ub: onp.ToScalar | onp.ToArrayND | None = None, |
32 |
| - b_ub: onp.ToScalar | onp.ToArrayND | None = None, |
33 |
| - A_eq: onp.ToScalar | onp.ToArrayND | None = None, |
34 |
| - b_eq: onp.ToScalar | onp.ToArrayND | None = None, |
| 192 | + c: onp.ToFloat1D, |
| 193 | + A_ub: onp.ToFloat2D | None = None, |
| 194 | + b_ub: onp.ToFloat1D | None = None, |
| 195 | + A_eq: onp.ToFloat2D | None = None, |
| 196 | + b_eq: onp.ToFloat1D | None = None, |
35 | 197 | bounds: Bound = (0, None),
|
36 | 198 | method: MethodLinprog = "highs",
|
37 |
| - callback: Callable[[_OptimizeResult], None] | None = None, |
38 |
| - options: Mapping[str, object] | None = None, |
39 |
| - x0: onp.ToScalar | onp.ToArrayND | None = None, |
40 |
| - integrality: onp.ToScalar | onp.ToArrayND | None = None, |
| 199 | + callback: Callable[[_OptimizeResult], _Ignored] | None = None, |
| 200 | + options: _OptionsHighs | None = None, |
| 201 | + x0: onp.ToFloat1D | None = None, |
| 202 | + integrality: _Max3 | Sequence[_Max3] | onp.CanArrayND[npc.integer] | None = None, |
41 | 203 | ) -> _OptimizeResult: ...
|
0 commit comments