Я пытаюсь понять scipy.signal.deconvolve
.
С математической точки зрения свертка - это просто умножение в пространстве Фурье, поэтому я ожидаю
что для двух функций f
и g
: Deconvolve(Convolve(f,g) , g) == f
В numpy/scipy это либо не так, либо мне не хватает важного момента. Хотя есть некоторые вопросы, связанные с deconvolve на SO уже (например, здесь и здесь), они не адресуют это, другие остаются неясными (this) или без ответа (здесь). Есть также два вопроса о SignalProcessing SE (this и this), ответы на которые не помогают в понимании как работает функция scipy deconvolve.
Вопрос:
- Как вы восстанавливаете исходный сигнал
f
из свернутого сигнала, предполагая, что вы знаете свертывающую функцию g.? - Или другими словами: как этот псевдокод
Deconvolve(Convolve(f,g) , g) == f
переводится в numpy/scipy?
Изменить. Обратите внимание: этот вопрос не предназначен для предотвращения числовых ошибок (хотя это также открытый вопрос ), но при понимании того, как convolve/deconvolve работают вместе в scipy.
Следующий код пытается сделать это с помощью функции Heaviside и гауссовского фильтра. Как видно на изображении, результат деконволюции свертки отсутствует все оригинальные функции Хевисайда. Я был бы рад, если бы кто-то мог пролить свет на этот вопрос.
import numpy as np
import scipy.signal
import matplotlib.pyplot as plt
# Define heaviside function
H = lambda x: 0.5 * (np.sign(x) + 1.)
#define gaussian
gauss = lambda x, sig: np.exp(-( x/float(sig))**2 )
X = np.linspace(-5, 30, num=3501)
X2 = np.linspace(-5,5, num=1001)
# convolute a heaviside with a gaussian
H_c = np.convolve( H(X), gauss(X2, 1), mode="same" )
# deconvolute a the result
H_dc, er = scipy.signal.deconvolve(H_c, gauss(X2, 1) )
#### Plot ####
fig , ax = plt.subplots(nrows=4, figsize=(6,7))
ax[0].plot( H(X), color="#907700", label="Heaviside", lw=3 )
ax[1].plot( gauss(X2, 1), color="#907700", label="Gauss filter", lw=3 )
ax[2].plot( H_c/H_c.max(), color="#325cab", label="convoluted" , lw=3 )
ax[3].plot( H_dc, color="#ab4232", label="deconvoluted", lw=3 )
for i in range(len(ax)):
ax[i].set_xlim([0, len(X)])
ax[i].set_ylim([-0.07, 1.2])
ax[i].legend(loc=4)
plt.show()
Изменить. Обратите внимание, что существует пример matlab, показывающий, как свертить/деконволюровать прямоугольный сигнал, используя
yc=conv(y,c,'full')./sum(c);
ydc=deconv(yc,c).*sum(c);
В духе этого вопроса это также помогло бы, если бы кто-то смог перевести этот пример в python.