Alternative to using Multi-level field struct

10 Ansichten (letzte 30 Tage)
Science Machine am 7 Jul. 2022
Bearbeitet: Bruno Luong am 8 Jul. 2022
I am taking two populated structs and re-ordering them, so that I can do an operation(such as fft), on the end-most field's elements, eg
bigNum=1e4;
for b=1:bigNum
for a=1:bigNum
val=Struct_A(a).dat(b);
Struct_B(b).dat(a)=val;
val2 = fft(Struct_B(b).dat(:);
end
end
I do this also with 3-layered field structures such as Struct_C(f).fielde(e).fieldd(d).dat.
• Is there a more efficient way to handle this reordering?
• Can I vectorize this or otherwise speed this up? I am using parfor loops, but, it seems just the idea of re-ordering structures is a bad paradigm when considering large data
0 Kommentare-2 ältere Kommentare anzeigen-2 ältere Kommentare ausblenden

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Michael Van de Graaff am 7 Jul. 2022
I gave it shot.
n = 1000;
s(n) = struct();
for ii = 1:n
for jj = 1:n
s(ii).a(jj) = ii;%this is just building the original struct
end
end
tic
for ii = 1:n
for jj = 1:n
val = s(ii).a(jj);
s2(jj).a(ii) = val;% do the loop like you have
end
end
toc
Elapsed time is 0.660588 seconds.
%now lets try something without loops, should be faster for large n
tic
tmp = cell2mat(squeeze(struct2cell(s))).';
tmp2=mat2cell(tmp,ones(1,n),[n]);
s3 = cell2struct(tmp2,fieldnames(s),4);
toc
Elapsed time is 0.033685 seconds.
% and let's do a loop to ensure s2 and s3 are the same
s_diff = zeros(n);
for ii = 1:n
for jj = 1:n
s_diff(ii,jj) = s2(ii).a(jj)-s3(ii).a(jj);
end
end
if max(abs(s_diff(:)))==0
disp('success') %I got success
else
disp('failure')
end
success
3 Kommentare1 älteren Kommentar anzeigen1 älteren Kommentar ausblenden
Science Machine am 8 Jul. 2022
Bearbeitet: Science Machine am 8 Jul. 2022
'While' keeping the data in its natual organiztion as eg
struct(index 1).field2(index2).field3(index3).dat(array or matrix)
each field is generally a different # of entries.
• I was reading maybe multi-dimensional array?
Michael Van de Graaff am 8 Jul. 2022
"would be possible to eschew structures altogether?"
Are you familiar with cell arrays? That seems like precisely what you are looking for, as they can be n-dimsionsal and each cell can contain whatever data type, including arrays of differeing sizes. You don't get the built in clarity of the fieldnames, but a GPU don't need no fieldnames :D (I have literally no knowledge of how GPU implementations work fyi)

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Bruno Luong am 8 Jul. 2022
Bearbeitet: Bruno Luong am 8 Jul. 2022
It seems you just burry an array into nested structures for no apparent reason other than using struct with a fieldname for a sake of it speaks to you.
Undo that and think like a computer:
% Generate dummy data
a = 10; % your big number
for i=1:a
for j=1:b
STRUCTA.A(i).B(j) = rand();
end
end
% Undo the thing to getback numerical array
a = length(STRUCTA.A);
b = length(STRUCTA.A(1).B);
AB=reshape([STRUCTA.A.B],[b,a]); % deepest nested length first, ...
% Simply work on the array, that how MATLAB should be used
% If you want to swap a/b dimension, transpose AB, no need for
% the ugly double for-loop as you do.
val2 = fft(AB,[],2)
val2 =
4.0661 + 0.0000i 0.0323 - 0.7934i -0.2520 - 0.6357i 0.4981 + 0.0308i -0.4295 - 0.9440i -1.0016 + 0.0000i -0.4295 + 0.9440i 0.4981 - 0.0308i -0.2520 + 0.6357i 0.0323 + 0.7934i 5.5655 + 0.0000i 0.4685 + 0.8790i 0.3279 + 0.0606i 0.1125 + 0.1375i 0.4377 - 0.4593i -1.2876 + 0.0000i 0.4377 + 0.4593i 0.1125 - 0.1375i 0.3279 - 0.0606i 0.4685 - 0.8790i 4.8333 + 0.0000i -0.5814 - 0.5989i 0.4646 - 0.5380i -0.1544 - 0.4535i -0.5136 - 0.3355i 1.9391 + 0.0000i -0.5136 + 0.3355i -0.1544 + 0.4535i 0.4646 + 0.5380i -0.5814 + 0.5989i 5.2862 + 0.0000i 0.7492 - 1.0385i 1.3908 + 0.8551i 0.2308 - 0.0047i -0.6972 + 0.4188i -0.5792 + 0.0000i -0.6972 - 0.4188i 0.2308 + 0.0047i 1.3908 - 0.8551i 0.7492 + 1.0385i 4.8983 + 0.0000i -0.4043 + 0.3373i 0.2988 - 0.9046i -0.4060 + 0.4049i 0.7049 - 0.6535i 0.2248 + 0.0000i 0.7049 + 0.6535i -0.4060 - 0.4049i 0.2988 + 0.9046i -0.4043 - 0.3373i 4.8601 + 0.0000i -0.2928 - 0.1440i -0.3565 - 0.5095i 0.4126 - 0.2177i -0.3226 + 0.0414i 1.4404 + 0.0000i -0.3226 - 0.0414i 0.4126 + 0.2177i -0.3565 + 0.5095i -0.2928 + 0.1440i 4.4551 + 0.0000i -1.6476 - 0.0270i 0.7631 - 0.6674i -0.2366 - 0.8680i -0.1395 - 0.1165i -0.4810 + 0.0000i -0.1395 + 0.1165i -0.2366 + 0.8680i 0.7631 + 0.6674i -1.6476 + 0.0270i 4.1921 + 0.0000i -0.6224 - 0.1522i 1.5197 - 0.6028i 0.5938 + 0.2190i 1.0945 - 0.7803i -0.1243 + 0.0000i 1.0945 + 0.7803i 0.5938 - 0.2190i 1.5197 + 0.6028i -0.6224 + 0.1522i 5.2778 + 0.0000i 0.2595 + 0.7150i -0.2160 - 0.3907i 1.0669 + 0.0340i 0.3649 - 0.8534i -0.3927 + 0.0000i 0.3649 + 0.8534i 1.0669 - 0.0340i -0.2160 + 0.3907i 0.2595 - 0.7150i 5.5209 + 0.0000i 1.3374 + 0.5652i -0.5742 + 0.1283i -0.1109 + 0.2116i 0.7891 + 0.7053i -0.8280 + 0.0000i 0.7891 - 0.7053i -0.1109 - 0.2116i -0.5742 - 0.1283i 1.3374 - 0.5652i 4.2459 + 0.0000i 0.6400 - 0.5771i 0.4029 + 0.8782i -0.1877 + 0.6045i -0.5498 - 0.5591i -1.6546 + 0.0000i -0.5498 + 0.5591i -0.1877 - 0.6045i 0.4029 - 0.8782i 0.6400 + 0.5771i
2 KommentareKeine anzeigenKeine ausblenden
Science Machine am 8 Jul. 2022
Can this be done with 3 or more levels? i have a more complicated structure like myStr(i).angle(theta).radius(r).dat(1:xLocation) and since there are so many parameters, I needed to organize that somehow. Several times, depending on the operation, I have to juggle the entries.
function strTest3()
% Gen data
a = 3; %
b = 5; %
c = 7; %
for i=1:a
for j=1:b
for k=1:c
%STRUCTA.A(i).B(j) = i*j;
STRUCTA.A(i).B(j).C(k) = i*j*k;
end
end
end
% Undo
a = length(STRUCTA.A);
b = length(STRUCTA.A(1).B);
c = length(STRUCTA.A(1).B(1).C);
AB=reshape([STRUCTA.A.B],[b,a]); % this works
ABC=reshape([STRUCTA.A.B.C],[c,b,a]); % this produces error
val2 = fft(AB,[],2)
end
Bruno Luong am 8 Jul. 2022
Bearbeitet: Bruno Luong am 8 Jul. 2022
With three (four) levels you have to do 2-step
...
AB = [STRUCTA.A.B];
ABC = reshape([AB.C],[c b a]);
...

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu GPU Computing finden Sie in Help Center und File Exchange

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by