MATLAB Answers

0

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.

Asked by Zachary Bassett on 4 Apr 2017
Latest activity Commented on by 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

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?
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];
summation = [];
for i = 1:size(moment,1)
x = moment(i,:,1);
for j = 1:size(moment,1)
y = moment(j,:,2);
for k = 1:size(moment,1)
z = moment(k,:,3);
for ii = 1:size(moment,1)
xx = moment(ii,:,4);
summation = [summation;x+y+z+xx];
end
end
end
end
Here's an updated version of the code that fixes the "sum" and size(moment,1). Thanks for the suggestions!
What I would like to be flexible with the code is that the size of the array can be an n x 3. It will also always be a 3-dimensional array but the number of arrays in the 3rd dimension can also vary in size.

Sign in to comment.

3 Answers

Answer by David Goodmanson on 4 Apr 2017
Edited by David Goodmanson on 4 Apr 2017
 Accepted Answer

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

Thanks but i didn't ask it :-p, but it is much more elegant. I didn't have much time to try to put an elegant solution of going through each permutation of all the sums or rows.
Joseph and David, thank you so much! Both of those methods work for what I'm trying to do. I'd been racking my brain for a day trying to figure out how to do this.
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.

Sign in to comment.


Answer by 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

Sign in to comment.


Answer by 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

Sign in to comment.