Я пытаюсь понять scipy.signal.deconvolve
.Понимание scipy deconvolve
С математической точки зрения свертка просто умножение в Фурье пространстве, так что я бы ожидать , что для двух функций f
и g
:
Deconvolve(Convolve(f,g) , g) == f
В NumPy/SciPy это или не так, или Мне не хватает важного момента. Хотя есть еще вопросы, связанные с deconvolve на SO уже (например, here и here), они не затрагивают этот момент, другие остаются неясными (this) или без ответа (here). Также есть два вопроса по SignalProcessing SE (this и this), ответы на которые не помогают понять, как работает функция deconvolve от scipy.
вопрос будет:
- Как вы восстановить исходный сигнал
f
из свернутого сигнала, если вы знаете функцию свертки г.? - Или другими словами: Как этот псевдокод
Deconvolve(Convolve(f,g) , g) == f
перевести на numpy/scipy?
Edit: Обратите внимание, что этот вопрос не направлен на предотвращении численных неточностей (хотя это тоже open question), но при понимании того, как скручивать/деконволюцию работать вместе в SciPy.
Следующий код пытается сделать это с помощью функции Heaviside и gaussian filter. Как видно из изображения, результат деконволюции свертки не равен всей исходной функции Хевисайда. Я был бы рад, если бы кто-то мог пролить свет на этот вопрос.
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 example, показывающий, как свертка/деконволюция прямоугольного сигнала с использованием
yc=conv(y,c,'full')./sum(c);
ydc=deconv(yc,c).*sum(c);
В духе этого вопроса также помогло бы, если бы кто-то смог перевести этот пример в python.
Запуска его с 'mode = full' дает разумный хороший результат (пока вокруг индекса 1000, тогда не будут видны граничные эффекты (?)); К сожалению, не знаю достаточно о теории. – Cleb
@Cleb Ницца. Но запустив его с помощью 'mode =" full ", сначала сдвигается свернутый сигнал, так что в этом случае край находится на 1000 вместо 500. Любая идея о причине? Как я могу интерпретировать результат свернутого массива по сравнению с исходным? – ImportanceOfBeingErnest
Пока не знаю. В [документации] (https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.signal.deconvolve.html) представлен небольшой пример игрушки, где он отлично работает; но я не знаю, почему ваш результат выглядит, похоже, к сожалению. – Cleb