Asked by Javad
on 15 Mar 2018

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.

Answer by Stephen Cobeldick
on 15 Mar 2018

Edited by Stephen Cobeldick
on 16 Mar 2018

Accepted Answer

"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

Sign in to comment.

Answer by Michelangelo Ricciulli
on 15 Mar 2018

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.

Stephen Cobeldick
on 15 Mar 2018

@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.

Michelangelo Ricciulli
on 15 Mar 2018

Sign in to comment.

Answer by ahmad mahmoodi
on 14 Oct 2018

Edited by Walter Roberson
on 14 Oct 2018

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.

Walter Roberson
on 16 Oct 2018

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
on 18 Nov 2018

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

Walter Roberson
on 18 Nov 2018

Can you attach your full code and input data?

Sign in to comment.

Answer by ahmad mahmoodi
on 19 Nov 2018

Edited by Walter Roberson
on 19 Nov 2018

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".

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.