@@ -29,6 +29,12 @@ def setUp(self):
29
29
# Create some transfer functions
30
30
self .siso_tf1 = TransferFunction ([1 ], [1 , 2 , 1 ])
31
31
self .siso_tf2 = _convert_to_transfer_function (self .siso_ss1 )
32
+
33
+ # tests for pole cancellation
34
+ self .pole_cancellation = TransferFunction ([1.067e+05 , 5.791e+04 ],
35
+ [10.67 , 1.067e+05 , 5.791e+04 ])
36
+ self .no_pole_cancellation = TransferFunction ([1.881e+06 ],
37
+ [188.1 , 1.881e+06 ])
32
38
33
39
# Create MIMO system, contains ``siso_ss1`` twice
34
40
A = np .matrix ("1. -2. 0. 0.;"
@@ -167,6 +173,14 @@ def test_step_info(self):
167
173
2.50 ,
168
174
rtol = rtol )
169
175
176
+ # confirm that pole-zero cancellation doesn't perturb results
177
+ # https://github.com/python-control/python-control/issues/440
178
+ step_info_no_cancellation = step_info (self .no_pole_cancellation )
179
+ step_info_cancellation = step_info (self .pole_cancellation )
180
+ for key in step_info_no_cancellation :
181
+ np .testing .assert_allclose (step_info_no_cancellation [key ],
182
+ step_info_cancellation [key ], rtol = 1e-4 )
183
+
170
184
def test_impulse_response (self ):
171
185
# Test SISO system
172
186
sys = self .siso_ss1
@@ -348,33 +362,41 @@ def test_step_robustness(self):
348
362
sys2 = TransferFunction (num , den2 )
349
363
350
364
# Compute step response from input 1 to output 1, 2
351
- t1 , y1 = step_response (sys1 , input = 0 , T_num = 100 )
352
- t2 , y2 = step_response (sys2 , input = 0 , T_num = 100 )
365
+ t1 , y1 = step_response (sys1 , input = 0 , T = 2 , T_num = 100 )
366
+ t2 , y2 = step_response (sys2 , input = 0 , T = 2 , T_num = 100 )
353
367
np .testing .assert_array_almost_equal (y1 , y2 )
354
368
355
369
def test_auto_generated_time_vector (self ):
356
- # confirm a TF with a pole at p simulates for 7.0 /p seconds
370
+ # confirm a TF with a pole at p simulates for ratio /p seconds
357
371
p = 0.5
372
+ ratio = 9.21034 * p # taken from code
373
+ ratio2 = 25 * p
358
374
np .testing .assert_array_almost_equal (
359
375
_ideal_tfinal_and_dt (TransferFunction (1 , [1 , .5 ]))[0 ],
360
- (7 / p ))
376
+ (ratio / p ))
361
377
np .testing .assert_array_almost_equal (
362
378
_ideal_tfinal_and_dt (TransferFunction (1 , [1 , .5 ]).sample (.1 ))[0 ],
363
- (7 / p ))
364
- # confirm a TF with poles at 0 and p simulates for 7.0 /p seconds
379
+ (ratio2 / p ))
380
+ # confirm a TF with poles at 0 and p simulates for ratio /p seconds
365
381
np .testing .assert_array_almost_equal (
366
382
_ideal_tfinal_and_dt (TransferFunction (1 , [1 , .5 , 0 ]))[0 ],
367
- (7 / p ))
383
+ (ratio2 / p ))
384
+
368
385
# confirm a TF with a natural frequency of wn rad/s gets a
369
- # dt of 1/(7.0 *wn)
386
+ # dt of 1/(ratio *wn)
370
387
wn = 10
388
+ ratio_dt = 1 / (0.025133 * ratio * wn )
371
389
np .testing .assert_array_almost_equal (
372
390
_ideal_tfinal_and_dt (TransferFunction (1 , [1 , 0 , wn ** 2 ]))[1 ],
373
- 1 / (7.0 * wn ))
391
+ 1 / (ratio_dt * ratio * wn ))
392
+ wn = 100
393
+ np .testing .assert_array_almost_equal (
394
+ _ideal_tfinal_and_dt (TransferFunction (1 , [1 , 0 , wn ** 2 ]))[1 ],
395
+ 1 / (ratio_dt * ratio * wn ))
374
396
zeta = .1
375
397
np .testing .assert_array_almost_equal (
376
398
_ideal_tfinal_and_dt (TransferFunction (1 , [1 , 2 * zeta * wn , wn ** 2 ]))[1 ],
377
- 1 / (7.0 * wn ))
399
+ 1 / (ratio_dt * ratio * wn ))
378
400
# but a smapled one keeps its dt
379
401
np .testing .assert_array_almost_equal (
380
402
_ideal_tfinal_and_dt (TransferFunction (1 , [1 , 2 * zeta * wn , wn ** 2 ]).sample (.1 ))[1 ],
@@ -384,37 +406,32 @@ def test_auto_generated_time_vector(self):
384
406
.1 )
385
407
np .testing .assert_array_almost_equal (
386
408
_ideal_tfinal_and_dt (TransferFunction (1 , [1 , 2 * zeta * wn , wn ** 2 ]))[1 ],
387
- 1 / (7.0 * wn ))
409
+ 1 / (ratio_dt * ratio * wn ))
410
+
411
+
388
412
# TF with fast oscillations simulates only 5000 time steps even with long tfinal
389
413
self .assertEqual (5000 ,
390
414
len (_default_time_vector (TransferFunction (1 , [1 , 0 , wn ** 2 ]),tfinal = 100 )))
391
- # and simulates for 7.0/dt time steps
392
- self .assertEqual (
393
- len (_default_time_vector (TransferFunction (1 , [1 , 0 , wn ** 2 ]))),
394
- int (7.0 / (1 / (7.0 * wn ))))
395
415
396
416
sys = TransferFunction (1 , [1 , .5 , 0 ])
397
417
sysdt = TransferFunction (1 , [1 , .5 , 0 ], .1 )
398
418
# test impose number of time steps
399
419
self .assertEqual (10 , len (step_response (sys , T_num = 10 )[0 ]))
400
- self .assertEqual (10 , len (step_response (sysdt , T_num = 10 )[0 ]))
420
+ # test that discrete ignores T_num
421
+ self .assertNotEqual (15 , len (step_response (sysdt , T_num = 15 )[0 ]))
401
422
# test impose final time
402
423
np .testing .assert_array_almost_equal (
403
424
100 ,
404
- step_response (sys , 100 )[0 ][- 1 ],
405
- decimal = .5 )
425
+ np .ceil (step_response (sys , 100 )[0 ][- 1 ]))
406
426
np .testing .assert_array_almost_equal (
407
427
100 ,
408
- step_response (sysdt , 100 )[0 ][- 1 ],
409
- decimal = .5 )
428
+ np .ceil (step_response (sysdt , 100 )[0 ][- 1 ]))
410
429
np .testing .assert_array_almost_equal (
411
430
100 ,
412
- impulse_response (sys , 100 )[0 ][- 1 ],
413
- decimal = .5 )
431
+ np .ceil (impulse_response (sys , 100 )[0 ][- 1 ]))
414
432
np .testing .assert_array_almost_equal (
415
433
100 ,
416
- initial_response (sys , 100 )[0 ][- 1 ],
417
- decimal = .5 )
434
+ np .ceil (initial_response (sys , 100 )[0 ][- 1 ]))
418
435
419
436
420
437
def test_time_vector (self ):
0 commit comments