Próbuję zrozumieć scipy.signal.deconvolve
.Zrozumienie scipy deconvolve
Z matematycznego punktu widzenia splot jest tylko mnożenie w przestrzeni Fouriera więc spodziewałbym że dla dwóch funkcji f
i g
:
Deconvolve(Convolve(f,g) , g) == f
W numpy/scipy to jest albo nie przypadek lub Brakuje mi ważnej sprawy. Mimo że istnieją pewne pytania związane z dekonvolve na SO już (jak here i here), nie odnoszą się do tego punktu, inne pozostają niejasne (this) lub nieodebrane (here). Są również dwa pytania dotyczące SignalProcessing SE (this i this), na które odpowiedzi nie są pomocne w zrozumieniu działania funkcji dekonwolucji scipy.
pytanie byłoby:
- Jak odtworzyć oryginalny sygnał
f
z zawiłe sygnału zakładając wiesz funkcję splatanie g.? - Innymi słowy: w jaki sposób ten pseudokod
Deconvolve(Convolve(f,g) , g) == f
przekształca się w numpy/scipy?
Edit: Należy zauważyć, że kwestia ta nie jest ukierunkowane na zapobieganie nieścisłości numeryczne (chociaż jest to także open question), ale na zrozumieniu, jak prace convolve/deconvolve razem w scipy.
Następujący kod próbuje to zrobić za pomocą funkcji Heaviside i filtru gaussowskiego. Jak widać na obrazku, wynikiem dekonwolucji splotu nie jest żadna oryginalna funkcja Heaviside. Byłbym szczęśliwy, gdyby ktoś mógł rzucić trochę światła na tę kwestię.
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()
Edit: Zauważ, że nie jest matlab example, pokazujący jak convolve/deconvolve prostokątny sygnał używając
yc=conv(y,c,'full')./sum(c);
ydc=deconv(yc,c).*sum(c);
W duchu tym pytaniu również pomogłoby, gdyby ktoś mógł przetłumaczyć ten przykład na pytona.
Running go z 'mode = full' daje rozsądny dobry wynik (do około 1000 indeksów, wtedy widoczne są efekty graniczne (?)); niestety nie wiem wystarczająco dużo o teorii. – Cleb
@Cleb Nice. Ale uruchamianie go za pomocą 'mode =" full "' przede wszystkim przesuwa zniekształcony sygnał tak, że krawędź znajduje się przy 1000 zamiast 500 w tym przypadku. Masz pojęcie o przyczynie? Jak mogę interpretować wynik splatanej tablicy w porównaniu z oryginalnym? – ImportanceOfBeingErnest
Jeszcze nie wiem. W [documentation] (https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.signal.deconvolve.html) jest podany przykład zabawki, gdzie działa idealnie; ale nie mam pojęcia, dlaczego twój wynik wygląda, jak się niestety wydaje. – Cleb