How can I show variable index in a for loop?

I have 100 matrices, name x1, x2, ..., x100. I want to do the below process for all 100 variables using a "for loop" (i=1:100). As an instance I have written this process for variable x1.
x1=mat2gray(squeeze(x1)); save ('x1.mat', 'x1'); imwrite(x1, 'x1.tiff'); figure, imshow('x1.tiff');
I kindly appreciate any suggestion.

 채택된 답변

Stephen23
Stephen23 2018년 3월 15일
편집: Stephen23 2018년 3월 16일

0 개 추천

"I have 100 matrices, name x1, x2, ..., x100. I want to do the below process for all 100 variables using a "for loop""
Accessing variables like that is how beginners force themselves into writing slow, complex, buggy code that is hard to debug. In 99.99% of cases it is trivial to avoid this situation, which then makes code faster, simpler, and easier to debug. You can read about the reasons why this is a slow and inefficient way to write code:
The most important question is: how did you get those variables into the workspace? The two most common ways that are by load-ing a .mat file directly into the workspace, or by magically defining variable names in a loop. Both of these are trivial to avoid, for example instead of load-ing directly into the workspace, simply load into a variable (which is a structure) and loop over its fieldnames:
S = load(...);
C = fieldnames(S);
for k = 1:numel(C)
S.(C{k})
end

추가 답변 (3개)

Michelangelo Ricciulli
Michelangelo Ricciulli 2018년 3월 15일

2 개 추천

Hi there, a quick and dirty method could be using the eval function. First you define the variable name
var=['x' num2str(i)];
then you can write your entire command as a string
cmd=[var '=mat2gray(squeeze(' var ')); save (''' var '''.mat'', ''' var ''');']
Finally you can just run
eval(cmd);
By the way, the next time you could use just one 3d matrix, (e.g., x(:,:,i)) or a cell array.

댓글 수: 2

Stephen23
Stephen23 2018년 3월 15일
편집: Stephen23 2018년 3월 15일
@Michelangelo Ricciulli: you could help teach other users how to avoid slow, complex, inefficient code practices with a bit more detail than just "use just one 3d matrix... or a cell array": how about telling them why. For example, show why the MATLAB documentation specifically recommends avoiding doing what you have written in your answer: "A frequent use of the eval function is to create sets of variables such as A1, A2, ..., An, but this approach does not use the array processing power of MATLAB and is not recommended. The preferred method is to store related data in a single array"
@Javad: eval is what beginners use to force themselves into writing slow, complex, buggy code that is hard to debug. Expert users to do not use eval for trivially accessing variable names in a loop, but instead use indexing, which is simple, neat, and very efficient.
Hi Stephen. I realized after I submitted the answer that it would have been probably better to start with a correct example and then, only after that, explain the "dirty" method for sake of completeness.

댓글을 달려면 로그인하십시오.

ahmad mahmoodi
ahmad mahmoodi 2018년 10월 14일
편집: Walter Roberson 2018년 10월 14일

0 개 추천

Hello all,
How can I simply write a code like this:
function dT=Mesal(T,t)
n=100;
dT=zeros(n,1);
for i=1:n
if i==1
dT(i)=T(i);
elseif i==n
dT(i)=T(i-1);
else
dT(i)=T(i+1);
end
end
Thank you in advance.

댓글 수: 8

madhan ravi
madhan ravi 2018년 10월 14일
Ask a separate question
dT = reshape(T([1, 3:n, n]),[],1);
ahmad mahmoodi
ahmad mahmoodi 2018년 10월 15일
편집: Walter Roberson 2018년 10월 15일
Hello Walter. Thank you for the response. I am a beginner in Matlab. I do not know how to use the command you mentioned inside my code.
Here is my main Matlab code that I have problem with indexing it. Please let me know your comment about the way of solving it. Thank you in advance.
function dT = Fb5(t, T)
A, B, C and all coefficients are defined here
dT=zeros(4*n,1);
for i=1:n
if i==1
T(4*i-1,:)=90;
dT(4*i-3)=A*T(4*i-3)+B*T(4*i-1)+C*T(4*i-2)+G;
dT(4*i-2)=A*T(4*i-2)+B*T(4*i)+C*T(4*i-3)+G;
dT(4*i)=D*T(4*i)+E*T(4*i+4)+F*T(4*i-2);
elseif i==n
dT(4*i-3)=A*T(4*i-3)+B*T(4*i-1)+C*T(4*i-2)+G;
dT(4*i-2)=A*T(4*i-2)+B*T(4*i-1)+C*T(4*i-3)+G;
dT(4*i-1)=D*T(4*i-1)+E*T(4*i-5)+F*T(4*i-3);
else
dT(4*i-3)=A1*T(4*i-3)+B1*T(4*i-1)+C1*T(4*i-2)+Gi;
dT(4*i-2)=A1*T(4*i-2)+B1*T(4*i)+C1*T(4*i-3)+Gi;
dT(4*i-1)=D1*T(4*i-1)+E*T(4*i-5)+F1*T(4*i-3);
dT(4*i)=D1*T(4*i)+E*T(4*i+4)+F1*T(4*i-2);
end
end
end
Then I want to use ode45 to solve it
T0(1:4*n,1)=15;
[t,T] = ode45(@Fb5,[0 100000],T0);
plot(t,T(:,2),'-o')
What size is T? T(4*i-1,:)=90; uses it as if it were 2D. Most of the entries use it in a way that would be consistent with it being a vector of length 4*n.
ahmad mahmoodi
ahmad mahmoodi 2018년 10월 15일
편집: Walter Roberson 2018년 10월 15일
I specified dT as the function of T nd t at the beginnig. By defining size of dT as zeros(4*n,1), I am specifying size of T as well (that is (4*n,1)). I changed T(4*i-1,:) to T(4*i-1)=90 to have a 1D problem (as you mentioned), but It doesn't work again. I think the problem maybe with indexing.
I followed the example of Matlab (Matlab help ode45). Here is the question: What should I do to solve it like the Matlab example (I write it here)? Thanks again
Matlab example:
function dy = vdp1000(t,y)
dy = zeros(2,1);
dy(1) = y(2);
dy(2) = 1000*(1 - y(1)^2)*y(2) - y(1);
[T,Y] = ode15s(@vdp1000,[0 3000],[2 0]);
plot(T,Y(:,1),'-o')
I think this should do it without a loop:
dT=zeros(4*n,1);
v4 = (4:4:(n-1)*4)-4;
T(4*1-1)=90; %i == 1 case, must be done before 4*1-3 line
dT(4*1-3)=A*T(4*1-3)+B*T(4*1-1)+C*T(4*1-2)+G; %i == 1 case
dT(4*1-2)=A*T(4*1-2)+B*T(4*1)+C*T(4*1-3)+G; %i == 1 case
dT(4*1)=D*T(4*1)+E*T(4*1+4)+F*T(4*1-2); %i == 1 case
dT(4*2-3+v4)=A1*T(4*2-3+v4)+B1*T(4*2-1+v4)+C1*T(4*2-2+v4)+Gi;
dT(4*2-2+v4)=A1*T(4*2-2+v4)+B1*T(4*2+v4)+C1*T(4*2-3+v4)+Gi;
dT(4*2-1+v4)=D1*T(4*2-1+v4)+E*T(4*2-5+v4)+F1*T(4*2-3+v4);
dT(4*2+v4)=D1*T(4*2+v4)+E*T(4*2+4+v4)+F1*T(4*2-2+v4);
dT(4*n-3)=A*T(4*n-3)+B*T(4*n-1)+C*T(4*n-2)+G; %i == n case
dT(4*n-2)=A*T(4*n-2)+B*T(4*n-1)+C*T(4*n-3)+G; %i == n case
dT(4*n-1)=D*T(4*n-1)+E*T(4*n-5)+F*T(4*n-3); %i == n case
ahmad mahmoodi
ahmad mahmoodi 2018년 11월 18일
Hello Walter,
Thank you for your answer. It works but the results are not as expected. They will be dependent on "n" too much. for example if I define n=10 the output which is T(4) will converge to 60 and if I set "n" on 20, T(4) will converge to 120. n should just affect the precision of the output which should converge to 90 (T(4*1-1)).
I checked the coefficients many times and the problem is not with them because I ran my code with the same coefficients in another software and it perfectly worked.
Regards
Can you attach your full code and input data?

댓글을 달려면 로그인하십시오.

ahmad mahmoodi
ahmad mahmoodi 2018년 11월 19일
편집: ahmad mahmoodi 2018년 11월 19일

0 개 추천

This is the main code considering your comment:
function dT = Fb6(t, T)
c_p_grout=1500;
rho_grout=1460;
lambda_grout=1.5;
c_p_fluid=4183;
rho_fluid=997.6;
lambda_soil=2.51225;
lambda_fluid=0.5913;
m_dot=0.46;
L=300; %L and dL can be changed to have different n
dl=20;
n=L/dl+1;
dT=zeros(4*n,1);
d_b=0.2;
d_a=0.04;
d_i=d_a-2*0.0037;
d_s1=0.22;
d_z1=sqrt((d_b^2+d_s1^2)/2);
R_conv=0.00670;
R_cond_1=0.08568;
x=0.70275;
R_a=0.23701;
R_b=0.073;
R_g=4*R_b-R_conv-R_cond_1;
R_gg=1/((1/(R_a-R_conv-R_cond_1-x*R_g))-(1/(1-x)/R_g))*4;
R_fg=R_conv+R_cond_1+x*R_g;
R_gb=(1-x)*R_g;
R_gg1=R_gg;
R_gg2=R_gg1;
R_fgred=R_fg/2;
R_gbred_wo_soil=R_gb/2;
R_ggred_wo_soil=1/((2/R_gg1)+(2/R_gg2));
R_bz1=log(d_z1/d_b)/(2*pi*lambda_soil);
R_gbred=R_gbred_wo_soil+2*R_bz1;
R_ggred=1/((1/R_ggred_wo_soil)+(1/2/R_gbred_wo_soil)-(1/2/R_gbred));
C_fluid1=2*rho_fluid*c_p_fluid*pi/4*d_i^2*dl/2;
C_fluid2=2*rho_fluid*c_p_fluid*pi/4*d_i^2*dl;
C_g1=rho_grout*(pi/4)*((d_b^2/2)-(2*d_a^2))*c_p_grout*dl/2;
C_g2=rho_grout*(pi/4)*((d_b^2/2)-(2*d_a^2))*c_p_grout*dl;
T_b=15;
A=(-dl/2)*((1/C_g1*R_ggred)+(1/C_g1*R_gbred)+(1/C_g1*R_fgred));
B=(dl/2)*(1/C_g1*R_fgred);
C=(dl/2)*(1/C_g1*R_ggred);
D=(-dl/2)*((1/C_fluid1*R_fgred))-(m_dot*c_p_fluid/C_fluid1);
E=(m_dot*c_p_fluid/C_fluid1);
F=(dl/2)*(1/C_fluid1*R_fgred);
G=(dl/2)*(T_b/C_g1*R_gbred);
A1=(-dl)*((1/C_g2*R_ggred)+(1/C_g2*R_gbred)+(1/C_g2*R_fgred));
B1=(dl)*(1/C_g2*R_fgred);
C1=(dl)*(1/C_g2*R_ggred);
D1=(-dl)*((1/C_fluid2*R_fgred))-(m_dot*c_p_fluid/C_fluid2);
E1=(m_dot*c_p_fluid/C_fluid2);
F1=(dl)*(1/C_fluid2*R_fgred);
Gi=(dl)*(T_b/C_g2*R_gbred);
v4 =(4:4:(n-1))-4;
T(4*1-1)=90; %i == 1 case, must be done before 4*1-3 line v4 = (4:4:(n-1))-4
dT(4*1-3)=A*T(4*1-3)+B*T(4*1-1)+C*T(4*1-2)+G; %i == 1 case
dT(4*1-2)=A*T(4*1-2)+B*T(4*1)+C*T(4*1-3)+G; %i == 1 case
dT(4*1)=D*T(4*1)+E*T(4*1+4)+F*T(4*1-2); %i == 1 case
dT(4*2-3+v4)=A1*T(4*2-3+v4)+B1*T(4*2-1+v4)+C1*T(4*2-2+v4)+Gi;
dT(4*2-2+v4)=A1*T(4*2-2+v4)+B1*T(4*2+v4)+C1*T(4*2-3+v4)+Gi;
dT(4*2-1+v4)=D1*T(4*2-1+v4)+E1*T(4*2-5+v4)+F1*T(4*2-3+v4);
dT(4*2+v4)=D1*T(4*2+v4)+E*T(4*2+4+v4)+F1*T(4*2-2+v4);
dT(4*n-3)=A*T(4*n-3)+B*T(4*n-1)+C*T(4*n-2)+G; %i == n case
dT(4*n-2)=A*T(4*n-2)+B*T(4*n-1)+C*T(4*n-3)+G; %i == n case
dT(4*n-1)=D*T(4*n-1)+E*T(4*n-5)+F*T(4*n-3); %i == n case
end
and this is the code for solving it:
n=16; %from main code
T0(1:4*n,1)=15;
[t,T] = ode45(@Fb6,[0 10000],T0);
plot(t,T(:,4),'-o');
T(:,4) should converge to 90(T(4*1-1)) for different amounts of "n".

카테고리

도움말 센터File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

질문:

2018년 3월 15일

편집:

2018년 11월 19일

Community Treasure Hunt

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

Start Hunting!

Translated by