Понимание scipy deconvolve
Я пытаюсь понятьscipy.signal.deconvolve
.
С математической точки зрения свертка - это просто умножение в пространстве Фурье, поэтому я ожидаю, что для двух функцийf
а такжеg
:Deconvolve(Convolve(f,g) , g) == f
В numpy / scipy это либо не тот случай, либо я упускаю важный момент. Хотя есть некоторые вопросы, связанные с деконволюцией на SO уже (например,Вот а такжеВот) они не обращаются к этому пункту, другие остаются неясными (этот) или без ответа (Вот). Есть также два вопроса о SignalProcessing SE (этот а такжеэтот) ответы на которые не помогают понять, как работает функция развертки Сципи.
Вопрос будет:
Как вы восстанавливаете исходный сигналf
из извилистого сигнала, предполагая, что вы знаете сверточную функцию г.Или другими словами: как работает этот псевдокодDeconvolve(Convolve(f,g) , g) == f
перевести на numpy / scipy?редактировать: Обратите внимание, что этот вопрос не направлен на предотвращение числовых неточностей (хотя это такжеоткрытый вопрос) но при понимании того, как свертывать / разворачивать работать вместе в scipy.
Следующий код пытается сделать это с помощью функции Хевисайда и гауссовского фильтра. Как видно на изображении, результат деконволюции свертки вовсе не является исходной функцией Хевисайда. Я был бы рад, если бы кто-то мог пролить свет на этот вопрос.
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.