For loop vectorisation having structure arrays
3 次查看(过去 30 天)
显示 更早的评论
Hi,
I'm still having trouble converting for loops into vectorised form. This time, I have a code snippet which generates two arrays (array2 & array3) using a for loop. Unfortunately, I couldn't manage to get a vectorised solution. I'd be more than happy to get your help.
Thanks in advance,
Mel
array2 = zeros(height(array1),1);
array3 = zeros(height(array1),1);
for i = 1:length(array1)
temp_s1 = array1(i);
idx = [struct_data1(:).cid].' == temp_s1;
temp_s2 = struct_data1(idx);
array2(i) = temp_s2([struct_data1(idx).group2].'== 1).group1;
array3(i) = struct_data2([struct_data2(:).cid].' == temp_s1).gid;
end
2 个评论
Walter Roberson
2023-3-11
array2(i) = temp_s2([struct_data1(idx).group2].'== 1).group1;
That assumes that you will get exactly one match from the == 1 in that line, and that the group1 returned is a scalar.
As outside observers, we have no particular reason to expect that you will ever sometimes get 0 matches or sometimes get more than one match.
We can guess that idx might have more than one true entry since you [struct_data1(idx).group2] which is code that is compatible with the possibility that more than one entry in struct_data1 is being referred to.
采纳的回答
Jan
2023-3-12
编辑:Jan
2023-3-12
What is the prupose of a vectorization here? Remember that vectorized code creates temporary arrays usually and this is expensive. Therefore loops are faster in many cases.
Avoid repeated work instead:
c1 = [struct_data1(:).cid].'; % Do this once only
c2 = [struct_data1(:).group2].';
c3 = [struct_data2(:).cid].';
for i = 1:length(array1)
temp_s1 = array1(i);
idx = (c1 == temp_s1);
temp_s2 = struct_data1(idx);
array2(i) = temp_s2(c2(idx) == 1).group1;
array3(i) = struct_data2(c3 == temp_s1).gid;
end
In my local Matlabr R2018b this reduces the runtime from 38 sec of the original to 0.4 sec.
Further 10% faster:
[~, index] = ismember(array1, c3);
array2 = zeros(size(array1, 1),1);
array3 = zeros(size(array1, 1),1);
for i = 1:length(array1)
temp_s1 = array1(i);
idx = (c1 == temp_s1);
temp_s2 = struct_data1(idx);
array2(i) = temp_s2(c2(idx) == 1).group1;
array3(i) = struct_data2(index(i)).gid;
end
4 个评论
Jan
2023-3-13
My first suggestion offered a speedup of a factor 100. The version 4 with ismembc2 is again 260 times faster. 26'000 is a satisfying acceleration and it is based on simplifications of the code, not a vectorization.
Most of the time in the fastest version is spent for combining the scalar fields of the struct to vectors. This shows, that the chosen representation of the data as structs might by clear and clean, but a bunch of vectors will be more efficient.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Loops and Conditional Statements 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!