# How can I correctly plot an impulse_response() of a discrete transfer function?

I posted this question on stack overflow and I think it was the wrong place so I moved it here.

Hello, I'm new to python, I just want to use the control library and I'm slowly learning, I did my research and read the docs but as a newbie programmer I don't really understand much. I know it's about the syntax but I don't know what exactly is wrong. I'm moving from matlab to python and I can't get this to work:

from control import *
from sympy import *
from numpy import *
from matplotlib.pyplot import *

Gp = tf(100,[1,0,100])
T = 0.05
Gz =sample_system(Gp, T)

x = linspace(0.0, 0.7, num=15)

T, yout = impulse_response(Gz, T=x)
plot(T, yout)


if I run this I get this output:

ValueError: Time steps T must match sampling time


and if I change x = linspace(0.0, 0.7, num=15) for x = linspace(0.05, 0.7, num=14) I get this:

ValueError: A value in x_new is below the interpolation range.


No idea what I'm doing wrong, I read the docs on impulse_response() and linspace(), I can't find any examples of similar problems or people plotting impulse responses using python. Thanks in advance

Edit1: Okay I've gotten here so far:

imp = signal.unit_impulse(100, 'mid')
T, yout = signal.butter(4, 0.2)
z = array([0.,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5])
T, yout = impulse_response(Gz, T=z, input=imp)
T, yout = signal.butter(4, 0.2)
plot(T, yout)
grid(True)
show()


now I get a plot that looks like this:

But I need something like this: Edit2: Okay seems like the whole problem was that yout had these dimensions: (1,15) and all I had to do was .flatten(), on the other hand I was using wrong linspace so I changed it for arange, and the end result is this:

Gp = tf(100,[1,0,100])
ts = 0.05
Gz =sample_system(Gp, ts)
pprint(Gz)

t = arange(0.0, 15*ts, ts)

T, yout = impulse_response(Gz, T=t)
yout=yout.flatten()
plot(T, yout)
margins(0.1, 0.1)
xlabel('Time [sec]')
ylabel('Amplitude')
grid(True)
show()


and the output is:

Still seems to me that something is missing, but I don't know what, and that this is not a clean solution, anyone got a cleaner way of doing this? Having to flatten() seems wrong to me... in matlab you just had to impulse(Gz, t) and got the plot right away.

• linspace() generates an np.array() object – endolith Nov 26 '19 at 19:18
• Allright, gonna edit it, seems like I was using it wrong then, thanks. – Wonky Nov 26 '19 at 19:27
• – endolith Nov 28 '19 at 1:52

So finally this is the way I got to plot it right:

Gp = ct.tf(100,[1,0,100])
ts = 0.05
Gz =ct.sample_system(Gp, ts)
sym.pprint(Gz)

t = np.linspace(0,14*ts,num=15)

T, yout = ct.impulse_response(Gz, t)
yout=yout.flatten()

fig, ax = plt.subplots()
ax.step(T, yout)
ax.yaxis.set_minor_locator(MultipleLocator(0.05))
ax.yaxis.set_major_locator(MultipleLocator(0.1))
plt.margins(0.1, 0.1)
plt.title('Impulse Response c.1)')
plt.xlabel('Time [sec]')
plt.ylabel('Amplitude')
plt.grid(True)
plt.show()


and this is the output:

this would be the equivalent of matlab's impulse() in python