1
votes

I have a 3D array (image) with the dimensions of 256 x 3527 x 8. I wish to divide all the values by the 3rd dimension by a vector of 1 through 8.

For example, my vector looks like:

Esun = [1 2 3 4 5 6 7 8]

In each layer of the image of size 256 x 3527 (of 8 layers), I want to divide it by the respective value in Esun.

If MATLAB doesn't have such a function, will it be faster to cut my 3D array into 8 pieces and run it through a loop, or turn Esun into a 3D repetitive array and do a matrix division?

2

2 Answers

1
votes

Please do not use arrayfun as it is essentially a loop. Use the mighty bsxfun instead combined with permute:

Esun = 1:8; % Esun = [1 2 3 4 5 6 7 8];
B = bsxfun(@rdivide, A, permute(Esun, [1 3 2]));

The variable A is the 3D matrix that you have that is of size 256 x 3527 x 8. The call to permute uses Esun and converts it into a 3D vector of 1 row and 1 column. After, bsxfun broadcasts the 3D vector so that it becomes a 3D matrix of size 256 x 3527 x 8 where each slice i represents the ith value in Esun. We then perform the element-wise division.

This basically performs the repetitive array operation that you're speaking of, but the replication is done internally in bsxfun and is faster than if you were to create the repetitive array first then perform the division.

0
votes

You can use arrayfun as following:

c=arrayfun(@(i) X(:,:,i)*Esun(i),1:8,'UniformOutput',0);

Assuming that X is your image array. In the above, MATLAB return a 1x8 cell array, then you can use cat function to obtain the new array:

B = cat(3, c{:}); % cat all cell elements in 3-rd dim