MATLAB: Simple Loop - Storing Arrays as Variables

  • Context: MATLAB 
  • Thread starter Thread starter ephedyn
  • Start date Start date
  • Tags Tags
    Loop Matlab
Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
6 replies · 13K views
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 definitely 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 definitely 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.