9
9
10
10
import numpy as np
11
11
12
+
12
13
class InteriorPointMethod :
13
14
"""
14
15
Operate on linear programming problems using the Primal-Dual Interior-Point Method.
@@ -21,7 +22,14 @@ class InteriorPointMethod:
21
22
max_iter (int): Maximum number of iterations.
22
23
"""
23
24
24
- def __init__ (self , c : np .ndarray , a : np .ndarray , b : np .ndarray , tol : float = 1e-8 , max_iter : int = 100 ) -> None :
25
+ def __init__ (
26
+ self ,
27
+ c : np .ndarray ,
28
+ a : np .ndarray ,
29
+ b : np .ndarray ,
30
+ tol : float = 1e-8 ,
31
+ max_iter : int = 100 ,
32
+ ) -> None :
25
33
self .c = c
26
34
self .a = a
27
35
self .b = b
@@ -33,7 +41,9 @@ def __init__(self, c: np.ndarray, a: np.ndarray, b: np.ndarray, tol: float = 1e-
33
41
34
42
def _is_valid_input (self ) -> bool :
35
43
"""Validate the input for the linear programming problem."""
36
- return (self .a .shape [0 ] == self .b .shape [0 ]) and (self .a .shape [1 ] == self .c .shape [0 ])
44
+ return (self .a .shape [0 ] == self .b .shape [0 ]) and (
45
+ self .a .shape [1 ] == self .c .shape [0 ]
46
+ )
37
47
38
48
def _convert_to_standard_form (self ):
39
49
"""Convert constraints to standard form by adding slack and surplus variables."""
@@ -65,17 +75,23 @@ def solve(self) -> tuple[np.ndarray, float]:
65
75
r2 = a .T @ y + s - c
66
76
r3 = x * s
67
77
68
- if np .linalg .norm (r1 ) < self .tol and np .linalg .norm (r2 ) < self .tol and np .linalg .norm (r3 ) < self .tol :
78
+ if (
79
+ np .linalg .norm (r1 ) < self .tol
80
+ and np .linalg .norm (r2 ) < self .tol
81
+ and np .linalg .norm (r3 ) < self .tol
82
+ ):
69
83
break
70
84
71
85
mu = np .dot (x , s ) / n
72
86
73
87
# Form the KKT matrix
74
- kkt = np .block ([
75
- [np .zeros ((n , n )), a .T , np .eye (n )],
76
- [a , np .zeros ((m , m )), np .zeros ((m , n ))],
77
- [s_diag , np .zeros ((n , m )), x_diag ]
78
- ])
88
+ kkt = np .block (
89
+ [
90
+ [np .zeros ((n , n )), a .T , np .eye (n )],
91
+ [a , np .zeros ((m , m )), np .zeros ((m , n ))],
92
+ [s_diag , np .zeros ((n , m )), x_diag ],
93
+ ]
94
+ )
79
95
80
96
# Right-hand side
81
97
r = np .hstack ([- r2 , - r1 , - r3 + mu * np .ones (n )])
@@ -84,8 +100,8 @@ def solve(self) -> tuple[np.ndarray, float]:
84
100
delta = np .linalg .solve (kkt , r )
85
101
86
102
dx = delta [:n ]
87
- dy = delta [n : n + m ]
88
- ds = delta [n + m :]
103
+ dy = delta [n : n + m ]
104
+ ds = delta [n + m :]
89
105
90
106
# Step size
91
107
alpha_primal = min (1 , 0.99 * min (- x [dx < 0 ] / dx [dx < 0 ], default = 1 ))
0 commit comments