How to vectorize inside user defined functions to avoid nested loops?
显示 更早的评论
Hello everyone, I'm trying to vectorize some code so as to avoid making a nested loop. However, at the innermost loop I have to run a function that I've defined myself, and I can't seem to find a way to make that function "understand" its inputs properly. What I have right now, which works but is rather slow, is something like this:
for i = 1:n*m
for j = 1:n*m
I_ww(i,j) = InfluenceLine(XcWing(i,j),YcWing(i,j),ZcWing(i,j),XvWing,YvWing,ZvWing,XnWing(i,j),YnWing(i,j),ZnWing(i,j),AngleOfAttack);
end
end
I'd like to rewrite that so it looks something like this:
I_ww(:,:) = InfluenceLine(XcWing(:,:),YcWing(:,:),ZcWing(:,:),XvWing,YvWing,ZvWing,XnWing(:,:),YnWing(:,:),ZnWing(:,:),AngleOfAttack);
I've realized, however, that with this syntax, the inputs which were supposed to be scalars, namely XcWing(i,j) and so forth, are now the entire matrices XcWing, which my function does not support. Is there a way to get the function to compute only one element of each of the input matrices at a time?
5 个评论
You can call arrayfun twice, but this isn't going to be faster than looping. Unfortunately, it's likely that if you want to vectorize this, you need to rewrite your function to take either vectors or matrices instead of scalars.
Matlab is really only faster when using its vector operations. Any way to recombine scalar operations isn't going to improve performance significantly.
Vectorization does not mean replacing my slow loops with some other code, it means writing functions that operate on entire arrays at once.
This means it is the function that is important, not the loops. However you do not tell us anything about the function, yet the function is the only important thing to consider. If you give us details about the function then we can give advice about vectorization.
André Camões
2016-1-27
编辑:André Camões
2016-1-27
The usual way to resolve if-like decisions in vectorized code is to use indexing (logical indexing is the fastest), typically either:
- pick an array susbset using indices, apply operation to it, replace into a subset of the array. The rest of the array remain unchanged.
- apply an operator to the entire array, then use indices to replace a subset of elements with zero/NaN/...
Also note that both cross and dot can be applied to multidimensional arrays, so you can vectorize these operations too. Read the documentation to see how this works: I would highly recommend that you use the syntax using the optional dimension argument, like this example from the documentation:
>> A = cat(3,[1 1;1 1],[2 3;4 5],[6 7;8 9]);
>> B = cat(3,[2 2;2 2],[10 11;12 13],[14 15; 16 17]);
>> C = dot(A,B,3)
C =
106 140
178 220
"The result, C, contains four separate dot products. The first dot product, C(1,1) = 106, is equal to the dot product of A(1,1,:) with B(1,1,:)."
Both of these changes will mean going through your entire code and rewriting it all... but is seems like it might be possible. Good luck!
André Camões
2016-1-27
采纳的回答
更多回答(0 个)
类别
在 帮助中心 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!