Best practice of for loops and vectorisation, also maybe cumprod.

Hello all,
Like many, I am entering Matlab from a C (embedded) background, so am struggling with the adjustment to vectors.
Simple cases such as the following are beginning to be understandable to me.
for i = 1:length(myVector)
dim(i)= i;
end
is equivalent to
dim = 1:length(myVector);
However I'm stuck on a slightly more complex case relating to nested arrays. I have a nested cell array (someArray) and I wish to know the cumulative product of all those elements.
someArray = {cell(1,4); cell(1,13); cell(1,3); cell(1,2); cell(1,5)}
someArray =
{1x4 cell}
{1x13 cell}
{1x3 cell}
{1x2 cell}
{1x5 cell}
The following works, but it feels clunky.
product = 1;
for i = 1:length(someArray)
dim(i) = length(someArray{i});
product = product*dim(i);
end
count =
1560
I feel like this is hacky and that there's a better way, but my thinking is stuck. Is there a way to use cumprod()? Any suggestions are welcome. I'm using ML ed. R2012b

댓글 수: 2

You say you wish to know "the cumulative product of all those elements".
I assume that is just a slight mistake in the description since you seem happy with your result, but I was assuming you meant you want the product of all the elements in each cell array rather than simply the product of the lengths of each cell array. The former would be a little more complex, but if you do just want the product of the lengths then either your code or David Young's below will do fine.
Beware though that while cellfun looks neat it is, unfortunately rarely as performant as simply doing a for loop.
Thanks for the response. Yep, typo there. I just want the product.
The code here works to my satisfaction, I was just hoping there would be a leaner way to perform the same task and at the same time learn a new vectors method. I guess I'll leave it as it is.

댓글을 달려면 로그인하십시오.

 채택된 답변

David Young
David Young 2014년 9월 11일
prod(cellfun(@length, someArray))

댓글 수: 14

Though I'd add that your original solution isn't, in my view, particularly clunky - it's more a question of style and what is clear, which depends on your background. There may also sometimes be speed and memory issues, and if they arise it's worth doing timing tests. (The vectorised code ought to be faster, but it's not always the case.)
By the way, there's a question of whether you need to keep the array of lengths. If you do, my code would be modified to
dim = cellfun(@length, someArray);
product = prod(dim);
and if you don't, your own code could be simplified by replacing the two occurrences of dim(i) with a simple variable.
That's great and really clear. I've simplified my problem for this answer and I do need to retain the array. A huge help, thanks :)
What here is the difference between cellfun and arrayfun?
cell fun works on cell arrays, arrayfun works on normal arrays although I think in a recent version of Matlab arrayfun was extended to be able to work on cell arrays too, but I always just use cellfun for cell arrays.
Sean de Wolski
Sean de Wolski 2014년 9월 11일
편집: Sean de Wolski 2014년 9월 11일
In my opinion, always avoid arrayfun (unless you're working with GPUs). It's clunky, often times slower than for-loop and much harder to understand.
Actually, for your above example, I would use cellfun if it was a quick command line operation where I just needed to know the result (less typing). If I was putting this in a function to be reused a lot, I'd probably use the for-loop that you have above.
The one change I would make would be to avoid using i/j as variables in MATLAB since they represent the sqrt(-1). I usually use ii, or ix.
Welcome to the MATLAB Answers!
Think of a cell array as an array of individual cells. Inside each cell is the stored array, which may be numeric, cell, struct, char or whatever. cellfun extracts the contents of each cell in turn, to pass to the function argument. arrayfun, on the other hand, passes the cells themselves to the function argument. Thus cellfun is like your loop with length(someArray{i}) inside, whilst arrayfun is like a loop with length(someArray(i)) inside.
To see a difference compare:
cellfun(@disp, {1 2 3});
with
arrayfun(@disp, {1 2 3});
The square brackets that appear in the first case show that the cells are being displayed, rather than their contents. ( disp strips the outermost brackets off - so disp( { [1] } ) displays [1] whilst disp( [1] ) displays 1.)
cellfun can't be applied to non-cell arrays. arrayfun applies the function to each element of any array.
Wow, great answers guys!
Is it true that for loops used to be slower in previous versions of MatLab and that's why a lot of older forum posts are pushing for vectorisation, but more recent advice seems to be less concerned about them?
@Sean, I have already learnt the iterators tip, but was using i for my example for clarity and because coding C leaves deep scars! Why would you keep the for loop if it was in a situation that would be used a lot vs quick-and-dirty command-line action?
@David, that explanation is very clear. When my brain started seeing {} and () accessor methods as maybe the referencing/dereferencing of pointer systems that they represent (am I way off?), they began to make more sense.
Adam
Adam 2014년 9월 11일
편집: Adam 2014년 9월 11일
Vectorisation is still vastly faster than for loops, but cellfun and arrayfun are not really vectorised forms. Some people consider them less readable, some (myself included) consider them neater and more readable, but they are regularly slower.
Vectorisation in terms of Matlab is more of the form that
a = rand(100,1);
b = rand(100,1);
c = a + b;
is miles faster than
c = zeros(100,1)
for i = 1:100
c(i) = a(i) + b(i);
end
Stephen23
Stephen23 2014년 9월 11일
편집: Stephen23 2025년 3월 21일
"but more recent advice seems to be less concerned about them": implying therefore that "I don't have to bother learning it"?
Actually vectorization can be a lot faster for doing numeric calculations with arrays of any size (it rather depends on the operations being performed), and this is really what MATLAB excels at. Vectorization is still MATLAB's official advice too, and the fact that it makes neater, more readable code is a bonus for the humans who have to write it and read it.
C is great, but it is C. MATLAB is great, in completely different ways: think of arrays less as pointers-and-offsets, and more as the mathematical things that they actually represent. Then MATLAB will start to make sense.
Stephen23
Stephen23 2014년 9월 11일
편집: Stephen23 2025년 3월 21일
Adam commented "cell fun works on cell arrays, arrayfun works on normal arrays although I think in a recent version of Matlab arrayfun was extended to be able to work on cell arrays too, but I always just use cellfun for cell array"
Kinda, but this misses the point. It is like saying that even though () do work on cell arrays, but I only use {}. They do different things, and have vastly different applications. Using arrayfun on a cellarray is equivalent to using () indexing, whereas cellfun is equivalent to using {} indexing.
A useful tip is this:
  1. () indexing always returns the same data type as the array it is indexing.
  2. {} indexing returns the data inside the cells.
Ditto for the functions:
  1. ARRAYFUN works with the same data type as the input array/s.
  2. CELLFUN works with the data inside the cells.
Ah, that makes sense. I just read somewhere that arrayfun had been enhanced to the extent that cellfun was now superfluous, though I have never tested that myself. If they still both have clear distinct usages that makes more sense.
You can also use the legacy flag 'length' for speed:
cellfun('length', someArray)
Marshall - yes, using {} rather than () is like doing an extra pointer dereference in C.
@Stephen, ""but more recent advice seems to be less concerned about them": implying therefore that "I don't have to bother learning it"?"
Not at all, I'm very interested in learning more about it! I was just interested in why there seems to have been a shift in advice over time when I've been reading forums.
Great advice and information from everyone here, thanks for the great welcome!

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품

질문:

2014년 9월 11일

편집:

2025년 3월 21일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by