For loop vectorisation having structure arrays

2 visualizaciones (últimos 30 días)
Melanie VT
Melanie VT el 11 de Mzo. de 2023
Comentada: Melanie VT el 13 de Mzo. de 2023
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 comentarios
Walter Roberson
Walter Roberson el 11 de Mzo. de 2023
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.
Melanie VT
Melanie VT el 12 de Mzo. de 2023
I get what you mean @Walter Roberson! Thank you for drawing my attention to this matter🙏🏼

Iniciar sesión para comentar.

Respuesta aceptada

Jan
Jan el 12 de Mzo. de 2023
Editada: Jan el 12 de Mzo. de 2023
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 comentarios
Jan
Jan el 13 de Mzo. de 2023
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.
Melanie VT
Melanie VT el 13 de Mzo. de 2023
That's a splendid job @Jan! My hat's off to you👒 I can't literally thank you enough. You're providing not only solutions but also capacity strengthening! This is why you're an L10-MVP, I guess. From now on, I will build my codes with this logic. Thanks a million; it's really exceptional🙏🏻

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Loops and Conditional Statements en Help Center y File Exchange.

Etiquetas

Productos


Versión

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by