10000 Add sb10yd by KybernetikJo · Pull Request #203 · python-control/Slycot · GitHub
[go: up one dir, main page]

Skip to content

Add sb10yd #203

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Aug 26, 2023
Prev Previous commit
Next Next commit
Add unittest for discrete time case
  • Loading branch information
KybernetikJo committed Aug 25, 2023
commit 0b1530f677ad966f84d56be12aed333603a18118
81 changes: 79 additions & 2 deletions slycot/tests/test_sb10yd.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import numpy as np
from scipy import signal

import matplotlib.pyplot as plt

class test_sb10yd(unittest.TestCase):

def test_sb10yd_exec(self):
def test_sb10yd_cont_exec(self):
"""A simple execution test.
"""

Expand All @@ -32,7 +34,7 @@ def test_sb10yd_exec(self):
# Because flag = 0, we expect n == n_id
np.testing.assert_equal(n, n_id)

def test_sb10yd_allclose(self):
def test_sb10yd_cont_allclose(self):
"""Compare given and identified frequency response.
"""

Expand Down Expand Up @@ -68,5 +70,80 @@ def test_sb10yd_allclose(self):
# absolute(a-b) or absolute(b-a) <= atol, for rtol=0 element-wise true
np.testing.assert_allclose(abs(H_id),abs(H),rtol=0,atol=0.1)

def test_sb10yd_disc_exec(self):
"""A simple execution test.
"""

A = np.array([[0.0, 1.0], [-0.5, -0.1]])
B = np.array([[0.0], [1.0]])
C = np.array([[1.0, 0.0]])
D = np.zeros((1,1))

sys_tf = signal.ss2tf(A,B,C,D)
num, den = sys_tf

dt = 0.1
num, den, dt = signal.cont2discrete((num, den), dt, method="zoh")
print(den)

omega, H = signal.freqz(num.squeeze(), den)

real_H_resp = np.real(H)
imag_H_resp = np.imag(H)

n = 2
dico = 1 # 0 for continuous time
flag = 0 # 0 for no constraints on the poles
n_id, *_ = synthesis.sb10yd(
dico, flag, len(omega),
real_H_resp, imag_H_resp, omega, n, tol=0)

# Because flag = 0, we expect n == n_id
np.testing.assert_equal(n, n_id)

def test_sb10yd_disc_allclose(self):
"""Compare given and identified frequency response.
"""

A = np.array([[0.0, 1.0], [-0.5, -0.1]])
B = np.array([[0.0], [1.0]])
C = np.array([[1.0, 0.0]])
D = np.zeros((1,1))

sys_tf = signal.ss2tf(A,B,C,D)
num, den = sys_tf

dt = 0.01
num, den, dt = signal.cont2discrete((num, den), dt, method="zoh")

omega, H = signal.freqz(num.squeeze(), den)

real_H_resp = np.real(H)
imag_H_resp = np.imag(H)

n = 2
dico = 1 # 0 for discrete time
flag = 0 # 0 for no constraints on the poles
n_id, A_id, B_id, C_id, D_id = synthesis.sb10yd(
dico, flag, len(omega),
real_H_resp, imag_H_resp, omega, n, tol=0)

sys_id = signal.dlti(A_id,B_id,C_id,D_id, dt=dt)
sys_tf_id = signal.TransferFunction(sys_id)
num_id, den_id = sys_tf_id.num, sys_tf_id.den
w_id, H_id = signal.freqz(num_id.squeeze(), den_id, worN=omega)

#print(np.max(abs(H)-abs(H_id)), np.max(abs(H_id)-abs(H)))
#print(np.max(abs(H_id)/abs(H)))

#plt.loglog(omega, abs(H))
#plt.loglog(omega, abs(H_id))
#plt.show(block=True)

# Compare given and identified frequency response up to some toleration.
# absolute(a-b) <= atol + rtol*abolute(b), element-wise true
# absolute(a-b) or absolute(b-a) <= atol, for rtol=0 element-wise true
np.testing.assert_allclose(abs(H_id),abs(H),rtol=0,atol=1.0)

if __name__ == "__main__":
unittest.main()
0