43
43
# External packages and modules
44
44
import numpy as np
45
45
import warnings
46
- from .exception import ControlSlycot , ControlMIMONotImplemented , \
47
- ControlDimension
46
+ from .exception import ControlSlycot , ControlArgument , ControlDimension
48
47
from .iosys import isdtime , isctime
49
48
from .statesp import StateSpace
50
49
from .statefbk import gram
@@ -403,8 +402,10 @@ def era(YY, m, n, nin, nout, r):
403
402
raise NotImplementedError ('This function is not implemented yet.' )
404
403
405
404
406
- def markov (data , m = None , dt = True , truncate = False ):
407
- """Calculate the first `m` Markov parameters [D CB CAB ...]
405
+ def markov (* args , ** kwargs ):
406
+ """markov(Y, U, [, m])
407
+
408
+ Calculate the first `m` Markov parameters [D CB CAB ...]
408
409
from data
409
410
410
411
This function computes the Markov parameters for a discrete time system
@@ -419,14 +420,31 @@ def markov(data, m=None, dt=True, truncate=False):
419
420
the input data is less than the desired number of Markov parameters (a
420
421
warning message is generated in this case).
421
422
423
+ The function can be called with either 1, 2, or 3 arguments:
424
+
425
+ * ``K, S, E = lqr(response)``
426
+ * ``K, S, E = lqr(respnose, m)``
427
+ * ``K, S, E = lqr(Y, U)``
428
+ * ``K, S, E = lqr(Y, U, m)``
429
+
430
+ where `response` is an `TimeResponseData` object, and `Y`, `U`, are 1D or 2D
431
+ array and m is an integer.
432
+
422
433
Parameters
423
434
----------
435
+ Y : array_like
436
+ Output data. If the array is 1D, the system is assumed to be single
437
+ input. If the array is 2D and transpose=False, the columns of `Y`
438
+ are taken as time points, otherwise the rows of `Y` are taken as
439
+ time points.
440
+ U : array_like
441
+ Input data, arranged in the same way as `Y`.
424
442
data : TimeResponseData
425
443
Response data from which the Markov parameters where estimated.
426
444
Input and output data must be 1D or 2D array.
427
445
m : int, optional
428
446
Number of Markov parameters to output. Defaults to len(U).
429
- dt : ( True of float, optional)
447
+ dt : True of float, optional
430
448
True indicates discrete time with unspecified sampling time,
431
449
positive number is discrete time with specified sampling time.
432
450
It can be used to scale the markov parameters in order to match
@@ -460,17 +478,41 @@ def markov(data, m=None, dt=True, truncate=False):
460
478
--------
461
479
>>> T = np.linspace(0, 10, 100)
462
480
>>> U = np.ones((1, 100))
463
- >>> response = ct.forced_response(ct.tf([1], [1, 0.5], True), T, U)
464
- >>> H = ct.markov(response, 3 )
481
+ >>> T, Y = ct.forced_response(ct.tf([1], [1, 0.5], True), T, U)
482
+ >>> H = ct.markov(Y, U, 3, transpose=False )
465
483
466
484
"""
467
485
# Convert input parameters to 2D arrays (if they aren't already)
468
- Umat = np .array (data .inputs , ndmin = 2 )
469
- Ymat = np .array (data .outputs , ndmin = 2 )
470
486
471
- # If data is in transposed format, switch it around
472
- if data .transpose and not data .issiso :
473
- Umat , Ymat = np .transpose (Umat ), np .transpose (Ymat )
487
+ # Get the system description
488
+ if (len (args ) < 1 ):
489
+ raise ControlArgument ("not enough input arguments" )
490
+
491
+ if isinstance (args [0 ], TimeResponseData ):
492
+ Umat = np .array (args [0 ].inputs , ndmin = 2 )
493
+ Ymat = np .array (args [0 ].outputs , ndmin = 2 )
494
+ transpose = args [0 ].transpose
495
+ if args [0 ].transpose and not args [0 ].issiso :
496
+ Umat , Ymat = np .transpose (Umat ), np .transpose (Ymat )
497
+ index = 1
498
+ else :
499
+ if (len (args ) < 2 ):
500
+ raise ControlArgument ("not enough input arguments" )
501
+ Umat = np .array (args [0 ], ndmin = 2 )
502
+ Ymat = np .array (args [1 ], ndmin = 2 )
503
+ transpose = kwargs .pop ('transpose' , False )
504
+ if transpose :
505
+ Umat , Ymat = np .transpose (Umat ), np .transpose (Ymat )
506
+ index = 2
507
+
508
+
509
+ if (len (args ) > index ):
510
+ m = args [index ]
511
+ else :
512
+ m = None
513
+
514
+ dt = kwargs .pop ('dt' , True )
515
+ truncate = kwargs .pop ('truncate' , False )
474
516
475
517
# Make sure the number of time points match
476
518
if Umat .shape [1 ] != Ymat .shape [1 ]:
@@ -549,4 +591,4 @@ def markov(data, m=None, dt=True, truncate=False):
549
591
H = np .squeeze (H )
550
592
551
593
# Return the first m Markov parameters
552
- return H if not data . transpose else np .transpose (H )
594
+ return H if not transpose else np .transpose (H )
0 commit comments