8000 unit tests for infinite frequency response values, warnings · python-control/python-control@96e44fe · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 96e44fe

Browse files
committed
unit tests for infinite frequency response values, warnings
1 parent b67eb7d commit 96e44fe

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

control/lti.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -644,8 +644,9 @@ def dcgain(sys):
644644
Returns
645645
-------
646646
gain : ndarray
647-
The zero-frequency gain, or np.nan if the system has a pole
648-
at the origin
647+
The zero-frequency gain, or np.inf if the system has a pole at the
648+
origin, np.nan if there is a pole/zero cancellation at the origin.
649+
649650
"""
650651
return sys.dcgain()
651652

control/tests/freqresp_test.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,3 +364,73 @@ def test_phase_wrap(TF, wrap_phase, min_phase, max_phase):
364364
mag, phase, omega = ctrl.bode(TF, wrap_phase=wrap_phase)
365365
assert(min(phase) >= min_phase)
366366
assert(max(phase) <= max_phase)
367+
368+
369+
def test_freqresp_warn_infinite():
370+
"""Test evaluation of transfer functions at the origin"""
371+
sys_finite = ctrl.tf([1], [1, 0.01])
372+
sys_infinite = ctrl.tf([1], [1, 0.01, 0])
373+
374+
# Transfer function with finite zero frequency gain
375+
np.testing.assert_almost_equal(sys_finite(0), 100)
376+
np.testing.assert_almost_equal(sys_finite(0, warn_infinite=False), 100)
377+
np.testing.assert_almost_equal(sys_finite(0, warn_infinite=True), 100)
378+
379+
# Transfer function with infinite zero frequency gain
380+
with pytest.warns(RuntimeWarning, match="divide by zero"):
381+
np.testing.assert_almost_equal(sys_infinite(0), np.inf)
382+
with pytest.warns(RuntimeWarning, match="divide by zero"):
383+
np.testing.assert_almost_equal(
384+
sys_infinite(0, warn_infinite=True), np.inf)
385+
np.testing.assert_almost_equal(sys_infinite(0, warn_infinite=False), np.inf)
386+
387+
# Switch to state space
388+
sys_finite = ctrl.tf2ss(sys_finite)
389+
sys_infinite = ctrl.tf2ss(sys_infinite)
390+
391+
# State space system with finite zero frequency gain
392+
np.testing.assert_almost_equal(sys_finite(0), 100)
393+
np.testing.assert_almost_equal(sys_finite(0, warn_infinite=False), 100)
394+
np.testing.assert_almost_equal(sys_finite(0, warn_infinite=True), 100)
395+
396+
# State space system with infinite zero frequency gain
397+
with pytest.warns(RuntimeWarning, match="not finite"):
398+
np.testing.assert_almost_equal(sys_infinite(0), np.inf)
399+
with pytest.warns(RuntimeWarning, match="not finite"):
400+
np.testing.assert_almost_equal(sys_infinite(0), np.inf)
401+
np.testing.assert_almost_equal(sys_infinite(0, warn_infinite=True), np.inf)
402+
np.testing.assert_almost_equal(sys_infinite(0, warn_infinite=False), np.inf)
403+
404+
405+
def test_dcgain_consistency():
406+
"""Test to make sure that DC gain is consistently evaluated"""
407+
# Set up transfer function with pole at the origin
408+
sys_tf = ctrl.tf([1], [1, 0])
409+
assert 0 in sys_tf.pole()
410+
411+
# Set up state space system with pole at the origin
412+
sys_ss = ctrl.tf2ss(sys_tf)
413+
assert 0 in sys_ss.pole()
414+
415+
# Evaluation
416+
np.testing.assert_equal(sys_tf(0), np.inf + 0j)
417+
np.testing.assert_equal(sys_ss(0), np.inf + 0j)
418+
np.testing.assert_equal(sys_tf.dcgain(), np.inf + 0j)
419+
np.testing.assert_equal(sys_ss.dcgain(), np.inf + 0j)
420+
421+
# Set up transfer function with pole, zero at the origin
422+
sys_tf = ctrl.tf([1, 0], [1, 0])
423+
assert 0 in sys_tf.pole()
424+
assert 0 in sys_tf.zero()
425+
426+
sys_ss = ctrl.tf2ss(ctrl.tf([1, 0], [1, 1])) * \
427+
ctrl.tf2ss(ctrl.tf([1], [1, 0]))
428+
assert 0 in sys_ss.pole()
429+
assert 0 in sys_ss.zero()
430+
431+
# Pole and zero at the origin should give nan for the response
432+
np.testing.assert_equal(sys_tf(0), np.nan)
433+
np.testing.assert_equal(sys_tf.dcgain(), np.nan)
434+
# TODO: state space cases not yet working
435+
# np.testing.assert_equal(sys_ss(0), np.nan)
436+
# np.testing.assert_equal(sys_ss.dcgain(), np.nan)

control/tests/statesp_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ def test_dc_gain_discr(self):
523523
@pytest.mark.parametrize("dt", [None, 0, 1, True],
524524
ids=["dtNone", "c", "dt1", "dtTrue"])
525525
def test_dc_gain_integrator(self, outputs, inputs, dt):
526-
"""DC gain when eigenvalue at DC returns appropriately sized array of nan.
526+
"""DC gain w/ pole at origin returns appropriately sized array of inf.
527527
528528
the SISO case is also tested in test_dc_gain_{cont,discr}
529529
time systems (dt=0)

0 commit comments

Comments
 (0)
0