Skip to content

Commit

Permalink
Change DICO parameter to boolean dtime. Update tests as well.
Browse files Browse the repository at this point in the history
  • Loading branch information
rabraker committed Nov 22, 2018
1 parent cfe18ea commit 33c59a8
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
29 changes: 18 additions & 11 deletions control/statefbk.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ def place(A, B, p):
return K


def place_varga(A, B, p, DICO='C', alpha=None):
def place_varga(A, B, p, dtime=False, alpha=None):
"""Place closed loop eigenvalues
K = place_varga(A, B, p, DICO='C', alpha=None)
K = place_varga(A, B, p, dtime=False, alpha=None)
Required Parameters
----------
Expand All @@ -128,8 +128,8 @@ def place_varga(A, B, p, DICO='C', alpha=None):
Optional Parameters
---------------
DICO : 'C' for continuous time pole placement or 'D' for discrete time.
The default is DICO='C'.
dtime: False for continuous time pole placement or True for discrete time.
The default is dtime=False.
alpha: double scalar
If DICO='C', then place_varga will leave the eigenvalues with real
real part less than alpha untouched.
Expand Down Expand Up @@ -160,7 +160,7 @@ def place_varga(A, B, p, DICO='C', alpha=None):
--------
>>> A = [[-1, -1], [0, 1]]
>>> B = [[0], [1]]
>>> K = place(A, B, [-2, -5])
>>> K = place_varga(A, B, [-2, -5])
See Also:
--------
Expand All @@ -184,25 +184,32 @@ def place_varga(A, B, p, DICO='C', alpha=None):
system_eigs = np.linalg.eig(A_mat)[0]
placed_eigs = np.array(p)

# Need a character parameter for SB01BD
if dtime:
DICO = 'D'
else:
DICO = 'C'

if alpha is None:
# SB01BD ignores eigenvalues with real part less than alpha
# (if DICO='C') or with modulus less than alpha
# (if DICO = 'D').
if DICO == 'C':
if dtime:
# For discrete time, slycot only cares about modulus, so just make
# alpha the smallest it can be.
alpha = 0.0
else:
# Choosing alpha=min_eig is insufficient and can lead to an
# error or not having all the eigenvalues placed that we wanted.
# Evidently, what python thinks are the eigs is not precisely
# the same as what slicot thinks are the eigs. So we need some
# numerical breathing room. The following is pretty heuristic,
# but does the trick
alpha = -2*abs(min(system_eigs.real))
elif DICO == 'D':
# For discrete time, slycot only cares about modulus, so just make
# alpha the smallest it can be.
alpha = 0.0
elif DICO == 'D' and alpha < 0.0:
elif dtime and alpha < 0.0:
raise ValueError("Need alpha > 0 when DICO='D'")


# Call SLICOT routine to place the eigenvalues
A_z,w,nfp,nap,nup,F,Z = \
sb01bd(B_mat.shape[0], B_mat.shape[1], len(placed_eigs), alpha,
Expand Down
8 changes: 4 additions & 4 deletions control/tests/statefbk_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def testPlace(self):
@unittest.skipIf(not slycot_check(), "slycot not installed")
def testPlace_varga_continuous(self):
"""
Check that we can place eigenvalues for DICO='C'
Check that we can place eigenvalues for dtime=False
"""
A = np.array([[1., -2.], [3., -4.]])
B = np.array([[5.], [7.]])
Expand Down Expand Up @@ -243,13 +243,13 @@ def testPlace_varga_continuous_partial_eigs(self):
@unittest.skipIf(not slycot_check(), "slycot not installed")
def testPlace_varga_discrete(self):
"""
Check that we can place poles using DICO='D' (discrete time)
Check that we can place poles using dtime=True (discrete time)
"""
A = np.array([[1., 0], [0, 0.5]])
B = np.array([[5.], [7.]])

P = np.array([0.5, 0.5])
K = place_varga(A, B, P, DICO='D')
K = place_varga(A, B, P, dtime=True)
P_placed = np.linalg.eigvals(A - B.dot(K))
# No guarantee of the ordering, so sort them
P.sort()
Expand All @@ -269,7 +269,7 @@ def testPlace_varga_discrete_partial_eigs(self):
P = np.array([0.2, 0.6])
P_expected = np.array([0.5, 0.6])
alpha = 0.51
K = place_varga(A, B, P, DICO='D', alpha=alpha)
K = place_varga(A, B, P, dtime=True, alpha=alpha)
P_placed = np.linalg.eigvals(A - B.dot(K))
P_expected.sort()
P_placed.sort()
Expand Down

0 comments on commit 33c59a8

Please sign in to comment.