I have been trying to optimise some code that takes input signal in the form of a 2D array and convolves it with a gaussian of a certain FWHM. The size of this 2D signal array is (671, 2001), and I am convolving along the second axis - the time axis. Where,
time = 0:0.5:1000
nt = length(time) # nt = 2001
I am convolving with a gaussian of FWHM of 150, corrosponding to a standard deviation of about 63.7. I then pad the initial signal by 3 times the FWHM, setting the new values before the original start index as 0 and the new values after the original end index as the signal at the last time point.
Hence, nt = 3801
after padding.
My MATLAB code calculates this convolution in 117.5043 seconds. This is done through a nested for loop over each of the axis - should be slow in MATLAB. The main bit of theMATLAB code is as follows,
for it = 1:nt
% scan convolution mask across time
kernal = preb*exp(-b*(tc-tc(it)).^2); % convolution mask - Gaussian
N(it) = sum(kernal)*dt; % normalise
kernal = kernal/N(it); % ensure convolution integrates to 1
% calculate convolution for each row
for iq = 1:Nq
WWc(iq,it) = dt*sum((WWc0(iq,1:nt).').*kernal(1:nt));
end
end
I have rewritten this in Julia, except using circulant matrices to construct a gaussian kernal, this effectivley removes the foor loop over time, and the kernal to be applied over all time is now fully defined by one matrix. I then either loop over the rows and multiply this kernal by the signal of each row, or use the mapslices
function. The main bit of code in Julia is as follows,
K = Circulant(G.Fx) # construct circulant matrix of gaussian function G.Fx
conv = zeros(nr, nt) # init convolved signal
#for i=1:nr # If using a loop instead of mapslice
# conv[i, :] = transpose(sC[i, :]) * K
#end
conv = mapslices(x -> K*x, sC; dims=2)
In Julia this convolution takes 368 seconds (almost 3 times as slow as MATLAB), despite using circulant matrices to skip a foor loop and reducing it down to multiplying two arrays of size (1, 3801) and (3801, 3801) for each row.
output of @time:
368.047741 seconds (19.37 G allocations: 288.664 GiB, 14.30% gc time, 0.03% compilation time)
Both are run on the same computer, should Julia not outperform MATLAB here?