Skip to content

Commit 317d261

Browse files
committed
Change output to ndarray
1 parent 446a161 commit 317d261

File tree

3 files changed

+63
-43
lines changed

3 files changed

+63
-43
lines changed

control/modelsimp.py

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -438,21 +438,9 @@ def markov(data, m=None, dt=True, truncate=False):
438438
439439
Returns
440440
-------
441-
H : TimeResponseData
442-
Markov parameters / impulse response [D CB CAB ...] represented as
443-
a :class:`TimeResponseData` object containing the following properties:
444-
445-
* time (array): Time values of the output.
446-
447-
* outputs (array): Response of the system. If the system is SISO,
448-
the array is 1D (indexed by time). If the
449-
system is not SISO, the array is 3D (indexed
450-
by the output, trace, and time).
451-
452-
* inputs (array): Inputs of the system. If the system is SISO,
453-
the array is 1D (indexed by time). If the
454-
system is not SISO, the array is 3D (indexed
455-
by the output, trace, and time).
441+
H : ndarray
442+
First m Markov parameters, [D CB CAB ...]
443+
456444
457445
Notes
458446
-----
@@ -557,23 +545,8 @@ def markov(data, m=None, dt=True, truncate=False):
557545
H = H.reshape(q,m,p) # output, time*input -> output, time, input
558546
H = H.transpose(0,2,1) # output, input, time
559547

560-
# Create unit area impulse inputs
561-
inputs = np.zeros((p,p,m))
562-
trace_labels, trace_types = [], []
563-
for i in range(p):
564-
inputs[i,i,0] = 1/dt # unit area impulse
565-
trace_labels.append(f"From {data.input_labels[i]}")
566-
trace_types.append('impulse')
548+
if q == 1 and p == 1:
549+
H = np.squeeze(H)
567550

568-
# Markov parameters as TimeResponseData with unit area impulse inputs
569551
# Return the first m Markov parameters
570-
return TimeResponseData(time=data.time[:m],
571-
outputs=H,
572-
output_labels=data.output_labels,
573-
inputs=inputs,
574-
input_labels=data.input_labels,
575-
trace_labels=trace_labels,
576-
trace_types=trace_types,
577-
transpose=data.transpose,
578-
plot_inputs=False,
579-
issiso=data.issiso)
552+
return H if not data.transpose else np.transpose(H)

control/tests/modelsimp_test.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,17 @@ def testMarkovSignature(self):
4444
m = 3
4545
H = markov(response, m)
4646
Htrue = np.array([1., 0., 0.])
47-
np.testing.assert_array_almost_equal(H.outputs, Htrue)
47+
np.testing.assert_array_almost_equal(H, Htrue)
4848

4949
# Make sure that transposed data also works
5050
response.transpose=True
5151
H = markov(response, m)
52-
np.testing.assert_array_almost_equal(H.outputs, np.transpose(Htrue))
52+
np.testing.assert_array_almost_equal(H, np.transpose(Htrue))
5353

5454
# Generate Markov parameters without any arguments
5555
response.transpose=False
5656
H = markov(response, m)
57-
np.testing.assert_array_almost_equal(H.outputs, Htrue)
57+
np.testing.assert_array_almost_equal(H, Htrue)
5858

5959
# Test example from docstring
6060
T = np.linspace(0, 10, 100)
@@ -119,7 +119,7 @@ def testMarkovResults(self, k, m, n):
119119
# experimentally determined probability to get non matching results
120120
# with rtot=1e-6 and atol=1e-8 due to numerical errors
121121
# for k=5, m=n=10: 0.015 %
122-
np.testing.assert_allclose(Mtrue, Mcomp.outputs, rtol=1e-6, atol=1e-8)
122+
np.testing.assert_allclose(Mtrue, Mcomp, rtol=1e-6, atol=1e-8)
123123

124124
def testModredMatchDC(self):
125125
#balanced realization computed in matlab for the transfer function:

examples/markov.py

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,43 @@
1010

1111
import control as ct
1212

13+
def create_impulse_response(H, time, transpose, dt):
14+
"""Helper function to use TimeResponseData type for plotting"""
15+
16+
H = np.array(H, ndmin=3)
17+
18+
if transpose:
19+
H = np.transpose(H)
20+
21+
q, p, m = H.shape
22+
inputs = np.zeros((p,p,m))
23+
24+
issiso = True if (q == 1 and p == 1) else False
25+
26+
input_labels = []
27+
trace_labels, trace_types = [], []
28+
for i in range(p):
29+
inputs[i,i,0] = 1/dt # unit area impulse
30+
input_labels.append(f"u{[i]}")
31+
trace_labels.append(f"From u{[i]}")
32+
trace_types.append('impulse')
33+
34+
output_labels = []
35+
for i in range(q):
36+
output_labels.append(f"y{[i]}")
37+
38+
return ct.TimeResponseData(time=time[:m],
39+
outputs=H,
40+
output_labels=output_labels,
41+
inputs=inputs,
42+
input_labels=input_labels,
43+
trace_labels=trace_labels,
44+
trace_types=trace_types,
45+
sysname="H_est",
46+
transpose=transpose,
47+
plot_inputs=False,
48+
issiso=issiso)
49+
1350
# set up a mass spring damper system (2dof, MIMO case)
1451
# m q_dd + c q_d + k q = u
1552
m1, k1, c1 = 1., 1., .1
@@ -41,19 +78,29 @@
4178

4279
dt = 0.5
4380
sysd = sys.sample(dt, method='zoh')
81+
sysd.name = "H_true"
4482

45-
t = np.arange(0,5000,dt)
46-
u = np.random.randn(sysd.B.shape[-1], len(t)) # random forcing input
83+
# random forcing input
84+
t = np.arange(0,500,dt)
85+
u = np.random.randn(sysd.B.shape[-1], len(t))
4786

4887
response = ct.forced_response(sysd, U=u)
4988
response.plot()
5089
plt.show()
5190

52-
markov_true = ct.impulse_response(sysd,T=dt*100)
53-
markov_est = ct.markov(response,m=100,dt=dt)
91+
m = 100
92+
ir_true = ct.impulse_response(sysd,T=dt*m)
93+
ir_true.tranpose = True
94+
95+
H_est = ct.markov(response,m=m,dt=dt)
96+
# Helper function for plotting only
97+
ir_est = create_impulse_response(H_est,
98+
ir_true.time,
99+
ir_true.transpose,
100+
dt)
54101

55-
markov_true.plot(title=xixo)
56-
markov_est.plot(color='orange',linestyle='dashed')
102+
ir_true.plot(title=xixo)
103+
ir_est.plot(color='orange',linestyle='dashed')
57104
plt.show()
58105

59106
if 'PYCONTROL_TEST_EXAMPLES' not in os.environ:

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy