@@ -29,6 +29,12 @@ def setUp(self):
2929 # Create some transfer functions
3030 self .siso_tf1 = TransferFunction ([1 ], [1 , 2 , 1 ])
3131 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 ])
3238
3339 # Create MIMO system, contains ``siso_ss1`` twice
3440 A = np .matrix ("1. -2. 0. 0.;"
@@ -167,6 +173,14 @@ def test_step_info(self):
167173 2.50 ,
168174 rtol = rtol )
169175
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+
170184 def test_impulse_response (self ):
171185 # Test SISO system
172186 sys = self .siso_ss1
@@ -348,33 +362,41 @@ def test_step_robustness(self):
348362 sys2 = TransferFunction (num , den2 )
349363
350364 # 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 )
353367 np .testing .assert_array_almost_equal (y1 , y2 )
354368
355369 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
357371 p = 0.5
372+ ratio = 9.21034 * p # taken from code
373+ ratio2 = 25 * p
358374 np .testing .assert_array_almost_equal (
359375 _ideal_tfinal_and_dt (TransferFunction (1 , [1 , .5 ]))[0 ],
360- (7 / p ))
376+ (ratio / p ))
361377 np .testing .assert_array_almost_equal (
362378 _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
365381 np .testing .assert_array_almost
DC9C
_equal (
366382 _ideal_tfinal_and_dt (TransferFunction (1 , [1 , .5 , 0 ]))[0 ],
367- (7 / p ))
383+ (ratio2 / p ))
384+
368385 # 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)
370387 wn = 10
388+ ratio_dt = 1 / (0.025133 * ratio * wn )
371389 np .testing .assert_array_almost_equal (
372390 _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 ))
374396 zeta = .1
375397 np .testing .assert_array_almost_equal (
376398 _ideal_tfinal_and_dt (TransferFunction (1 , [1 , 2 * zeta * wn , wn ** 2 ]))[1 ],
377- 1 / (7.0 * wn ))
399+ 1 / (ratio_dt * ratio * wn ))
378400 # but a smapled one keeps its dt
379401 np .testing .assert_array_almost_equal (
380402 _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):
384406 .1 )
385407 np .testing .assert_array_almost_equal (
386408 _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+
388412 # TF with fast oscillations simulates only 5000 time steps even with long tfinal
389413 self .assertEqual (5000 ,
390414 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 ))))
395415
396416 sys = TransferFunction (1 , [1 , .5 , 0 ])
397417 sysdt = TransferFunction (1 , [1 , .5 , 0 ], .1 )
398418 # test impose number of time steps
399419 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 ]))
401422 # test impose final time
402423 np .testing .assert_array_almost_equal (
403424 100 ,
404- step_response (sys , 100 )[0 ][- 1 ],
405- decimal = .5 )
425+ np .ceil (step_response (sys , 100 )[0 ][- 1 ]))
406426 np .testing .assert_array_almost_equal (
407427 100 ,
408- step_response (sysdt , 100 )[0 ][- 1 ],
409- decimal = .5 )
428+ np .ceil (step_response (sysdt , 100 )[0 ][- 1 ]))
410429 np .testing .assert_array_almost_equal (
411430 100 ,
412- impulse_response (sys , 100 )[0 ][- 1 ],
413- decimal = .5 )
431+ np .ceil (impulse_response (sys , 100 )[0 ][- 1 ]))
414432 np .testing .assert_array_almost_equal (
415433 100 ,
416- initial_response (sys , 100 )[0 ][- 1 ],
417- decimal = .5 )
434+ np .ceil (initial_response (sys , 100 )[0 ][- 1 ]))
418435
419436
420437 def test_time_vector (self ):
0 commit comments