Is there a way to remove the nested for loops from this segment of code? I'm trying to make the code generic so it can take in n-number of moment arrays.
2 views (last 30 days)
Show older comments
Zachary Bassett
on 4 Apr 2017
Commented: David Goodmanson
on 5 Apr 2017
moment(:,:,1) = [1 0 0; 2 1 0];
moment(:,:,2) = [2 2 2; 3 0 1];
moment(:,:,3) = [3 1 2; 1 1 1];
moment(:,:,4) = [1 0 0; 0 0 1];
sum = [];
for i = 1:size(moment)
x = moment(i,:,1);
for j = 1:size(moment)
y = moment(j,:,2);
for k = 1:size(moment)
z = moment(k,:,3);
for ii = 1:size(moment)
xx = moment(ii,:,4);
sum = [sum;x+y+z+xx];
end
end
end
end
2 Comments
Jan
on 4 Apr 2017
Edited: Jan
on 4 Apr 2017
Do not use "sum" as a name of a variable. This shadowing of built-in function causes unexpected behavior frequently, when the function sum() is used later.
Does for i = 1:size(moment) do, what you expect? size(moment) replies a vector. So better use: size(moment, 1) to avoid confusions.
What sould be flexible in the code? The number of dimension, the size of the array?
Accepted Answer
David Goodmanson
on 4 Apr 2017
Edited: David Goodmanson
on 4 Apr 2017
Hello Joseph, I believe this does what you want. It assumes you have a 3d array called momentarray, containing an arbitrary number of moment matrices. It should work for any number of moment matrix rows and columns. I called each moment matrix a layer in the 3d array. S is the result.
The code does not preallocate any arrays so it is inefficient that way but it is still fast enough for reasonably sized S.
n = size(momentarray,3); % number of moment matrices
m = size(momentarray,1); % number of rows in each moment matrix
S = momentarray(:,:,n);
layr = n-1;
while layr >= 1
rowS = size(S,1);
temp = [];
for j = 1:m % loop over rows in a layer
a = repmat(momentarray(j,:,layr),rowS,1); % duplicate the row
temp = [temp;a+S]; % add to previous S and concatenate
end
S = temp;
layr = layr-1;
end
3 Comments
David Goodmanson
on 5 Apr 2017
Hello Zachary and Joseph,
Oops, in my answer I should have said hello to Zachary, but thanks to each of you for your comments. As Joseph mentioned it does help a lot to have adequate time to work out an answer. This site can become habit forming, though.
More Answers (2)
Spencer Chen
on 4 Apr 2017
Not exactly sure if this is what you are looking for:
> sum(moment,3);
to sum the 3rd dimension of the matrix?
0 Comments
Joseph Cheng
on 4 Apr 2017
to make it more generic you could do something like
momentind = [1 1 1 1 1 1]
cind = 1;
while momentind(end)~=3;
%perform sum
% temp = 0;
% for ind = 1:numel(momentind)
% temp = temp+moment(momentind(end-ind+1),:,ind);
% end
%increment last index but check for carryovers
momentind(cind)=momentind(cind)+1;
for ind = 1:numel(momentind)-1
Covers = mod(momentind,3);
Coverinds = find(Covers==0);
momentind(Coverinds+1)=momentind(Coverinds+1)+1;
momentind(Coverinds)=1
end
end
where you can keep a index counter that increments by 1 for the last dimension and then look for carry overs which would increment the next. with this index list you can then just go through it with a loop
0 Comments
See Also
Categories
Find more on Data Distribution Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!