Skip to content

Commit f1f5375

Browse files
committed
remove _dare_slycot and make slycot/scipy structure moer uniform
1 parent cf3c9b2 commit f1f5375

File tree

1 file changed

+26
-53
lines changed

1 file changed

+26
-53
lines changed

control/mateqn.py

Lines changed: 26 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Implementation of the functions lyap, dlyap, care and dare
44
# for solution of Lyapunov and Riccati equations.
55
#
6-
# Author: Bjorn Olofsson
6+
# Original author: Bjorn Olofsson
77

88
# Copyright (c) 2011, All rights reserved.
99

@@ -162,6 +162,7 @@ def lyap(A, Q, C=None, E=None, method=None):
162162
_check_shape("Q", Q, n, n, square=True, symmetric=True)
163163

164164
if method == 'scipy':
165+
# Solve the Lyapunov equation using SciPy
165166
return sp.linalg.solve_continuous_lyapunov(A, -Q)
166167

167168
# Solve the Lyapunov equation by calling Slycot function sb03md
@@ -177,6 +178,7 @@ def lyap(A, Q, C=None, E=None, method=None):
177178
_check_shape("C", C, n, m)
178179

179180
if method == 'scipy':
181+
# Solve the Sylvester equation using SciPy
180182
return sp.linalg.solve_sylvester(A, Q, -C)
181183

182184
# Solve the Sylvester equation by calling the Slycot function sb04md
@@ -293,6 +295,7 @@ def dlyap(A, Q, C=None, E=None, method=None):
293295
_check_shape("Q", Q, n, n, square=True, symmetric=True)
294296

295297
if method == 'scipy':
298+
# Solve the Lyapunov equation using SciPy
296299
return sp.linalg.solve_discrete_lyapunov(A, Q)
297300

298301
# Solve the Lyapunov equation by calling the Slycot function sb03md
@@ -396,24 +399,6 @@ def care(A, B, Q, R=None, S=None, E=None, stabilizing=True, method=None,
396399
# Decide what method to use
397400
method = _slycot_or_scipy(method)
398401

399-
if method == 'slycot':
400-
# Make sure we can import required slycot routines
401-
try:
402-
from slycot import sb02md
403-
except ImportError:
404-
raise ControlSlycot("Can't find slycot module 'sb02md'")
405-
406-
try:
407-
from slycot import sb02mt
408-
except ImportError:
409-
raise ControlSlycot("Can't find slycot module 'sb02mt'")
410-
411-
# Make sure we can find the required slycot routine
412-
try:
413-
from slycot import sg02ad
414-
except ImportError:
415-
raise ControlSlycot("Can't find slycot module 'sg02ad'")
416-
417402
# Reshape input arrays
418403
A = np.array(A, ndmin=2)
419404
B = np.array(B, ndmin=2)
@@ -447,9 +432,16 @@ def care(A, B, Q, R=None, S=None, E=None, stabilizing=True, method=None,
447432
E, _ = np.linalg.eig(A - B @ K)
448433
return _ssmatrix(X), E, _ssmatrix(K)
449434

450-
# Create back-up of arrays needed for later computations
451-
R_ba = copy(R)
452-
B_ba = copy(B)
435+
# Make sure we can import required slycot routines
436+
try:
437+
from slycot import sb02md
438+
except ImportError:
439+
raise ControlSlycot("Can't find slycot module 'sb02md'")
440+
441+
try:
442+
from slycot import sb02mt
443+
except ImportError:
444+
raise ControlSlycot("Can't find slycot module 'sb02mt'")
453445

454446
# Solve the standard algebraic Riccati equation by calling Slycot
455447
# functions sb02mt and sb02md
@@ -459,7 +451,7 @@ def care(A, B, Q, R=None, S=None, E=None, stabilizing=True, method=None,
459451
X, rcond, w, S_o, U, A_inv = sb02md(n, A, G, Q, 'C', sort=sort)
460452

461453
# Calculate the gain matrix G
462-
G = solve(R_ba, B_ba.T) @ X
454+
G = solve(R, B.T) @ X
463455

464456
# Return the solution X, the closed-loop eigenvalues L and
465457
# the gain matrix G
@@ -486,11 +478,11 @@ def care(A, B, Q, R=None, S=None, E=None, stabilizing=True, method=None,
486478
eigs, _ = sp.linalg.eig(A - B @ K, E)
487479
return _ssmatrix(X), eigs, _ssmatrix(K)
488480

489-
# Create back-up of arrays needed for later computations
490-
R_b = copy(R)
491-
B_b = copy(B)
492-
E_b = copy(E)
493-
S_b = copy(S)
481+
# Make sure we can find the required slycot routine
482+
try:
483+
from slycot import sg02ad
484+
except ImportError:
485+
raise ControlSlycot("Can't find slycot module 'sg02ad'")
494486

495487
# Solve the generalized algebraic Riccati equation by calling the
496488
# Slycot function sg02ad
@@ -505,7 +497,7 @@ def care(A, B, Q, R=None, S=None, E=None, stabilizing=True, method=None,
505497
L = np.array([(alfar[i] + alfai[i]*1j) / beta[i] for i in range(n)])
506498

507499
# Calculate the gain matrix G
508-
G = solve(R_b, B_b.T @ X @ E_b + S_b.T)
500+
G = solve(R, B.T @ X @ E + S.T)
509501

510502
# Return the solution X, the closed-loop eigenvalues L and
511503
# the gain matrix G
@@ -589,14 +581,11 @@ def dare(A, B, Q, R, S=None, E=None, stabilizing=True, method=None,
589581
_check_shape(S_s, S, n, m)
590582

591583
# Figure out how to solve the problem
592-
if method == 'scipy' and not stabilizing:
593-
raise ControlArgument(
594-
"method='scipy' not valid when stabilizing is not True")
595-
596-
elif method == 'slycot':
597-
return _dare_slycot(A, B, Q, R, S, E, stabilizing)
584+
if method == 'scipy':
585+
if not stabilizing:
586+
raise ControlArgument(
587+
"method='scipy' not valid when stabilizing is not True")
598588

599-
else:
600589
X = sp.linalg.solve_discrete_are(A, B, Q, R, e=E, s=S)
601590
if S is None:
602591
G = solve(B.T @ X @ B + R, B.T @ X @ A)
@@ -609,28 +598,12 @@ def dare(A, B, Q, R, S=None, E=None, stabilizing=True, method=None,
609598

610599
return _ssmatrix(X), L, _ssmatrix(G)
611600

612-
613-
def _dare_slycot(A, B, Q, R, S=None, E=None, stabilizing=True):
614-
# Make sure we can import required slycot routines
615-
try:
616-
from slycot import sb02md
617-
except ImportError:
618-
raise ControlSlycot("Can't find slycot module 'sb02md'")
619-
620-
try:
621-
from slycot import sb02mt
622-
except ImportError:
623-
raise ControlSlycot("Can't find slycot module 'sb02mt'")
624-
601+
# Make sure we can import required slycot routine
625602
try:
626603
from slycot import sg02ad
627604
except ImportError:
628605
raise ControlSlycot("Can't find slycot module 'sg02ad'")
629606

630-
# Determine main dimensions
631-
n = A.shape[0]
632-
m = B.shape[1]
633-
634607
# Initialize optional matrices
635608
S = np.zeros((n, m)) if S is None else np.array(S, ndmin=2)
636609
E = np.eye(A.shape[0]) if E is None else np.array(E, ndmin=2)

0 commit comments

Comments
 (0)