Speed up process of passing each row of large array to external function
2 views (last 30 days)
Show older comments
I have a very large array consisting of 10,000 rows and 1,927 columns. Each row is a photoluminescence spectrum that I am passing from AppDesigner to an external function to fit multiple Gaussians. I have tried using Image Analyst's fit_multiple_gaussians.m and Tom O'Haver's findpeakfits.m, which both work very well. However, to no one's surprise, calling either of these functions 10,000 times in a for-loop is very slow for spectra that contain 1,927 data points. Because each row of the array is an independent spectrum, is there an efficient way to parallelize the function call, or possibly perform these operations on a GPU without having to decrease the number of data points in each spectrum? Below is the code snippet of the for-loop:
x = lambdas % 1 x 1927 element vector
gaussians = zeros(length(int(:,1)),numGaussians,length(lambda)); %pre-allocate size of gaussians array
%Loop over the length of the array and pass each row to the function
for i = 1 : length(int(:,1))
%int is a 10,000 x 1,927 array containining intensity data. 10,000
%independent spectra with 1,927 data points per spectrum.
y = int(i,:);
FitResults = []; %clear previous result. FitResults is a small Nx5 array, where N is determined by the number of Gaussians needed to fit the spectrum
FitResults = findpeaksfit(x,y,SlopeThreshold,AmpThreshold,smoothwidth,peakgroup,smoothtype,peakshape,extra,NumTrials,autozero,fixedparameters,plots);
%Extract Gaussian peaks and widths from function output
for j = 1 : size(FitResults,1)
peakPosition = FitResults(j,2);
width = FitResults(j,4);
%pass Gaussian parameters to another function to rebuild Gaussian
gaussians(i,j,:) = gaussian(app,lambda,peakPosition,width);
end
end
function g = gaussian(app, x, peakPosition, width)
g = exp(-((x - peakPosition) ./ (0.60056120439323 .* width)) .^ 2);
end
6 Comments
dpb
on 28 Sep 2023
Edited: dpb
on 28 Sep 2023
"The clarity of the spectra contained in one dataset varies dramatically, with varying numbers of peaks, intensities, noise levels, etc. ..."
I can imagine -- I developed alogorithms for gamma spec for an online coal elemental S analyzer some 40 years ago (in Visual Basic, believe it or not!) without any such helping features...implemented own Marquardt solver in conjunction with the linear quadratic background correction...
There, however, it took some 5 minutes to collect enough counts so that it was only having to do that calc that often. Unfortunately, with the technology then and no cryogenics, that was using NaI crystal and so the resolution was so poor the analyzer itself was a device ahead of its time for power plant applications. In the time since, it's night and day although in the end for combustion control, simply the elemental S isn't that useful because the coal firing qualities are so highly dependent upon the particular sulfur compounds present more than just the amount of total S.
Accepted Answer
Catalytic
on 27 Sep 2023
Edited: Catalytic
on 27 Sep 2023
This reduces it to one loop, which should work with parfor -
x = lambdas; % 1 x 1927 element vector
intt=int';
logg=nan(numGaussians,length(lambda), size(int,1)); %pre-allocate log of gaussians
%Loop over the array and pass each COLUMN to the function
for i = 1 : size(int,1)
FitResults = findpeaksfit(x,intt(:,i), SlopeThreshold,AmpThreshold,smoothwidth,peakgroup,smoothtype,peakshape,extra,NumTrials,autozero,fixedparameters,plots);
peakPosition=FitResults(:,2);
width=FitResults(:,4);
logg(:,:,i)=(x - peakPosition) ./ width ;
end
gaussians=exp(-(logg/0.60056120439323).^2);
gaussians=permute(gaussians,[3,1,2]);
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!