1

I have a 192x256x192 cell where every cell is a 13-entry-long vector. I am tasked with creating 192 HeatMaps with 192x256 squares in each map. The value of each square is supposed to be found as the b-value of an exponential fit to the 13-entry-long vector.

I.e. Cell{:,:,1} is an image. Cell{1,1,1} represents the 13 changes in intensity a pixel experiences over time. I want to make 192 HeatMaps where each spot on the heatmap is the b-value of an exponential fit for that pixels changes in intensity over time.

I have some code for this (see below), but I am not a great programmer and it runs incredibly slowly. Does anyone have advice on an alternate means of doing this? Or advice on this topic.

Thanks.

ExpHeatMap = zeros(192,256,192);
t = 1:13;
ft=fittype('exp1');

for i = 1:192

    for j = 1:256

        for k = 1:192

            testArray = HeatMapValues{k,j,i}(1:end);
            numZeros = find(testArray == 0);

            if numZeros > 10

                ExpHeatMap(k,j,i) = 0;

            else

                cf = fit(t',HeatMapValues{k,j,i}',ft);
                ExpHeatMap(k,j,i) = cf.b;

            end

        end

    end

end
Divakar
  • 218,885
  • 19
  • 262
  • 358
odnanreh12
  • 17
  • 5
  • You can probably speed it up by using cellfun http://www.mathworks.co.uk/help/matlab/ref/cellfun.html – Tom Aug 14 '14 at 17:17
  • Just two little tips. First, the last indexing in `testArray` is unnecessary, i.e. `testArray = HeatMapValues{k,j,i};`. Second, I think that you can change the call to `find` as `numZeros = find(testArray == 0, 1, 'first');`. – Jommy Aug 14 '14 at 17:27
  • The line `ExpHeatMap(k,j,i) = 0;` is redoundant due to the preallocation. – Jommy Aug 14 '14 at 17:30
  • Did [this solution](http://stackoverflow.com/a/25314069/3293881) prove any good to this problem? – Divakar Aug 15 '14 at 04:03

2 Answers2

1

Here is a no-for-loop approach based on cellfun -

fv = cellfun(@(x) getfield(fit(t(:),x',ft),'b'), HeatMapValues);
ExpHeatMap = fv.*reshape(~(sum(vertcat(HeatMapValues{:}),2)>10),...
                                                 size(HeatMapValues))

I think the majority of the speeding up process would still depend on how you can vectorize the fit calculations. cellfun is one way to avoid for-loops, but it doesn't necessarily speed up calculations by a huge margin. But I don't think it would be slower than for-loop approach.

Divakar
  • 218,885
  • 19
  • 262
  • 358
  • This does seem to be faster, but I keep getting this error which makes no sense to me because everything I input is a column vector. "Error using fit>iFit (line 133) Y must be a column vector." – odnanreh12 Aug 19 '14 at 16:21
  • @odnanreh12 Could you try out the edited code? It must work now for any type of vector as `t`. – Divakar Aug 19 '14 at 16:34
0

I would first suggest to use ii, jj and kk instead of i, j and k. Next, I suggest you pre-allocate the variable testArray as you did for ExpHeatMap. Also, shouldn't it be {i, j, k} instead of {k, j, i}?

m_power
  • 3,156
  • 5
  • 33
  • 54
  • Thanks for the advice, some question (I am relatively new to MatLab so pardon my ignorance): I see it all the time, but why do people us ii,jj, and kk instead of just the single letters? Is this just a matter of convention? As for the other comment, in the end it doesn't really matter but I did it this way because I wanted it to be completed image by image and {i,j,k} would the the first pixel of each image, then the second pixel of each image, etc. Just a weird choice I made for who-knows-why. – odnanreh12 Aug 14 '14 at 18:19
  • @odnanreh12 `i` and `j` refer to imaginary unit in MATLAB. Refer to this [link](http://stackoverflow.com/a/14790765/2419003). – m_power Aug 14 '14 at 18:44