Skip to content

Commit 649215e

Browse files
authored
Merge pull request #525 from bnavigator/fix-523
fix #523: finding z for |H(z)|=1 computed the wrong polynomials
2 parents 6d51358 + 48a18d6 commit 649215e

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

control/margins.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,14 @@ def _poly_z_real_crossing(num, den, num_inv_zp, den_inv_zq, p_q, dt, epsw):
156156
return z, w
157157

158158

159-
def _poly_z_mag1_crossing(num, den, num_inv, den_inv, p_q, dt, epsw):
159+
def _poly_z_mag1_crossing(num, den, num_inv_zp, den_inv_zq, p_q, dt, epsw):
160160
# |H(z)| = 1, H(z)*H(1/z)=1, num(z)*num(1/z) == den(z)*den(1/z)
161-
p1 = np.polymul(num, num_inv)
162-
p2 = np.polymul(den, den_inv)
161+
p1 = np.polymul(num, num_inv_zp)
162+
p2 = np.polymul(den, den_inv_zq)
163163
if p_q < 0:
164+
# * z**(-p_q)
164165
x = [1] + [0] * (-p_q)
165-
p2 = np.polymul(p2, x)
166+
p1 = np.polymul(p1, x)
166167
z = np.roots(np.polysub(p1, p2))
167168
eps = np.finfo(float).eps**(1 / len(p2))
168169
z, w = _z_filter(z, dt, eps)
@@ -171,7 +172,7 @@ def _poly_z_mag1_crossing(num, den, num_inv, den_inv, p_q, dt, epsw):
171172
return z, w
172173

173174

174-
def _poly_z_wstab(num, den, num_inv, den_inv, p_q, dt, epsw):
175+
def _poly_z_wstab(num, den, num_inv_zp, den_inv_zq, p_q, dt, epsw):
175176
# Stability margin: Minimum distance to -1
176177

177178
# TODO: Find a way to solve for z or omega analytically with given

control/tests/margin_test.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -338,13 +338,19 @@ def test_zmore_stability_margins(tsys_zmore):
338338
'cnum, cden, dt,'
339339
'ref,'
340340
'rtol',
341-
[([2], [1, 3, 2, 0], 1e-2, # gh-465
342-
(2.9558, 32.8170, 0.43584, 1.4037, 0.74953, 0.97079),
343-
0.1 # very crude tolerance, because the gradients are not great
344-
),
345-
([2], [1, 3, 3, 1], .1, # 2/(s+1)**3
346-
[3.4927, 69.9996, 0.5763, 1.6283, 0.7631, 1.2019],
347-
1e-3)])
341+
[( # gh-465
342+
[2], [1, 3, 2, 0], 1e-2,
343+
[2.9558, 32.390, 0.43584, 1.4037, 0.74951, 0.97079],
344+
2e-3), # the gradient of the function reduces numerical precision
345+
( # 2/(s+1)**3
346+
[2], [1, 3, 3, 1], .1,
347+
[3.4927, 65.4212, 0.5763, 1.6283, 0.76625, 1.2019],
348+
1e-4),
349+
( # gh-523
350+
[1.1 * 4 * np.pi**2], [1, 2 * 0.2 * 2 * np.pi, 4 * np.pi**2], .05,
351+
[2.3842, 18.161, 0.26953, 11.712, 8.7478, 9.1504],
352+
1e-4),
353+
])
348354
def test_stability_margins_discrete(cnum, cden, dt, ref, rtol):
349355
"""Test stability_margins with discrete TF input"""
350356
tf = TransferFunction(cnum, cden).sample(dt)

0 commit comments

Comments
 (0)