Skip to content

Commit a444efb

Browse files
committed
fix up rebase issues
1 parent 495b10e commit a444efb

File tree

3 files changed

+49
-89
lines changed

3 files changed

+49
-89
lines changed

control/mateqn.py

Lines changed: 26 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@
3737

3838
import warnings
3939
import numpy as np
40-
from numpy import shape, size, copy, zeros, eye, dot, \
41-
finfo, inexact, atleast_2d
40+
from numpy import copy, eye, dot, finfo, inexact, atleast_2d
4241

4342
import scipy as sp
44-
from scipy.linalg import eigvals, solve_discrete_are, solve
43+
from scipy.linalg import eigvals, solve
4544

46-
from .exception import ControlSlycot, ControlArgument, slycot_check
45+
from .exception import ControlSlycot, ControlArgument, ControlDimension, \
46+
slycot_check
4747
from .statesp import _ssmatrix
4848

4949
# Make sure we have access to the right slycot routines
@@ -137,9 +137,9 @@ def lyap(A, Q, C=None, E=None, method=None):
137137
method = _slycot_or_scipy(method)
138138
if method == 'slycot':
139139
if sb03md is None:
140-
raise ControlSlycot("can't find slycot module 'sb03md'")
140+
raise ControlSlycot("Can't find slycot module 'sb03md'")
141141
if sb04md is None:
142-
raise ControlSlycot("can't find slycot module 'sb04md'")
142+
raise ControlSlycot("Can't find slycot module 'sb04md'")
143143

144144
# Reshape input arrays
145145
A = np.array(A, ndmin=2)
@@ -197,7 +197,7 @@ def lyap(A, Q, C=None, E=None, method=None):
197197
from slycot import sg03ad
198198

199199
except ImportError:
200-
raise ControlSlycot("can't find slycot module 'sg03ad'")
200+
raise ControlSlycot("Can't find slycot module 'sg03ad'")
201201

202202
# Solve the generalized Lyapunov equation by calling Slycot
203203
# function sg03ad
@@ -266,11 +266,11 @@ def dlyap(A, Q, C=None, E=None, method=None):
266266
if method == 'slycot':
267267
# Make sure we have access to the right slycot routines
268268
if sb03md is None:
269-
raise ControlSlycot("can't find slycot module 'sb03md'")
269+
raise ControlSlycot("Can't find slycot module 'sb03md'")
270270
if sb04qd is None:
271-
raise ControlSlycot("can't find slycot module 'sb04qd'")
271+
raise ControlSlycot("Can't find slycot module 'sb04qd'")
272272
if sg03ad is None:
273-
raise ControlSlycot("can't find slycot module 'sg03ad'")
273+
raise ControlSlycot("Can't find slycot module 'sg03ad'")
274274

275275
# Reshape input arrays
276276
A = np.array(A, ndmin=2)
@@ -312,7 +312,7 @@ def dlyap(A, Q, C=None, E=None, method=None):
312312
"method='scipy' not valid for Sylvester equation")
313313

314314
# Solve the Sylvester equation by calling Slycot function sb04qd
315-
X = sb04qd(n, m, -A, asarray(Q).T, C)
315+
X = sb04qd(n, m, -A, Q.T, C)
316316

317317
# Solve the generalized Lyapunov equation
318318
elif C is None and E is not None:
@@ -400,18 +400,18 @@ def care(A, B, Q, R=None, S=None, E=None, stabilizing=True, method=None):
400400
try:
401401
from slycot import sb02md
402402
except ImportError:
403-
raise ControlSlycot("can't find slycot module 'sb02md'")
403+
raise ControlSlycot("Can't find slycot module 'sb02md'")
404404

405405
try:
406406
from slycot import sb02mt
407407
except ImportError:
408-
raise ControlSlycot("can't find slycot module 'sb02mt'")
408+
raise ControlSlycot("Can't find slycot module 'sb02mt'")
409409

410410
# Make sure we can find the required slycot routine
411411
try:
412412
from slycot import sg02ad
413413
except ImportError:
414-
raise ControlSlycot("can't find slycot module 'sg02ad'")
414+
raise ControlSlycot("Can't find slycot module 'sg02ad'")
415415

416416
# Reshape input arrays
417417
A = np.array(A, ndmin=2)
@@ -501,10 +501,7 @@ def care(A, B, Q, R=None, S=None, E=None, stabilizing=True, method=None):
501501
'R', n, m, 0, A, E, B, Q, R, S)
502502

503503
# Calculate the closed-loop eigenvalues L
504-
L = zeros(n)
505-
L.dtype = 'complex64'
506-
for i in range(n):
507-
L[i] = (alfar[i] + alfai[i]*1j) / beta[i]
504+
L = np.array([(alfar[i] + alfai[i]*1j) / beta[i] for i in range(n)])
508505

509506
# Calculate the gain matrix G
510507
G = solve(R_b, dot(B_b.T, dot(X, E_b)) + S_b.T)
@@ -599,7 +596,7 @@ def dare(A, B, Q, R, S=None, E=None, stabilizing=True, method=None):
599596

600597
Rmat = _ssmatrix(R)
601598
Qmat = _ssmatrix(Q)
602-
X = solve_discrete_are(A, B, Qmat, Rmat, e=E, s=S)
599+
X = sp.linalg.solve_discrete_are(A, B, Qmat, Rmat, e=E, s=S)
603600
if S is None:
604601
G = solve(B.T.dot(X).dot(B) + Rmat, B.T.dot(X).dot(A))
605602
else:
@@ -616,18 +613,18 @@ def _dare_slycot(A, B, Q, R, S=None, E=None, stabilizing=True):
616613
try:
617614
from slycot import sb02md
618615
except ImportError:
619-
raise ControlSlycot("can't find slycot module 'sb02md'")
616+
raise ControlSlycot("Can't find slycot module 'sb02md'")
620617

621618
try:
622619
from slycot import sb02mt
623620
except ImportError:
624-
raise ControlSlycot("can't find slycot module 'sb02mt'")
621+
raise ControlSlycot("Can't find slycot module 'sb02mt'")
625622

626623
# Make sure we can find the required slycot routine
627624
try:
628625
from slycot import sg02ad
629626
except ImportError:
630-
raise ControlSlycot("can't find slycot module 'sg02ad'")
627+
raise ControlSlycot("Can't find slycot module 'sg02ad'")
631628

632629
# Reshape input arrays
633630
A = np.array(A, ndmin=2)
@@ -660,51 +657,15 @@ def _dare_slycot(A, B, Q, R, S=None, E=None, stabilizing=True):
660657

661658
# Solve the generalized algebraic Riccati equation by calling the
662659
# Slycot function sg02ad
663-
try:
660+
with warnings.catch_warnings():
664661
sort = 'S' if stabilizing else 'U'
662+
warnings.simplefilter("error", category=SlycotResultWarning)
665663
rcondu, X, alfar, alfai, beta, S_o, T, U, iwarn = \
666664
sg02ad('D', 'B', 'N', 'U', 'N', 'N', sort,
667665
'R', n, m, 0, A, E, B, Q, R, S)
668666

669-
except ValueError as ve:
670-
if ve.info < 0 or ve.info > 7:
671-
e = ValueError(ve.message)
672-
e.info = ve.info
673-
elif ve.info == 1:
674-
e = ValueError("The computed extended matrix pencil is " +
675-
"singular, possibly due to rounding errors")
676-
e.info = ve.info
677-
elif ve.info == 2:
678-
e = ValueError("The QZ algorithm failed")
679-
e.info = ve.info
680-
elif ve.info == 3:
681-
e = ValueError("Reordering of the generalized eigenvalues failed")
682-
e.info = ve.info
683-
elif ve.info == 4:
684-
e = ValueError("After reordering, roundoff changed values of " +
685-
"some complex eigenvalues so that leading " +
686-
"eigenvalues in the generalized Schur form no " +
687-
"longer satisfy the stability condition; this " +
688-
"could also be caused due to scaling")
689-
e.info = ve.info
690-
elif ve.info == 5:
691-
e = ValueError("The computed dimension of the solution does " +
692-
"not equal N")
693-
e.info = ve.info
694-
elif ve.info == 6:
695-
e = ValueError("The spectrum is too close to the boundary of " +
696-
"the stability domain")
697-
e.info = ve.info
698-
elif ve.info == 7:
699-
e = ValueError("A singular matrix was encountered during the " +
700-
"computation of the solution matrix X")
701-
e.info = ve.info
702-
raise e
703-
704-
L = zeros(n)
705-
L.dtype = 'complex64'
706-
for i in range(n):
707-
L[i] = (alfar[i] + alfai[i]*1j)/beta[i]
667+
# Calculate the closed-loop eigenvalues L
668+
L = np.array([(alfar[i] + alfai[i]*1j) / beta[i] for i in range(n)])
708669

709670
# Calculate the gain matrix G
710671
G = solve(dot(B_b.T, dot(X, B_b)) + R_b,
@@ -721,21 +682,20 @@ def _slycot_or_scipy(method):
721682
return 'slycot'
722683
elif method == 'scipy' or (method is None and not slycot_check()):
723684
return 'scipy'
724-
>>>>>>> d84fdc6 (add method='scipy' to mateqn functions)
725685
else:
726-
raise ValueError("unknown method %s" % method)
686+
raise ValueError("Unknown method %s" % method)
727687

728688

729689
# Utility function to check matrix dimensions
730690
def _check_shape(name, M, n, m, square=False, symmetric=False):
731691
if square and M.shape[0] != M.shape[1]:
732-
raise ControlArgument("%s must be a square matrix" % name)
692+
raise ControlDimension("%s must be a square matrix" % name)
733693

734694
if symmetric and not _is_symmetric(M):
735695
raise ControlArgument("%s must be a symmetric matrix" % name)
736696

737697
if M.shape[0] != n or M.shape[1] != m:
738-
raise ControlArgument("Incompatible dimensions of %s matrix" % name)
698+
raise ControlDimension("Incompatible dimensions of %s matrix" % name)
739699

740700

741701
# Utility function to check if a matrix is symmetric

control/tests/mateqn_test.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242
import control as ct
4343
from control.mateqn import lyap, dlyap, care, dare
44-
from control.exception import ControlArgument, slycot_check
44+
from control.exception import ControlArgument, ControlDimension, slycot_check
4545
from control.tests.conftest import slycotonly
4646

4747

@@ -334,21 +334,21 @@ def test_raise(self):
334334
Efq = array([[2, 1, 0], [1, 2, 0]])
335335

336336
for cdlyap in [lyap, dlyap]:
337-
with pytest.raises(ControlArgument):
337+
with pytest.raises(ControlDimension):
338338
cdlyap(Afq, Q)
339-
with pytest.raises(ControlArgument):
339+
with pytest.raises(ControlDimension):
340340
cdlyap(A, Qfq)
341341
with pytest.raises(ControlArgument):
342342
cdlyap(A, Qfs)
343-
with pytest.raises(ControlArgument):
343+
with pytest.raises(ControlDimension):
344344
cdlyap(Afq, Q, C)
345-
with pytest.raises(ControlArgument):
345+
with pytest.raises(ControlDimension):
346346
cdlyap(A, Qfq, C)
347-
with pytest.raises(ControlArgument):
347+
with pytest.raises(ControlDimension):
348348
cdlyap(A, Q, Cfd)
349-
with pytest.raises(ControlArgument):
349+
with pytest.raises(ControlDimension):
350350
cdlyap(A, Qfq, None, E)
351-
with pytest.raises(ControlArgument):
351+
with pytest.raises(ControlDimension):
352352
cdlyap(A, Q, None, Efq)
353353
with pytest.raises(ControlArgument):
354354
cdlyap(A, Qfs, None, E)
@@ -365,30 +365,30 @@ def test_raise(self):
365365
E = array([[2, 1], [1, 2]])
366366
Ef = array([[2, 1], [1, 2], [1, 2]])
367367

368-
with pytest.raises(ControlArgument):
368+
with pytest.raises(ControlDimension):
369369
care(Afq, B, Q)
370-
with pytest.raises(ControlArgument):
370+
with pytest.raises(ControlDimension):
371371
care(A, B, Qfq)
372-
with pytest.raises(ControlArgument):
372+
with pytest.raises(ControlDimension):
373373
care(A, Bf, Q)
374-
with pytest.raises(ControlArgument):
374+
with pytest.raises(ControlDimension):
375375
care(1, B, 1)
376376
with pytest.raises(ControlArgument):
377377
care(A, B, Qfs)
378378
with pytest.raises(ControlArgument):
379379
dare(A, B, Q, Rfs)
380380
for cdare in [care, dare]:
381-
with pytest.raises(ControlArgument):
381+
with pytest.raises(ControlDimension):
382382
cdare(Afq, B, Q, R, S, E)
383-
with pytest.raises(ControlArgument):
383+
with pytest.raises(ControlDimension):
384384
cdare(A, B, Qfq, R, S, E)
385-
with pytest.raises(ControlArgument):
385+
with pytest.raises(ControlDimension):
386386
cdare(A, Bf, Q, R, S, E)
387-
with pytest.raises(ControlArgument):
387+
with pytest.raises(ControlDimension):
388388
cdare(A, B, Q, R, S, Ef)
389-
with pytest.raises(ControlArgument):
389+
with pytest.raises(ControlDimension):
390390
cdare(A, B, Q, Rfq, S, E)
391-
with pytest.raises(ControlArgument):
391+
with pytest.raises(ControlDimension):
392392
cdare(A, B, Q, R, Sf, E)
393393
with pytest.raises(ControlArgument):
394394
cdare(A, B, Qfs, R, S, E)

control/tests/statefbk_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,13 +324,13 @@ def test_LQR_3args(self, matarrayin, matarrayout, method):
324324

325325
def test_lqr_badmethod(self):
326326
A, B, Q, R = 0, 1, 10, 2
327-
with pytest.raises(ValueError, match="unknown"):
327+
with pytest.raises(ValueError, match="Unknown method"):
328328
K, S, poles = lqr(A, B, Q, R, method='nosuchmethod')
329329

330330
def test_lqr_slycot_not_installed(self):
331331
A, B, Q, R = 0, 1, 10, 2
332332
if not slycot_check():
333-
with pytest.raises(ControlSlycot, match="can't find slycot"):
333+
with pytest.raises(ControlSlycot, match="Can't find slycot"):
334334
K, S, poles = lqr(A, B, Q, R, method='slycot')
335335

336336
@pytest.mark.xfail(reason="warning not implemented")
@@ -378,11 +378,11 @@ def test_lqr_call_format(self):
378378
np.testing.assert_array_almost_equal(Eref, E)
379379

380380
# Inconsistent system dimensions
381-
with pytest.raises(ct.ControlDimension, match="inconsistent system"):
381+
with pytest.raises(ct.ControlDimension, match="Incompatible dimen"):
382382
K, S, E = lqr(sys.A, sys.C, Q, R)
383383

384384
# incorrect covariance matrix dimensions
385-
with pytest.raises(ct.ControlDimension, match="incorrect weighting"):
385+
with pytest.raises(ct.ControlDimension, match="Q must be a square"):
386386
K, S, E = lqr(sys.A, sys.B, sys.C, R, Q)
387387

388388
def check_LQE(self, L, P, poles, G, QN, RN):
@@ -420,7 +420,7 @@ def test_lqe_call_format(self):
420420
sys_siso = rss(4, 1, 1)
421421
L_ss, P_ss, E_ss = lqe(sys_siso, np.eye(1), np.eye(1))
422422
L_tf, P_tf, E_tf = lqe(tf(sys_siso), np.eye(1), np.eye(1))
423-
np.testing.assert_array_almost_equal(E_ss, E_tf)
423+
np.testing.assert_array_almost_equal(np.sort(E_ss), np.sort(E_tf))
424424

425425
# Make sure we get an error if we specify N
426426
with pytest.raises(ct.ControlNotImplemented):

0 commit comments

Comments
 (0)