Я новичок в цифровой обработке сигналов, и при разработке моего первого подхода к управлению на основе моделей я впервые столкнулся с необходимостью вычислить свертку вне любого школьного контекста (мой опыт - еще одна область численного моделирования). Я адаптировал код из этого вопроса к своей проблеме, для которой я эмпирически знаю время шага отклика, и все отлично подходит. Я понимаю необходимость без труда умножить impulse_response
из моей системы на временной шаг.
tend = 600.0 # Total time [s]
dt = 15.0 # Time step [s]
k = 0.01 # Time constant [s]
sp = 0.15 # Step height [a.u.]
# Time interval
t = np.arange(0, tend + 1, dt)
# Define step function.
H = np.ones_like(t)
H[0] = 0.5
def impulse_response(t):
""" Unit response. """
return k * np.exp(-k * t) * H
# Response to step. Multiply by dt in discrete case.
response = np.convolve(H, impulse_response(t) * dt, 'full')
response = response[:len(response)//2]
# Define new, longer, time array for plotting response - must
# be same length as response, with step dt
tp = np.arange(len(response)) * dt
t = np.arange(-tend, tend, dt)
Hp = sp * np.ones_like(t)
Hp[t < 0] = 0.0
plt.style.use('bmh')
plt.step(t, Hp, label='Unit step function')
plt.plot(tp, sp * response, label='Response')
plt.tight_layout()
plt.xlabel('Time (s)')
plt.ylabel('Response [a.u.]')
plt.xlim(-100, tend + 1)
plt.legend()
Единственный момент, который я не понимаю в приведенном выше коде, - почему я получаю разные результаты, если я не умножайте на H
в приведенной ниже функции (как указано в справочном ответе и из моего понимания, поскольку моя высота шага равна нулю для t <0, это не должно иметь никакого значения). </p>
def impulse_response(t):
""" Unit response. """
return k * np.exp(-k * t) * H
Моя проблема: в реальном приложении к динамической системе у меня будут произвольные сигналы, для которых нужно будет вычислить свертку. Чтобы убедиться, что я хорошо понял постановку проблемы и проверить следующие шаги в разработке, я попытался проверить, как эта функция будет работать для одного единичного дельта-импульса. Длительность такой дельты равна нулю, я считаю, что это причина того, почему мне не нужно умножать на dt
в случае одиночного импульса. Это правильно? Таким образом я получаю ожидаемое аналитическое решение, но не уверен в своем заключении. Здесь следует модифицированный код.
# Define impulse function.
d = np.zeros_like(t)
d[0] = 1.0
def impulse_response(t):
""" Unit response. """
return k * np.exp(-k * t)
# Response to impulse. Multiply by dt in discrete case.
response = np.convolve(d, impulse_response(t), 'full')
response = response[:len(response)//2]
# Define new, longer, time array for plotting response - must
# be same length as response, with step dt
tp = np.arange(len(response)) * dt
plt.style.use('bmh')
plt.plot(tp, response, label='Response')
plt.plot(tp, k * np.exp(-k * tp), label='Analytical')
plt.tight_layout()
plt.xlabel('Time (s)')
plt.ylabel('Response [a.u.]')
plt.legend()