4343# External packages and modules
4444import numpy as np
4545import warnings
46- from .exception import ControlSlycot , ControlMIMONotImplemented , \
47- ControlDimension
46+ from .exception import ControlSlycot , ControlArgument , ControlDimension
4847from .iosys import isdtime , isctime
4948from .statesp import StateSpace
5049from .statefbk import gram
@@ -403,8 +402,10 @@ def era(YY, m, n, nin, nout, r):
403402 raise NotImplementedError ('This function is not implemented yet.' )
404403
405404
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 ...]
408409 from data
409410
410411 This function computes the Markov parameters for a discrete time system
@@ -419,14 +420,31 @@ def markov(data, m=None, dt=True, truncate=False):
419420 the input data is less than the desired number of Markov parameters (a
420421 warning message is generated in this case).
421422
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+
422433 Parameters
423434 ----------
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`.
424442 data : TimeResponseData
425443 Response data from which the Markov parameters where estimated.
426444 Input and output data must be 1D or 2D array.
427445 m : int, optional
428446 Number of Markov parameters to output. Defaults to len(U).
429- dt : ( True of float, optional)
447+ dt : True of float, optional
430448 True indicates discrete time with unspecified sampling time,
431449 positive number is discrete time with specified sampling time.
432450 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):
460478 --------
461479 >>> T = np.linspace(0, 10, 100)
462480 >>> 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 )
465483
466484 """
467485 # 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 )
470486
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 )
474516
475517 # Make sure the number of time points match
476518 if Umat .shape [1 ] != Ymat .shape [1 ]:
@@ -549,4 +591,4 @@ def markov(data, m=None, dt=True, truncate=False):
549591 H = np .squeeze (H )
550592
551593 # 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