MATLAB MATLAB: Simple Loop - Storing Arrays as Variables

  • Thread starter Thread starter ephedyn
  • Start date Start date
  • Tags Tags
    Loop Matlab
AI Thread Summary
The discussion revolves around a MATLAB user seeking advice on storing arrays as variables and implementing a loop for a complex code involving PDEs. The user initially attempts to create individual variables for each result but is advised to utilize a single 3D matrix for efficiency. Key points include the importance of using MATLAB's matrix operations over traditional loops for better performance and the clarification that MATLAB indexing starts at 1, not 0. The conversation highlights the user's gradual understanding of the benefits of matrix operations and their intention to transition to a more efficient coding approach. Ultimately, the user expresses a desire to implement these suggestions effectively.
ephedyn
Messages
169
Reaction score
1
OK, I've a much more complicated code, but I've simplified the below to portend to my question more specifically.

Basically, I want to store some arrays as variables in the following manner:
q1 = 2
q2 = 3
q3 = 4
...
...
q9 = 10
q10 = 11

Does anyone know what I should use instead of the parentheses "[ ]" which would have worked in C++?
%code%
for r = 0:10;
q[r]=1+r;
end

Thanks in advance!
 
Physics news on Phys.org
Use () instead of [].
Also, you can't use 0 as an index in Matlab; i.e. the first element in an array is element 1 (in your case q(1) )
 
Hmm, thanks for the help, it came up with a 1x10 matrix which would have been good for my stated problem, but I think what I really need are 10 1x1 matrices. I apologise that I didn't elaborate further as I'm not sure if I can clearly express the full problem, but maybe it will make more sense to you if I try to elaborate what I'm doing anyway:

I have 2 M-files, 1 containing a PDE geometry (order5gloop), and 1 containing its boundary conditions (order5bloop).

function [x,y]=order5gLOOP(bs,s)
%ORDER5GLOOP Creates a geometry file for an enclosed region.

% Number of boundary segments
nbs=4;

if nargin==0 % Number of boundary segments
x=nbs;
return
end

dl=[
0 0 0 0 % start parameter value
2 1 1 1 % end parameter value
0 0 0 0 % left hand region
1 1 1 1 % right hand region
];

bs1=bs(:)';

if find(bs1<1 | bs1>nbs),
error('PDE:order5gLOOP:InvalidBs', 'Non existent boundary segment number.')
end

if nargin==1,
x=dl(:,bs1);
return
end

x=zeros(size(s));
y=zeros(size(s));
[m,n]=size(bs);
if m==1 && n==1,
bs=bs*ones(size(s)); % expand bs
elseif m~=size(s,1) || n~=size(s,2),
error('PDE:order5gLOOP:SizeBs', 'bs must be scalar or of same size as s.');
end% Loop order
if ~isempty(s),
for r = 1.00: 0.01: 1.05

% boundary segment 1
ii=find(bs==1);
if ~isempty(ii)
x(ii)=s(ii);
y(ii)= (r-1)*(-5/4*(s(ii).^3)+15/16*(s(ii).^4)-6/32*(s(ii).^5))+r;
end

% boundary segment 2
ii=find(bs==2);
if ~isempty(ii)
x(ii)=interp1([dl(1,2),dl(2,2)],[2 2],s(ii));
y(ii)=interp1([dl(1,2),dl(2,2)],[1 0],s(ii));
end

% boundary segment 3
ii=find(bs==3);
if ~isempty(ii)
x(ii)=interp1([dl(1,3),dl(2,3)],[2 0],s(ii));
y(ii)=interp1([dl(1,3),dl(2,3)],[0 0],s(ii));
end

% boundary segment 4
ii=find(bs==4);
if ~isempty(ii)
x(ii)=interp1([dl(1,4),dl(2,4)],[0 0],s(ii));
y(ii)=interp1([dl(1,4),dl(2,4)],[0 r],s(ii));
end

end

end

There's obviously something wrong with the above as I'm not sure where to place the "for" command.

Manually, I would have filled in a real number as "r" and used the following commands to solve the PDE:

[p,e,t]=initmesh('order5gLOOP');
[p,e,t]=refinemesh('order5gLOOP',p,e,t);
[p,e,t]=refinemesh('order5gLOOP',p,e,t);
[p,e,t]=refinemesh('order5gLOOP',p,e,t);
[p,e,t]=refinemesh('order5gLOOP',p,e,t);
u=assempde('order5bLOOP',p,e,t,-1.0,0,0);
pdeplot(p,e,t,'xydata',u,'mesh','off','contour','on','levels',20,'colormap','white','colorbar','off','xygrid','on'), axis equal
C=sortrows([transpose(p) u]);

But I would prefer if I could loop for r=1:0.01:4 (writing 400 of these is impractical), and put each set of results (this gives me 3 columns: x, y, u) as variables C1, C2, C3, C4, C5... i.e. C(r). It makes my life easier to have different matrices... I think, as I will have to calculate the standard deviation of [u_(n) - u_(n-1)]/[y_(n) - y_(n-1)] where x=2 of each C.
Would anyone kindly know where I could start the loop command and what I should do for the C1, C2... etc. problem?

Thanks in advance!
 
But why would you use different matricies? Why not just a single matrix and an index (in this case a 1D matrix, i.e. an array)?
It might be conceptually slightly more difficult to understand but it is definately more efficient.
Also, why can't you simply use a loop when you calculate the standard devition and store the result in a new vector?

Moreover, note that you can use 3D matricies in Matlab meaning there is nothing stopping you from storing many 2D matrices in a single 3D matrix (with one index use as a "label").

Generally speaking you should ALWAYS use matricies when you can in Matlab and preferably also matrix operations this are much more efficent than for-loops.
 
f95toli said:
But why would you use different matricies? Why not just a single matrix and an index (in this case a 1D matrix, i.e. an array)?
It might be conceptually slightly more difficult to understand but it is definately more efficient.
Also, why can't you simply use a loop when you calculate the standard devition and store the result in a new vector?

Moreover, note that you can use 3D matricies in Matlab meaning there is nothing stopping you from storing many 2D matrices in a single 3D matrix (with one index use as a "label").

Generally speaking you should ALWAYS use matricies when you can in Matlab and preferably also matrix operations this are much more efficent than for-loops.

OK, I thought it through and realized that you're right about using a single 3D matrix. Your help has been much appreciated.

My concern now is how to implement this. You mentioned that "matrix operations are much more efficient than for-loops [for this]", could you give me a nudge in the direction to get started? My for-loop still doesn't work, and I don't mind abandoning it for whatever is more efficient. I tried changing the head (see the blue parts) and introducing the (r):

function [x,y]=order5gLOOP(bs,s)
%ORDER5GLOOP Creates a geometry file for an enclosed region.

% Loop order
r = 'arbitraryr'

% Number of boundary segments
nbs=4;

if nargin==0 % Number of boundary segments
x=nbs;
return
end

dl=[
0 0 0 0 % start parameter value
2 1 1 1 % end parameter value
0 0 0 0 % left hand region
1 1 1 1 % right hand region
];

bs1=bs(:)';

if find(bs1<1 | bs1>nbs),
error('PDE:order5gLOOP:InvalidBs', 'Non existent boundary segment number.')
end

if nargin==1,
x=dl(:,bs1);
return
end

x=zeros(size(s));
y=zeros(size(s));
[m,n]=size(bs);
if m==1 && n==1,
bs=bs*ones(size(s)); % expand bs
elseif m~=size(s,1) || n~=size(s,2),
error('PDE:order5gLOOP:SizeBs', 'bs must be scalar or of same size as s.');
end

if ~isempty(s),

% boundary segment 1
ii=find(bs==1);
if ~isempty(ii)
x(ii)=s(ii);
y(ii)= (r-1)*(-5/4*(s(ii).^3)+15/16*(s(ii).^4)-6/32*(s(ii).^5))+r;
end

% boundary segment 2
ii=find(bs==2);
if ~isempty(ii)
x(ii)=interp1([dl(1,2),dl(2,2)],[2 2],s(ii));
y(ii)=interp1([dl(1,2),dl(2,2)],[1 0],s(ii));
end

% boundary segment 3
ii=find(bs==3);
if ~isempty(ii)
x(ii)=interp1([dl(1,3),dl(2,3)],[2 0],s(ii));
y(ii)=interp1([dl(1,3),dl(2,3)],[0 0],s(ii));
end

% boundary segment 4
ii=find(bs==4);
if ~isempty(ii)
x(ii)=interp1([dl(1,4),dl(2,4)],[0 0],s(ii));
y(ii)=interp1([dl(1,4),dl(2,4)],[0 r],s(ii));
end

end

for arbitraryr = 1:0.01:4;
[p,e,t]=initmesh('order5gLOOP');
[p,e,t]=refinemesh('order5gLOOP',p,e,t);
[p,e,t]=refinemesh('order5gLOOP',p,e,t);
[p,e,t]=refinemesh('order5gLOOP',p,e,t);
[p,e,t]=refinemesh('order5gLOOP',p,e,t);
u(r)=assempde('order5bLOOP',p,e,t,-1.0,0,0);
pdeplot(p,e,t,'xydata',u,'mesh','off','contour','o n','levels',20,'colormap','white','colorbar','off' ,'xygrid','on'), axis equal
C(r)=sortrows([transpose(p) u]);
end

Thanks!
 
What do you want to do with matrix operation. I read you post, but I'm sorry I can't understand your question. Please give a more specific piece of code. The m file you give us is too long to understand.
 
Sorry that I didn't reply for a long time (it would be rude not to considering you've offered your help and read through my post), I've been busy with my medical checkups.

I can't explain my problem any better; I'm trying to settle it myself instead and work towards using a 3D matrix as suggested.

Nonetheless, thanks.
 

Similar threads

Replies
5
Views
3K
Replies
4
Views
2K
Replies
5
Views
1K
Replies
4
Views
2K
Replies
2
Views
3K
Replies
4
Views
8K
Replies
3
Views
7K
Back
Top