How can I speed up this loop (or avoid using it)?

I am trying to map the average concentration of a chemical (concxy2) at arbitrarily located points (xposn2 zposn2) (all 2D matrices, not monotonic) onto a 2D grid (xedges zedges). There are often several points that end up in a given bin of the grid, and I would like to quickly find the average of these points in a bin. Here's the code I'm presently using:
%Find where points in xposn2 and zposn2 fall in the grids defined by xedges and zedges. The number of points in a given bin is given by N, and the locations of the points in the grid are given by binx and binz.
[N,zedges,xedges,binz,binx]=histcounts2(zposn2,xposn2,NBINS,'YBinLimits',[xmin_bin,xmax_bin],'XBinLimits',[zmin_bin,zmax_bin]);
%Find the rows and columns of the new grid where there are points
[indr,indc]=find(N>0);
%Initialize an array for the binned concentrations
conc_sum = zeros(NBINS(1),NBINS(2));
%Now find out which points are in a given bin, and average their concentrations concxy2 in that bin
for i=1:length(indr)
indpts=find(binx == indc(i) & binz == indr(i));
conc_sum(indr(i),indc(i)) = sum(concxy2(indpts));
clear indpts;
end
The first part of this runs wonderfully quickly. The loop, however, with the matrix size I'm using, is VERY slow, even though I'm only looking for the bin locations of existing points (rather than looping through the entire binx binz arrays). The indices of the row and column locations of the points are indr and indc, respectively.
It is extremely fast to find how many points are in a given bin (N). But I can't figure out a way to quicly find the concentrations associated with those points (concxy2) and average them in the given bin (binx(i), binz(i)).
Any suggestions on speeding up or removing the loop would be MUCH appreciated.
Peter

 Respuesta aceptada

Guillaume
Guillaume el 13 de Mzo. de 2019
Editada: Guillaume el 13 de Mzo. de 2019
%your original start, we don't need the first 3 outputs
[~, ~, ~, binz, binx]=histcounts2(zposn2,xposn2,NBINS,'YBinLimits',[xmin_bin,xmax_bin],'XBinLimits',[zmin_bin,zmax_bin]);
conc_sum = accumarray([binx(:), binz(:)], concxy(:), [NBINS, NBINS], @mean) %average according to bin
Note that if zposn2, xposn2 and concxy are already column vectors, you don't need the (:).

1 comentario

Peter Franks
Peter Franks el 13 de Mzo. de 2019
Guillaume, dude, you are my new hero! Thank you! After a little fiddling, that worked perfectly! The calculation went from 20 minutes down to 10 seconds!

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Data Distribution Plots en Centro de ayuda y File Exchange.

Preguntada:

el 13 de Mzo. de 2019

Comentada:

el 13 de Mzo. de 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by