From: <HIDDEN>
Newsgroups: comp.soft-sys.matlab
Subject: Re: Correlation matrix, efficient method
Date: Tue, 10 May 2011 18:55:23 +0000 (UTC)
Organization: The MathWorks, Inc.
Lines: 27
Message-ID: <iqc1mq$bk7$>
References: <iqbs9o$mf6$>
Reply-To: <HIDDEN>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
X-Trace: 1305053723 11911 (10 May 2011 18:55:23 GMT)
NNTP-Posting-Date: Tue, 10 May 2011 18:55:23 +0000 (UTC)
X-Newsreader: MATLAB Central Newsreader 1187260
Xref: comp.soft-sys.matlab:726096

"susan" wrote in message <iqbs9o$mf6$>...
> hello,
> I have a matrix of x* y* z *176 from a fMRI imaging study.
> I need to get a square matrix with correlation values. i.e. each 'voxel(x*y*z)' has a timeseries (176). I need to correlate this with every other voxel.
> There has to be a more efficient way than for loops. So please help.
> Thanks,
> S
- - - - - - - - -
  If your matrix is four dimensional of x by y by z by 176 size and if x, y, and z are large, not only is it a very large matrix, but the square correlation matrix you desire would have to be a whopping big (x*y*z)^2 in size!  I hope your computer has room for such a monstrous entity.

  In any case, my recommendation would be to treat each of voxels' individual time series separately in such a way that its sum is zero and the sum of its squares is one.  Then all the correlation values can be calculated as the sum of the various paired products, which is a much simpler computation than doing a correlation calculation for each such pair from the original values.

  If v is one of these voxel time series, subtract mean(v) from each element, getting v1.  Then divide each v1 element by the square root of the sum of its squares, getting v2.  Then the sum of the v2 will be zero and the sum of its squares will be one.  The time spent doing this in comparison to your main task will be minuscule.  

  If V is a matrix of (x*y*z) by 176 size containing these adjusted v2 quantities, then you can get your desired correlation matrix by simple matrix multiplication:

 R = V*V.';

However, this will be necessarily be extremely time-consuming and memory-filling, even with the above simplifications.

  A short cut would be to replace this matrix multiplication by for-loops that only handle each possible pair once rather than twice, which would cut the time down by half though using slower for-loop operations.  You would still have the problem of storage space.

Roger Stafford