To resolve some of these issues I'm examining the 1d instance, using the following code.
One difference between the numerical integration and the fftconvolve, is the magnitude of the
convolution ; this is usually larger for fftconvolve. I have yet to find a way to bring them into alignment.
# Some code from :
#
https://dspillustrations.com/pages/posts/misc/convolution-examples-and-the-convolution-integral.html import matplotlib.pyplot as plt
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np
from scipy.fftpack import fftn, ifftn, fftshift
from scipy.integrate import simps
import scipy.signal as sg
# ----------------------------------------------------------------------
def showConvolution(f1, f2, t0):
# Calculate the overall convolution result using Simpson integration
convolution = np.zeros(len(t))
for n, t_ in enumerate(t):
prod = lambda tau: f1(tau) * f2(t_-tau)
convolution[n] = simps(prod(t), t)
# Create the shifted and flipped function
f_shift = lambda t: f2(t0-t)
prod = lambda tau: f1(tau) * f2(t0-tau)
# Plot the curves
#plt.subplot(211)
#plt.plot(t, f1(t), label=r'$f_1(\tau)$')
# plt.plot(t, f_shift(t), label=r'$f_2(t_0-\tau)$')
# plt.plot(t, prod(t), 'r-', label=r'$f_1(\tau)f_2(t_0-\tau)$')
# plot the convolution curve
# plt.subplot(212)
plt.plot(t, convolution, label='$(f_1*f_2)(t)$')
# recalculate the value of the convolution integral at the current time-shift t0
current_value = simps(prod(t), t)
plt.plot(t0, current_value, 'ro') # plot the point
# ----------------------------------------------------------------------
Fs = 50 # our sampling frequency for the plotting
Fs = 128
T = 5 # the time range we are interested in
t = np.arange(-T, T, 1/Fs) # the time samples
#f1 = lambda t: 0.7*(abs(t)<0.5).astype(float)
#f2 = lambda t: 0.8*(abs(t-0.62)<0.75).astype(float)
f1 = lambda t: np.maximum(0, 1-abs(t))
f2 = lambda t: (t>0) * np.exp(-t)
plt.figure(figsize=(8,3))
plt.subplot(211)
plt.plot(t, f1(t), label='$f_1(t)$')
plt.plot(t, f2(t), label='$f_2(t)$')
for i in range(20):
t0=-5+10*i/20
showConvolution(f1, f2, t0)
# plt.show()
# Now attempting discretization .
# t = np.arange(-T, T, 1/Fs) # the time samples
# f1 = lambda t: np.maximum(0, 1-abs(t))
# f2 = lambda t: (t>0) * np.exp(-2*t)
def g1(t0):
return np.maximum(0, 1-abs(t0))
def g2(t0):
if(t0>0):
return np.exp(-t0)
else:
return 0
# f1 = lambda t: (abs(t)<0.5).astype(float)
# f2 = lambda t: 0.8*(abs(t-0.2)<0.75).astype(float)
pwr=7
n=int(2**pwr)
#n=128 # 2^7
a1=np.zeros((n))
b1=np.zeros((n))
for i in range(n):
t0=-5+10*float(i)/(n-1)
a1[i]=g1(t0)
b1[i]=g2(t0)
c1 = sg.fftconvolve(a1,b1, mode = 'same') # use mode same
mc = c1.max()
print(' c1 max ')
print(mc)
#c1 /= pwr
#c1 /= 2
c1 /= mc
ma = a1.max()
mb = b1.max()
print(' a1 max ')
print(ma)
print(' b1 max ')
print(mb)
mb = ma*mb
#c1 = c1*mb/2#/((pwr+1)/2
#c1 = c1*mb
#c1 /= mc
c1=c1/2
plt.subplot(212)
plt.plot(a1,'k',color='steelblue')
# plt.plot(t, f1(t), label='$f_1(t)$')
plt.plot(b1,'k',color='orange')
plt.plot(c1,'k',color='red')
plt.show()
c1=np.zeros((n))
c1=conv1(a1,b1,c1)
plt.plot(c1,'k',color='red')
plt.show()