Reputation: 1894
I have 2 (not very small) 3-dimension structs with matrices as fields:
sz1 = 200;
sz2 = 9;
sz3 = [20, 40, 80, 160, 320, 640, 1280, 2560, 5120]
% actually the structs have 12 fields, each has size 200x9x5120
mat.p1(sz1, sz2, sz3(sz2)) = uint8(0);
mat.p2(sz1, sz2, sz3(sz2)) = uint8(0);
mat.p3(sz1, sz2, sz3(sz2)) = 0;
mat.p4(sz1, sz2, sz3(sz2)) = 0;
old_mat.p1(sz1, sz2, sz3(sz2)) = uint8(0);
old_mat.p2(sz1, sz2, sz3(sz2)) = uint8(0);
old_mat.p3(sz1, sz2, sz3(sz2)) = 0;
old_mat.p4(sz1, sz2, sz3(sz2)) = 0;
And i need to write a reset
function, where i will re-assign the values to 3 of 4 (actually 10 of 12) fields in both matrices as follows:
for i = 1:sz1
for j = 1:sz2
for k = 1:sz3(j)
mat.p1(i,j,k) = uint8(255);
mat.p3(i,j,k) = -1;
mat.p4(i,j,k) = 0.01;
old_mat.p1(i,j,k) = uint8(255);
old_mat.p3(i,j,k) = -1;
old_mat.p4(i,j,k) = 0.01;
end
end
end
Note that actually what i need in the matrices is the same as the reset
function, means i only need the 5120th index of the 3rd-dimension when 2nd-dimension is 9, if 2nd-dimension = 4, i only need up to 160 indices at 3rd-dimension etc.
The questions are:
Is there anyway to avoid the for-loops? I tried like this:
mat.p1(:) = uint8(255);
mat.p3(:) = -1;
mat.p4(:) = 0.01;
old_mat.p1(:) = uint8(255);
old_mat.p3(:) = -1;
old_mat.p4(:) = 0.01;
but here all the matrices are filled with max 3rd-dimension = 5120 so i expect someone can show me how to use the vectorizing function like arrayfun, bsxfun, cellfun etc.
, which can apply for just the "half-cubic" like the for-loops above.
UPDATE: Thanks horchler for the video, it seems the problem with big size (in bytes) of the matrices is solved when i change the matrix of struct to a struct with matrices as fields. This also clears the timing problem even with nested for-loops. So i updated the questions and the input as well, please see above.
Upvotes: 1
Views: 89
Reputation: 18504
Yes, I think that using a structure of arrays will work better for you here. You should be able to allocate using zeros
just as if mat.p1
, mat.p2
, etc. were regular arrays. I'd do something like this (note that you didn't indicate any values for mat.p2
) using a single for
loop:
sz1 = 200;
sz2 = 9;
sz3 = [20, 40, 80, 160, 320, 640, 1280, 2560, 5120];
% Be careful with this form of pre-allocation if your sz arrays change
% Clear your struct or make sure to use the code in a function
mat.p1(sz1,sz2,sz3(sz2)) = uint8(0);
mat.p3(sz1,sz2,sz3(sz2)) = 0;
mat.p4(sz1,sz2,sz3(sz2)) = 0;
for i = 1:sz2
mat.p1(:,i,1:sz3(i)) = uint8(255);
mat.p3(:,i,1:sz3(i)) = -1;
mat.p4(:,i,1:sz3(i)) = 0.01;
end
old_mat.p1 = mat.p1;
old_mat.p3 = mat.p3;
old_mat.p4 = mat.p4;
Alternatively, you could do something like this:
sz1 = 200;
sz2 = 9;
sz3 = [20, 40, 80, 160, 320, 640, 1280, 2560, 5120];
mat = struct('p1',zeros(sz1,sz2,sz3(sz2),'uint8'),...
'p3',zeros(sz1,sz2,sz3(sz2)),...
'p4',zeros(sz1,sz2,sz3(sz2)));
for i = 1:sz2
mat.p1(:,i,1:sz3(i)) = uint8(255);
mat.p3(:,i,1:sz3(i)) = -1;
mat.p4(:,i,1:sz3(i)) = 0.01;
end
old_mat = struct('p1',mat.p1,'p3',mat.p3,'p4',mat.p4);
Upvotes: 1