8000 Change _block_hankel to top-level, update docstrings and comments · python-control/python-control@6c73062 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6c73062

Browse files
committed
Change _block_hankel to top-level, update docstrings and comments
1 parent 250c448 commit 6c73062

File tree

1 file changed

+23
-22
lines changed

1 file changed

+23
-22
lines changed

control/modelsimp.py

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,21 @@ def minreal(sys, tol=None, verbose=True):
369369
return sysr
370370

371371

372+
def _block_hankel(Y, m, n):
373+
"""Create a block Hankel matrix from impulse response"""
374+
q, p, _ = Y.shape
375+
YY = Y.transpose(0,2,1) # transpose for reshape
376+
377+
H = np.zeros((q*m,p*n))
378+
379+
for r in range(m):
380+
# shift and add row to Hankel matrix
381+
new_row = YY[:,r:r+n,:]
382+
H[q*r:q*(r+1),:] = new_row.reshape((q,p*n))
383+
384+
return H
385+
386+
372387
def eigensys_realization(arg, r, m=None, n=None, dt=True, transpose=False):
373388
r"""eigensys_realization(YY, r)
374389
@@ -389,8 +404,8 @@ def eigensys_realization(arg, r, m=None, n=None, dt=True, transpose=False):
389404
* ``sysd, S = eigensys_realization(data, r)``
390405
* ``sysd, S = eigensys_realization(YY, r)``
391406
392-
where `response` is an `TimeResponseData` object, and `YY` is 1D or 3D
393-
array and r is an integer.
407+
where `data` is a `TimeResponseData` object, `YY` is a 1D or 3D
408+
array, and r is an integer.
394409
395410
Parameters
396411
----------
@@ -406,10 +421,10 @@ def eigensys_realization(arg, r, m=None, n=None, dt=True, transpose=False):
406421
n : integer, optional
407422
Number of columns in Hankel matrix. Default is 2*r.
408423
dt : True or float, optional
409-
True indicates discrete time with unspecified sampling time,
410-
positive number is discrete time with specified sampling time. It
411-
can be used to scale the StateSpace model in order to match the
412-
impulse response of this library. Default is True.
424+
True indicates discrete time with unspecified sampling time and a
425+
positive float is discrete time with the specified sampling time.
426+
It can be used to scale the StateSpace model in order to match the
427+
unit-area impulse response of python-control. Default is True.
413428
transpose : bool, optional
414429
Assume that input data is transposed relative to the standard
415430
:ref:`time-series-convention`. For TimeResponseData this parameter
@@ -439,20 +454,6 @@ def eigensys_realization(arg, r, m=None, n=None, dt=True, transpose=False):
439454
>>> response = ct.impulse_response(ct.tf([1], [1, 0.5], True), T)
440455
>>> sysd, _ = ct.eigensys_realization(response, r=1)
441456
"""
442-
def block_hankel_matrix(Y, m, n):
443-
"""Create a block Hankel matrix from Impulse response"""
444-
q, p, _ = Y.shape
445-
YY = Y.transpose(0,2,1) # transpose for reshape
446-
447-
H = np.zeros((q*m,p*n))
448-
449-
for r in range(m):
450-
# shift and add row to Hankel matrix
451-
new_row = YY[:,r:r+n,:]
452-
H[q*r:q*(r+1),:] = new_row.reshape((q,p*n))
453-
454-
return H
455-
456457
if isinstance(arg, TimeResponseData):
457458
YY = np.array(arg.outputs, ndmin=3)
458459
if arg.transpose:
@@ -475,7 +476,7 @@ def block_hankel_matrix(Y, m, n):
475476
if (l-1) < m+n:
476477
raise ValueError("not enough data for requested number of parameters")
477478

478-
H = block_hankel_matrix(YY[:,:,1:], m, n+1) # Hankel matrix (q*m, p*(n+1))
479+
H = _block_hankel(YY[:,:,1:], m, n+1) # Hankel matrix (q*m, p*(n+1))
479480
Hf = H[:,:-p] # first p*n columns of H
480481
Hl = H[:,p:] # last p*n columns of H
481482

@@ -486,7 +487,7 @@ def block_hankel_matrix(Y, m, n):
486487
# balanced realizations
487488
Sigma_inv = np.diag(1./np.sqrt(S[0:r]))
488489
Ar = Sigma_inv @ Ur.T @ Hl @ Vhr.T @ Sigma_inv
489-
Br = Sigma_inv @ Ur.T @ Hf[:,0:p]*dt
490+
Br = Sigma_inv @ Ur.T @ Hf[:,0:p]*dt # dt scaling for unit-area impulse
490491
Cr = Hf[0:q,:] @ Vhr.T @ Sigma_inv
491492
Dr = YY[:,:,0]
492493

0 commit comments

Comments
 (0)
0