Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Refactor api, keep old api working
  • Loading branch information
KybernetikJo committed Jul 11, 2024
commit a3276b72f32a0b2174f4724252e8877be1465b17
58 changes: 24 additions & 34 deletions control/modelsimp.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ def era(YY, m, n, nin, nout, r):
raise NotImplementedError('This function is not implemented yet.')


def markov(*args, **kwargs):
def markov(*args, m=None, transpose=False, dt=True, truncate=False):
"""markov(Y, U, [, m])

Calculate the first `m` Markov parameters [D CB CAB ...]
Expand All @@ -420,12 +420,12 @@ def markov(*args, **kwargs):
the input data is less than the desired number of Markov parameters (a
warning message is generated in this case).

The function can be called with either 1, 2, or 3 arguments:
The function can be called with either 1, 2 or 3 arguments:

* ``K, S, E = lqr(response)``
* ``K, S, E = lqr(respnose, m)``
* ``K, S, E = lqr(Y, U)``
* ``K, S, E = lqr(Y, U, m)``
* ``H = markov(response)``
* ``H = markov(respnose, m)``
* ``H = markov(Y, U)``
* ``H = markov(Y, U, m)``

where `response` is an `TimeResponseData` object, and `Y`, `U`, are 1D or 2D
array and m is an integer.
Expand All @@ -446,26 +446,20 @@ def markov(*args, **kwargs):
Number of Markov parameters to output. Defaults to len(U).
dt : True of float, optional
True indicates discrete time with unspecified sampling time,
positive number is discrete time with specified sampling time.
It can be used to scale the markov parameters in order to match
the impulse response of this library.
Default values is True.
positive number is discrete time with specified sampling time.It
can be used to scale the markov parameters in order to match the

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Markov should be capitalized.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

impulse response of this library. Default is True.
truncate : bool, optional
Do not use first m equation for least least squares.
Default value is False.
Do not use first m equation for least least squares. Default is False.
transpose : bool, optional
Assume that input data is transposed relative to the standard
:ref:`time-series-convention`. For TimeResponseData this parameter
is ignored. Default is False.

Returns
-------
H : ndarray
First m Markov parameters, [D CB CAB ...]


Notes
-----
It works for SISO and MIMO systems.

This function does comply with the Python Control Library
:ref:`time-series-convention` for representation of time series data.

References
----------
Expand Down Expand Up @@ -494,25 +488,21 @@ def markov(*args, **kwargs):
transpose = args[0].transpose
if args[0].transpose and not args[0].issiso:
Umat, Ymat = np.transpose(Umat), np.transpose(Ymat)
index = 1
if (len(args) == 2):
m = args[1]
elif (len(args) > 2):
raise ControlArgument("too many positional arguments")
else:
if (len(args) < 2):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK to remove parens (here and below).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

raise ControlArgument("not enough input arguments")
Umat = np.array(args[0], ndmin=2)
Ymat = np.array(args[1], ndmin=2)
transpose = kwargs.pop('transpose', False)
Umat = np.array(args[1], ndmin=2)
Ymat = np.array(args[0], ndmin=2)
if transpose:
Umat, Ymat = np.transpose(Umat), np.transpose(Ymat)
index = 2


if (len(args) > index):
m = args[index]
else:
m = None

dt = kwargs.pop('dt', True)
truncate = kwargs.pop('truncate', False)
if (len(args) == 3):
m = args[2]
elif (len(args) > 3):
raise ControlArgument("too many positional arguments")

# Make sure the number of time points match
if Umat.shape[1] != Ymat.shape[1]:
Expand Down
25 changes: 15 additions & 10 deletions control/tests/modelsimp_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ def testMarkovSignature(self):
m = 3
Htrue = np.array([1., 0., 0.])

H = markov(Y, U, m, transpose=False)
H = markov(Y, U, m=m, transpose=False)
np.testing.assert_array_almost_equal(H, Htrue)

response.transpose=False
H = markov(response, m)
H = markov(response, m=m)
np.testing.assert_array_almost_equal(H, Htrue)

# Make sure that transposed data also works
Expand All @@ -68,20 +68,25 @@ def testMarkovSignature(self):
H = markov(response, m)
np.testing.assert_array_almost_equal(H, Htrue)

H = markov(Y, U, m=m)
np.testing.assert_array_almost_equal(H, Htrue)

H = markov(response, m=m)
np.testing.assert_array_almost_equal(H, Htrue)

# Test example from docstring
# TODO: There is a problem here
# Htrue = np.array([1., 0.5, 0.])
# TODO: There is a problem here, last markov parameter does not fit
# the approximation error could be to big
Htrue = np.array([0, 1., -0.5])
T = np.linspace(0, 10, 100)
U = np.ones((1, 100))
T, Y = forced_response(tf([1], [1, 0.5], True), T, U)
H = markov(Y, U, 3, transpose=False)
#np.testing.assert_array_almost_equal(H, Htrue)
H = markov(Y, U, 4, transpose=False)
np.testing.assert_array_almost_equal(H[:3], Htrue[:3])

T = np.linspace(0, 10, 100)
U = np.ones((1, 100))
response = forced_response(tf([1], [1, 0.5], True), T, U)
H = markov(response, 3)
#np.testing.assert_array_almost_equal(H, Htrue)
H = markov(response, 4)
np.testing.assert_array_almost_equal(H[:3], Htrue[:3])

# Test example from issue #395
inp = np.array([1, 2])
Expand Down