Reputation: 143
I have two numpy
arrays. each one containing a kernel-like function centered on zero, perfectly symmetric, both with a length of 101. When I convolve these arrays, should I expect, as a result, another array which is also centered on zero? I am using numpy.convolve
, and I always get a resulting kernel array which is not centered on zero, which is not what I want: I need one that is also perfectly centered, not shifted.
My code is more or less like this:
import numpy as np
import matplotlib.pyplot as plt
x = np.array([...]) # x-axis
array1 = np.array([...]) # Blue curve
array2 = np.array([...]) # Green curve
# All arrays are one-dimensional
conv_array = np.convolve(array1, array2, mode='same') # Red curve
conv_array /= max(conv_array) # Normalization
plt.plot(x, array1)
plt.plot(x, array2)
plt.plot(x, conv_array)
plt.show()
The resulting plot of the curves is this:
What do I do to obtain a not-shifted convolved array?
Upvotes: 4
Views: 3102
Reputation: 152637
One very simple alternative is to use scipy.ndimage.convolve1d
instead of numpy.convolve
.
import numpy as np
import matplotlib.pyplot as plt
from astropy.modeling import models
# Create a model
x = np.arange(101) - 50 # x-axis
g1 = models.Gaussian1D(amplitude=2, mean=0, stddev=4)
g2 = models.Gaussian1D(amplitude=3, mean=0, stddev=3)
array1 = g1(x)
array2 = 1 - g2(x)
from scipy.ndimage import convolve1d
conv_array2 = convolve1d(array1, array2)
conv_array2 /= conv_array2.max()
# One can also use numpy convolve here
conv_array = np.convolve(array1, array2, mode='same') # Red curve
conv_array /= max(conv_array) # Normalization
plt.plot(x, array1)
plt.plot(x, array2)
plt.plot(x, conv_array) # Is centered on 0
plt.plot(x, conv_array2) # Is centered on 0
plt.show()
I guess the problem is that your arrays are not exactly centered on 0. (So x[50] != 0
). And numpy flips the kernel before convolution and therefore you get a shift. Notice if you try my example the numpy.convolve
result is also perfectly centered on 0 but I made sure array1
and array2
were centered on 0. From your plot I guess that -22<x<27
(which is not centered)
The reason why I recommend scipy
is because I also had a similar problem :-) They just use different definitions: numpy and scipy notice the different signs of the kernel-index.
Upvotes: 2
Reputation: 910
I fear this is a mathematical question on convolution, which I cannot answer. However if you simply wish to center the convolved array on zero (its minima) then the following will provide a 'quick fix':
plt.plot(x + x[np.argmin(conv_array[:conv_array.shape[0]*3/4)]],conv_array)
Upvotes: 0