How to get rid of this nested for cycles?
Afficher commentaires plus anciens
Here is my code:
% simulating similar inputs:
K = 3;
H = 250;
N = 50;
B = 10;
Q = cell(1,K);
rng('default')
Q = cellfun(@(x) rand(H, N, B) - rand(H, N, B),Q, 'UniformOutput', false);
% here starts my problem:
cumret = cellfun(@cumsum,Q,'UniformOutput',false);
rev = cell(1,3);
% i would like to get rid of the following triple for clycles:
for k = 1:K
for i = 1:N
for b = 1:B
rev{1,k}(:,b,i) = cumret{1,k}(:,i,b);
end
end
end
% and to get this very same result (whic is correct but slow to compute):
rev = cell2mat(rev);
% in other terms the following two plot must be the same:
figure(1)
for k = 1:K
for b = 1:B
plot(cumret{1,k}(:,1,b))
hold on
end
end
figure(2)
plot(rev(:,:,1))
Thank you in advance for your kind help.
Réponse acceptée
Plus de réponses (2)
I assume that you cannot change Q, and you need to calculate rev from Q.
% simulating similar inputs:
K = 3;
H = 250;
N = 50;
B = 10;
Q = cell(1,K);
rng('default')
Q = cellfun(@(x) rand(H, N, B) - rand(H, N, B),Q, 'UniformOutput', false);
Here is your original code for calculating rev from Q:
% here starts my problem:
cumret = cellfun(@cumsum,Q,'UniformOutput',false);
rev = cell(1,3);
% i would like to get rid of the following double for clycles:
for k = 1:K
for i = 1:N
for b = 1:B
rev{1,k}(:,b,i) = cumret{1,k}(:,i,b);
end
end
end
% and to get this very same result (whic is correct but slow to compute):
rev = cell2mat(rev);
Here is another way to calculate rev from Q. See the comments in the code for an explanation of each step and the links for a detailed description of each function used:
rev_test = permute( reshape( cumsum( cat(4, Q{:}), 1), [H N B*K]), [1 3 2]);
% ^^^^^^^^^^^^ concatenate the contents of the cells of Q, making a 250x50x10x3 array
% ^^^^^^^^^^^^^^^^^^^^^^^^ then cumsum that 4D array along its 1st dimension
% ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reshape that 4D cumsum'ed array to be 250x50x30
% ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ permute to 250x30x50
% and it gives the same result:
isequal(rev_test,rev)
3 commentaires
Barbab
le 1 Août 2023
Bruno Luong
le 1 Août 2023
More to the point, you see in the Voss's code the following,
... cat(4, Q{:}) ...
It simply first converts cell array to 4D array.
If you insist on using cell fomat you would have to do it many many times.
Voss
le 1 Août 2023
"when you cite my code, the triple for cycle is different from mine. Is there a specific reason for that?"
No reason, except that I made a mistake. I began by editing your code to remove some loops, and I mistakenly didn't put it back the way you had it. I've edited my answer so that your original code should be accurate now.
Bruno Luong
le 1 Août 2023
If you want to work with cell
% simulating similar inputs:
K = 3;
H = 250;
N = 50;
B = 10;
Q = cell(1,K);
rng('default')
Q = cellfun(@(x) rand(H, N, B) - rand(H, N, B),Q, 'UniformOutput', false);
% here starts my problem:
cumret = cellfun(@cumsum,Q,'UniformOutput',false);
% rev = cell(1,3);
% for k = 1:K
% for i = 1:N
% for b = 1:B
% rev{1,k}(:,b,i) = cumret{1,k}(:,i,b);
% end
% end
% end
rev = cellfun(@(a) permute(a, [1 3 2]), cumret, 'UniformOutput',false);
% and to get this very same result (whic is correct but slow to compute):
% rev2 = cell2mat(rev);
rev = cat(2, rev{:}); % faster
% in other terms the following two plot must be the same:
figure(1)
for k = 1:K
for b = 1:B
plot(cumret{1,k}(:,1,b))
hold on
end
end
figure(2)
plot(rev(:,:,1))
Catégories
En savoir plus sur Matrix Indexing dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!



