Binning in matlab: a one-liner

Sometimes a stimulus or response in an experiment is sampled at a uselessly high frequency. For example, a 3d (x, y and t axes) stimulus for a psychophysical reverse correlation experiment might include one noise sample per time frame. If a trial lasts a second, that can mean 100 samples or more, and if the spatial resolution and number of trials, that can mean a prohibitive amount of memory needed to process the data in the initial stages. The solution to this problem is downsampling.

A simple way of downsampling is binning. This involves taking a range of values of summing them together. For example, if a vector is 100 elements long, we can downsample it 20-fold elements using the code:

<pre>newels(1) =  sum(oldels(1:20));
newels(2) =  sum(oldels(21:40));
newels(3) =  sum(oldels(41:60));
newels(4) =  sum(oldels(61:80));
newels(5) =  sum(oldels(81:100));

There is a clever one-liner way of performing binning in matlab involving reshape. Here is the previous example, this time as a one-liner:

newels = sum(reshape(oldels,20,5) ,1);

Matlab can easily sum along a single dimension, hence the trick is to fold the vector such that one dimension contains all the samples of a bin. This can be done more generally by the function:

function [outv] = downsamplebin(invec,dimnum,amount)
    sizebefore = size(invec);
    sizemiddle = [sizebefore(1:dimnum-1),amount,sizebefore(dimnum)/amount,sizebefore(dimnum+1:length(sizebefore))];
    sizeafter = sizebefore;
    sizeafter(dimnum) = sizeafter(dimnum)/amount;
    outv = reshape(sum(reshape(invec,sizemiddle),dimnum),sizeafter);

Internally, reshape changes flags in the header section of vectors and matrices, not the data itself, hence this function is very fast.

Leave a comment

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s