How do I store intermediate values of a while loop in an array?

3 views (last 30 days)
I am trying to create the array &nbsp CODE_NUMBERS=[members a b c d] &nbsp for all iterations of the while loop below.
NSC=[9;10;1;2;3;11;4;12;5;6;7;8];
MPRP=[1 1 2 29e3 8;2 2 3 129e3 8;3 3 4 1e4 16;4 5 6 29e3 8;5 2 5 29e3 8;6 3 6 29e3 81;7 1 5 29e3 12;8 2 6 29e3 12;9 3 5 29e3 12;10 4 6 29e3 16];
NCJT=2;
m=length(MPRP);
members=MPRP(:,1);
JB=MPRP(:,2); %MEMBER BEGINNING NODES
JE=MPRP(:,3); %MEMBER END NODES
i=1;
while i<=m
a=NSC((JB(i)-1)*NCJT+1);
b=NSC((JB(i)-1)*NCJT+2);
c=NSC((JE(i)-1)*NCJT+1);
d=NSC((JE(i)-1)*NCJT+2);
i=i+1;
end
  1 Comment
per isakson
per isakson on 18 Mar 2017
Edited: per isakson on 18 Mar 2017
Replace the while-loop by
CODE_NUMBERS = nan( m, 4 );
while i<=m
a=NSC((JB(i)-1)*NCJT+1);
b=NSC((JB(i)-1)*NCJT+2);
c=NSC((JE(i)-1)*NCJT+1);
d=NSC((JE(i)-1)*NCJT+2);
%
CODE_NUMBERS( i, 1:4 ) = [a,b,c,d];
i=i+1;
end
What's &nbsp members?

Sign in to comment.

Answers (1)

dpb
dpb on 18 Mar 2017
Edited: dpb on 20 Mar 2017
No loops needed...
a=NSC((MPRP(:,2)-1)*NCJT+1);
b=a+1;
c=NSC((MPRP(:,3)-1)*NCJT+1);
d=c+1;
More than likely keeping these as a 2D array will turn out to be more useful than four separate variables as just a guess...
ADDENDUM
"Use the vectors, Luke!" :) Matlab is made for this--
"...is not practical to remove the loop"
With your intermediary variables already defined, the loop can be written as
X=xx(BJ)-xx(EJ);
Y=yy(BJ)-yy(EJ);
L=hypot(X,Y);
C=X./L;S=Y./L;
EA=MPRP(:,4).*MPRP(:,5)./L; % your E1*A1/L expression
CC=C.*C;CS=C.*S;SS=S.*S; % some shorthand of my own...
GK=bsxfun(@times,EA,[CC CS -CC -CS CS SS -CS -SS -CC -CS CC CS -CS -SS CS SS]);
GK=reshape(GK.',4,4,[]); % recast into 4x4x10 from 16x10
The only really tricky thing in the above is the need to transpose the array GK in the reshape operation so the columns when rearranged in order will be in proper row,column order as you've laid them out in your 2D array. I even checked to be certain after the fact (in the command window version pasted below I used G for the target of the reshape operation rather than overwriting GK as above to keep the two for checking logic)...
>> k=0;
for j=1:4
for i=1:4
k=k+1;disp([j i all(squeeze(G(j,i,:))==GK(:,k))]),
end,end
1 1 1
1 2 1
1 3 1
1 4 1
2 1 1
2 2 1
2 3 1
2 4 1
3 1 1
3 2 1
3 3 1
3 4 1
4 1 1
4 2 1
4 3 1
4 4 1
>>
This gives row,column and a 'T' indication the corresponding 3D vector at that location is the same as the one in the 2D array built earlier from left-to-right from your array. One could lay out that array in column-major order instead (reading down columns instead of across rows) and then the transpose wouldn't be needed (or wanted).
  4 Comments
dpb
dpb on 20 Mar 2017
Edited: dpb on 20 Mar 2017
"...is not practical to remove the loop"
Au contraire!!! :)
Updated Answer to reflect this case as well; although does take some thinking about how to get from a 2D to 3D representation via manipulation of dimensions and the necessary ordering in memory for that to be the correct elements.
But, to answer the original question, in a loop (the control for which should be for j=1:NJ btw, not 1:n as written) you'd need to write a plane at a time as
GK(:,:,j)= rhs;
where rhs is the expression for the elements for each plane you've written; you can overwrite the components therein as you don't need them once you've stored that plane in the final array.
You should, of course, preallocate the array before beginning the loop as
GK=zeros(4,4,10);
for efficiency.
The storage I chose is to to use the plane of a 3D array; alternatively one could use a cell array to hold 10 2D arrays; it would depend on how this is to be used later on although I would try to avoid cell arrays if at all possible; their accessibility can be an issue sometimes in referring to pieces across cells if that is needed.
dpb
dpb on 20 Mar 2017
Edited: dpb on 20 Mar 2017
"...works for this particular situation, but no[t] all loop situations."
Just one last comment prompted by the above...this is true: some operations just cannot be vectorized or can be only by such convoluted logic as to make the vector solution almost illegible and possibly even slower than a straightforward loop.
Learning which is which is something that comes with "time in grade" using Matlab. With time and practice and with some effort expended in learning more advanced techniques, one becomes more and more proficient in recognizing how to attack writing code. In this case, the key to identify is that Matlab automagically has element-wise operations on the elements in vectors and arrays and so even if the final assignment were to be done in a loop all the intermediary results can be computed quite simply.
After that, the last step of building the final array from those pieces is, granted, a fair leap for the novice; it requires there to be able to envision a storage pattern that can be operated on to produce the final desired one.
Of course, depending on the usage, it's possible that the 4x4 arrangement by column wouldn't be needed; you could write an indexing expression to use the earlier 2D arrangement or, since the array is symmetric around the diagonal, only those elements would actually have to be stored in that case and the lookup table would return the phantom symmetric location for the UR quadrant if the LL were all that were stored.

Sign in to comment.

Categories

Find more on Characters and Strings in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!