Skip to content

Commit 863538f

Browse files
committed
Replaced inv with solve and LSQ in modelsimp
1 parent 1fad4c6 commit 863538f

1 file changed

Lines changed: 19 additions & 9 deletions

File tree

control/modelsimp.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,26 @@ def modred(sys, ELIM, method='matchdc'):
177177
B1 = sys.B[NELIM,:]
178178
B2 = sys.B[ELIM,:]
179179

180-
A22I = np.linalg.inv(A22)
181-
182180
if method=='matchdc':
183181
# if matchdc, residualize
184-
Ar = A11 - A12*A22.I*A21
185-
Br = B1 - A12*A22.I*B2
186-
Cr = C1 - C2*A22.I*A21
187-
Dr = sys.D - C2*A22.I*B2
182+
183+
# Check if the matrix A22 is invertible
184+
# if np.linalg.matrix_rank(A22) != len(ELIM):
185+
# raise ValueError("Matrix A22 is singular to working precision.")
186+
187+
# Now precompute A22\A21 and A22\B2 (A22I = inv(A22))
188+
# We can solve two linear systems in one pass, since the
189+
# coefficients matrix A22 is the same. Thus, we perform the LU
190+
# decomposition (cubic runtime complexity) of A22 only once!
191+
# The remaining back substitutions are only quadratic in runtime.
192+
A22I_A21_B2 = np.linalg.solve(A22, np.concatenate((A21, B2), axis=1))
193+
A22I_A21 = A22I_A21_B2[:, :A21.shape[1]]
194+
A22I_B2 = A22I_A21_B2[:, A21.shape[1]:]
195+
196+
Ar = A11 - A12*A22I_A21
197+
Br = B1 - A12*A22I_B2
198+
Cr = C1 - C2*A22I_A21
199+
Dr = sys.D - C2*A22I_B2
188200
elif method=='truncate':
189201
# if truncate, simply discard state x2
190202
Ar = A11
@@ -373,8 +385,6 @@ def markov(Y, U, M):
373385
UU = np.hstack((UU, Ulast))
374386

375387
# Invert and solve for Markov parameters
376-
H = UU.I
377-
H = np.dot(H, Y)
388+
H = np.linalg.lstsq(UU, Y)[0]
378389

379390
return H
380-

0 commit comments

Comments
 (0)