MATLAB: Cellfun to extract arrays from multi-dimensional cell

cellfunfor

Hi all,
Imagine I have a 2-d cell, each cell element is a m by n matrix, I apply SVD on each element such that they are decomposed into left singular vectors, singular values and right singular vectors. Here's an example:
clear; clc;
a = 2;
b = 3;
matL = 5;
matW = 4;
myCell = cell(a, b);
myCell = cellfun(@(v) rand(matL, matW), myCell, 'UniformOutput', false);
[myCellL, myCellSig, myCellR] = ...
cellfun(@(v) svd(v, 'econ'), myCell, 'UniformOutput', false);
Now I'd like to extract the first vector of myCellL, first value of myCellSig, first vector of myCellR, put these into one cell element, and repeat for the second, third…… I can write a loop to do this (continue the above script):
myOtpt = cell(a, b, matW);
for i = 1:a
for j = 1:b
for k = 1:matW
myA = myCellL{i, j}(:, k);
myB = myCellSig{i, j}(k, k);
myC = myCellR{i, j}(:, k);
myOtpt{i, j, k} = {myA, myB, myC};
end
end
end
The second part of script (for loops) seems also is a repeat operation on cells 'myCellL, myCellSig, myCellR', is it possible to write these with cellfun, such that for loop is avoided?
Many thanks!

Best Answer

As Adam says, the loop version may be faster. With a few comments it also would be clearer. You're actually probably better off getting rid of your original svd cellfun and generating the output you want directly with one loop.
Now, if you really want to get rid of the loop, you don't even need a cellfun. It gets hairy though, I'm not going to explain the details:
newCellL = permute(num2cell(cat(3, myCellL{:}), 1), [1 4 2 3]);
newCellSig = reshape(num2cell(diag(blkdiag(myCellSig{:}))), 1, 1, [], numel(myCellSig))
newCellR = permute(num2cell(cat(3, myCellR{:}), 1), [1 4 2 3]);
newOtpt = permute(reshape(num2cell(cat(2, newCellL, newCellSig, newCellR), 2), [], size(myCell, 1), size(myCell, 2)), [2 3 1]);
A lot of array concatenation, splitting and dimension manipulation (plus some diag(blkdiag) to get the diagonal of all the matrices in one go. It's possible you could optimise the first three permute so that the 4th permute is not required, but it hurts my head already enough as it is.