# For loops in Matlab

## Homework Statement

Can someone help me set up a "for loop" for this equation

I intialize hc = x0 then I have to compute
hc1 = C.*(log(hc./b)+1)+ gamma.*(1-exp(-hc./gamma))
hc2 = C.*(log(hc1./b)+1)+ gamma.*(1-exp(-hc1./gamma))
hc3 = C.*(log(hc2./b)+1)+ gamma.*(1-exp(-hc2./gamma))
hc4 = C.*(log(hc3./b)+1)+ gamma.*(1-exp(-hc3./gamma))
.
.
.
hcn = blah blah blah
for some certain number of iterations n.

Here C, gamma and b are constants.

I'm strugling for hours with this thing.

Ultimately, though i need to set a condition when hc(n+1)-hc(n) < 0.001 then stop the loop and somehow record or print that last number of the loop

Thank you.

If someone could help me with this I would greatly greatly appreciate it!!!

Because you just need to print a last value of hc, you should create 2 variables (ie: f_hc, l_hc, f_hc ~ hc(n-1) and l_hc ~ hcn). Put them in for loop, calculate l_hc, and compare its with your condition. If condition is not satisfied, you set f_hc = l_hc and going to next loop.

uhm.... I dont understand what you are thinking. imo, 'for loop' is a finite loop. Meanwhile, you are doing a task that requires an infinite loop until one condition is satisfied. So in this case, i prefer using while loop.

Thanks for your advice but I'm still not quite clear what you mean.

A while loop seems to be a better idea here. But how would I translate the following in code:

while
hc(n) - hc(n-1) < 0.001
end
otherwise continue
until
hc(n) - hc(n-1) <0.001

print (hc(n))

Thanks

Mark44
Mentor
You want your while loop to look something like this:

Code:
while hc(n) - hc(n-1) > 0.001
% Do some further calculations for hc(n) and hc(n-1)

end
final_result = hc(n)

For the while loop to end, it must be that eventually hc(n) - hc(n-1) < 0.001. If for some reason this doesn't happen, the loop is an infinite loop.

When the loop exits, the value of hc(n) is assigned to final_result, and this causes Ans = 3.123458 (whatever)
to be displayed.

Thanks for your response but could you explain a bit more "further calculations part". And a little more detail of the overall code if you don't mind.

I am doing some research with a professor and we have this equation which cannot be solved directly because it is implicit.

hc = C.*(log(hc./b)+1)+ gamma.*(1-exp(-hc./gamma)) (Eq. 1)

That is why we are giving it an intial guess for hc and then we are computing hc with that guess and use the value in the next result like i explained above. This was a good method because it ended up that the result will converge to the real answer in the end.

This is easily done in excel but I'm having a heck of hard time to do it in matlab because in excel its not really efficient for us.

Ultimately, we need a graph of hc versus gamma for different C,b.

Thank you very much!

Mark44
Mentor
Here is the code as I would do it. Note that my code doesn't use arrays as your code did. For this reason, I changed the ./ and .* array operators with the ordinary / and * operators.

The operation of the while loop is pretty straightforward; it starts off with some initial values for hc_old and hc_new. You will probably want to change these values. The while loop first compares hc_old and hc_new. If they are within .001 of each other, the while loop exits. Otherwise, it stores hc_new in hc_old, and then computes a value for hc_new. hc_new and hc_old are then tested again to see if they are within .001 of each other, and so on, as before.

I don't know much about graphing in matlab, so take a look at Chapter 3 in this documentation - http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/getstart.pdf.

Code:
% Put some initial values in for hc_old, hc_new, and gamma
hc_old = 1.0
hc_new = 2.0
% Replace the value below for gamma with the right one
gamma = 1.0
while abs(hc_new - hc_old) > 0.001
% Store previously computed value of hc_new in hc_old
hc_old = hc_new
% Calculate new value for hc_new
hc_new = C*(log(hc_old/b)+1)+ gamma*(1-exp(-hc_old/gamma))
end
final_result = hc_new

Hi Thank you very much for your help it was really helpful and I think I got the most important part to work. Sorry to bug you but just one more quick thing.

This is what I have so far. I just need to be able to plot final_result versus gamma_range. But do you know how I can store the values of final_result into an array outside the for loop so that then i can just do.

plot(gamma_range, final_result) and it should plot it.

Many thanks again

Code:
% Put some initial values in for hc_old.
hc_old = input('Please enter a "guessing" starting value for hc in microns: ');

% First loop, loops through gamma values and calculates first  hc_new for a
% given hc_old. Second loop, checks the condition of successive hc_new-s.

for gamma = 0.01:0.01:1.5 % We are looping for gamma from 0.01 microns to 1.5 microns
hc_new = C*(log(hc_old/b)+1)+ gamma*(1-exp(-hc_old/gamma));
% Checks that successive values of hc_new converge
while abs(hc_new - hc_old)>0.0000001
% Store previously computed value of hc_new in hc_old
hc_old = hc_new;
% Calculate new value for hc_new
hc_new = C*(log(hc_old/b)+1)+ gamma*(1-exp(-hc_old/gamma));
end
final_result = hc_new
end
%Range of gamma
gamma_range = [0.01:0.01:1.5]',

Last edited:
Mark44
Mentor
Try this. Instead of using gamma as your for loop control variable, I changed it to use i, which ranges from 1...150. Each iteration of the for loop uses a different value of gamma, from .01 to 1.50.

I made the final_result variable an array with 150 elements. Each iteration of the for loop puts its computed value for the given gamma value into final_result array. When the for loop finishes, each of the 150 cells of final_result should be set with a value that results from the gamma value used in a particular iteration of the for loop.
Code:
% Put some initial values in for hc_old.
hc_old = input('Please enter a "guessing" starting value for hc in microns: ');
final_result= zeros(150);

% First loop, loops through gamma values and calculates first  hc_new for a
% given hc_old. Second loop, checks the condition of successive hc_new-s.
for i = 1:150
% for gamma = 0.01:0.01:1.5 % We are looping for gamma from 0.01 microns to 1.5 microns
gamma = i/150.0
hc_new = C*(log(hc_old/b)+1)+ gamma*(1-exp(-hc_old/gamma));

% Checks that successive values of hc_new converge
while abs(hc_new - hc_old)>0.0000001
% Store previously computed value of hc_new(i) in hc_old
hc_old = hc_new;
% Calculate new value for hc_new(i)
hc_new = C*(log(hc_old/b)+1)+ gamma*(1-exp(-hc_old/gamma));
end
final_result(i) = hc_new
end
%Range of gamma
gamma_range = [0.01:0.01:1.5]',

This didn't work. It just gave me 150 zeros. I don't know why because theoretically it does make sense. But thank you for your effort. :)

Plus there is another problem here, I think when the for loop takes a 1 it calculates gamma as 1/150 = 0.006666 and it should be 0.01 and so on for the other values of i. ;)

Last edited:
can you give me all constant values and an error msg that you received?

Mark44
Mentor
This didn't work. It just gave me 150 zeros. I don't know why because theoretically it does make sense. But thank you for your effort. :)

Plus there is another problem here, I think when the for loop takes a 1 it calculates gamma as 1/150 = 0.006666 and it should be 0.01 and so on for the other values of i. ;)

Second problem first. Change this line:
Code:
gamma = i/150.0
to this:
Code:
gamma = i/100.0

For the first problem you mentioned, I see that the line of code that calculates hc_new for the first time is
Code:
hc_new = C*(log(hc_old/b)+1)+ gamma*(1-exp(-hc_old/gamma));

If you are running this code exactly as I gave it to you, neither of the constants C and b have been set. It's always a mistake to use variables that have not been initialized.

No, of course the C and b are being calculated beforehand. Here is the total code. Maybe you can run it yourself and see what it produces. I am getting just 150 zeros for final_result(i)
I need a graph of final_result array versus gamma_range array.
Many thanks for all your efforts.
-HK

Good values for the inputs are:
x_inf = 0.2 (it already considers the units dont need to enter units)
constant = -0.0668
% composition of x = 0.2
starting guess = 1

Code:
% CALCULATING THE CRITICAL LAYER THICKNESS FOR EXPONENTIALLY GRADED LAYERS
% THIS EXAMPLE CONSIDERS InGaAs MATERIAL PROPERTIES
% ALL DIMENSIONS ARE GIVEN IN MICRONS

%The derived eqaution for the exponentially graded critical layer thickness
%is: hc =
%{[(1-V*cos^2(alpha))b]/[8*pi*abs(f_inf)*(1+V)cos(lambda)]}LN((hc/b)+1)
% + gamma - gamma*exp(-hc/b)

%EXPLANATION OF VARIABLES
% Here lambda and alpha are constant angles taken usually 60 degrees
% b - burgers vector magnitude
% V - poisson ration
% gamma - thickness coefficient
% f_inf - final mismatch strain

clear all;
%CALCULATING FINAL MISMATCH STRAIN
x_inf = input('Please give the final composition x_inf in microns: ');
c_inf = input('Please give constant value ratio of f_inf/x_inf: ');
f_inf = c_inf.*x_inf;

%CALCULATING THE POISSON RATIO
x = input('Please input the composition percentage x for In(x)Ga(1-x)As: ');
% Elesatic stiffness constants. The units here are in GPa
C11_InAs = 83.29;
C11_GaAs = 118.4;
C12_InAs = 45.26;
C12_GaAs = 53.7;
% Calculating the resulting elastic stiffness constants
C11 = x.*C11_InAs + (1-x).*C11_GaAs;
C12 = x.*C12_InAs + (1-x).*C12_GaAs;

%Calculating the poisson ratio
V = C12./(C11+C12);

%CALCULATING THE LATTICE CONSTANT. Dimensions in microns.
a_InAs = 6.0584*10^-4;
a_GaAs = 5.6534*10^-4;

a = x.*a_InAs + (1-x).*a_GaAs;

%CALCULATING THE BURGERS VECTOR
b = a./sqrt(2);

%DECLARING THE ANGLES
alpha = pi./3;
lambda = pi./3;

% CODE BELOW DESCRIBES HOW WE SOLVE FOR hc

A = (1-V.*cos(alpha).*cos(alpha)).*b;
B = (8*pi*abs(f_inf)*(1+V).*cos(lambda));
C = A./B

%gamma = input('Please enter a value for the thickness coefficient in microns: ');

% Put some initial values in for hc_old.
hc_old = input('Please enter a "guessing" starting value for hc in microns: ');
final_result= zeros(150);

% First loop, loops through gamma values and calculates first  hc_new for a
% given hc_old. Second loop, checks the condition of successive hc_new-s.
for i = 1:100
% for gamma = 0.01:0.01:1.5 % We are looping for gamma from 0.01 microns to 1.5 microns
gamma = i/100.0;
hc_new = C*(log(hc_old/b)+1)+ gamma*(1-exp(-hc_old/gamma));

% Checks that successive values of hc_new converge
while abs(hc_new - hc_old)>0.0000001
% Store previously computed value of hc_new(i) in hc_old
hc_old = hc_new;
% Calculate new value for hc_new(i)
hc_new = C*(log(hc_old/b)+1)+ gamma*(1-exp(-hc_old/gamma));
end
final_result(i) = hc_new
end
%Range of gamma
gamma_range = [0.01:0.01:1.5]',

Mark44
Mentor
Your for loop should run from 1 to 150. That will give your gamma values .01, .02, ..., 1.49, 1.50.

You are using matrix arithmetic operations such as .* and ./ in a number of places that aren't needed. The following are examples of this
C11 = x.*C11_InAs + (1-x).*C11_GaAs;
V = C12./(C11+C12);
a = x.*a_InAs + (1-x).*a_GaAs;

b = a./sqrt(2);
alpha = pi./3;
lambda = pi./3;

These are probably not causing any problems, but might be something to think about.

Since I don't have matlab (and have never used it), I am not able to run your script. I don't see anything obviously wrong with it, but I would do the following.

1. Temporarily change the for loop to for i=1:2. You want the loop to run just a couple of times so you can see the values produced by final_result(1) and final_result(2). These are apparently coming out as 0.
2. Take all the final semicolons off the statements in the for loop (including the inner while loop) so that you can see the output.

Alternatively, you can hand-simulate the execution of the for loop (which is likely where the problem lies), by starting with i = 1, and hand calculating hc_new and going through the while loop to see what happens. It should be that after the while loop exits, final_result(1) gets set to a nonzero value.

Hope that helps.

I figured it out for the zero parts. Apperantely MATLAB can create the array itself and it does need this line of code:
final_result = zeros(150)
You don't need to intialize an array of zeros I guess even though I would have thought that you needed to. Now the loop runs fine but it has this problem:

I get output like

for i = 1
final_result =
value 1

for i = 2
final_result =
value 1 value 2

for i = 3
final_result =
value 1 value 2 value 3

.
.
.

for i = 150
final_result =
value 1 value 2 ... value 150

Now for me the only valuable information here is for i = 150 but when i try to access
final_result(150) it will only give me the last result (i.e. just "value 150") and make all the other values, 0.

I'm not quite sure why it's doing that.

final_result(150) it will only give me the last result (i.e. just "value 150") and make all the other values, 0.

I dont understand this line. In array A, when you type A(i), it will return or write value of ith-member of A.

I found that if I do the following I get the right datapoints I need and the correct graph:

%Range of gamma

gamma_range = [0.01:0.01:0.5];

hc_found = [a(1),a(2),a(3),a(4),a(5),a(6),a(7),a(8),a(9),a(10),a(11),a(12),a(13),a(14),a(15),a(16),a(17),a(18),a(19),a(20),a(21),a(22),a(23),a(24),a(25),a(26),a(27),a(28),a(29),a(30),a(31),a(32),a(33),a(34),a(35),a(36),a(37),a(38),a(39),a(40),a(41),a(42),a(43),a(44),a(45),a(46),a(47),a(48),a(49),a(50)]

plot(gamma_range,hc_found)

Oh by the way i replaced 'final_result' by 'a' here just to make the typing easier.

This is a very very crude [:(((] method of doing it, so I was wondering if you can suggest another way to access those values. Testing with my patience it made me change my loop from 1:150 to 1:50 because I didn't want to get 150 datapoints that way.

Any ideas

I dont understand this line. In array A, when you type A(i), it will return or write value of ith-member of A.

Right sorry I didn't explain that really well. I meant if i replace final_result(i) = hc_new; with final_result(150) = hc_new; inside the code.

Otherwise you are right I can access each point individually from the results of the loop. Please look at previous post

Many thanks,
HK

Right sorry I didn't explain that really well. I meant if i replace final_result(i) = hc_new; with final_result(150) = hc_new; inside the code.

A(i) is different from A(150). When created, all values in array are 0 (in default). When you use A(i) inside the loop, in each step 'i', the value of ith-member will be overwritten. But when you use A(150), in all steps 'i', only 150th-member is overwritten. Therefore, the rest members still have initial values (in this case 0).

----
About plot, I use your previous code, data and I have this result:
http://img134.imageshack.us/img134/7483/55034703.jpg [Broken]

Code:
hc_found = final_result;
gamma_range = (0.01:0.01:1.5)';
plot(gamma_range,hc_found)

Last edited by a moderator:
Hahaha and I just finished typing up 150 values. Thank you so very much for your answer though.

Do you know, if I want to do a 3D plot of hc_found, gamma and a different range of x_inf how would i be able to do that. It tells me that one of these has to be a matrix. hc is implicitly dependet on gamma and x_inf from the equation.

Please delete this big graph now. I got the same graph. It just distorts the page a lot.

Thank you,

HK

Code:
hc_found1 =[a(1),a(2),a(3),a(4),a(5),a(6),a(7),a(8),a(9),a(10),a(11),a(12),a(13),a(14),a(15),a(16),a(17),a(18),a(19),a(20)];
hc_found2 =[a(21),a(22),a(23),a(24),a(25),a(26),a(27),a(28),a(29),a(30),a(31),a(32),a(33),a(34),a(35),a(36),a(37),a(38),a(39)];
hc_found3 =[a(40),a(41),a(42),a(43),a(44),a(45),a(46),a(47),a(48),a(49),a(50),a(51),a(52),a(53),a(54),a(55),a(56),a(57),a(58),a(59),a(60)];
hc_found4 =[a(61),a(62),a(63),a(64),a(65),a(66),a(67),a(68),a(69),a(70),a(71),a(72),a(73),a(74),a(75),a(76),a(77),a(78),a(79),a(80)];
hc_found5 =[a(81),a(82),a(83),a(84),a(85),a(86),a(87),a(88),a(89),a(90),a(91),a(92),a(93),a(94),a(95),a(96),a(97),a(98),a(99),a(100)];
hc_found6 =[a(101),a(102),a(103),a(104),a(105),a(106),a(107),a(108),a(109),a(110),a(111),a(112),a(113),a(114),a(115),a(116),a(117),a(118),a(119),a(120)];
hc_found7 =[a(121),a(122),a(123),a(124),a(125),a(126),a(127),a(128),a(129),a(130),a(131),a(132),a(133),a(134),a(135),a(136),a(137),a(138),a(139),a(140)];
hc_found8 =[a(141),a(142),a(143),a(144),a(145),a(146),a(147),a(148),a(149),a(150)];

hc_found = [hc_found1,hc_found2,hc_found3,hc_found4,hc_found5,hc_found6,hc_found7,hc_found8];

i still dont understand why you need to type hc1 = [a(i)...] meanwhile we can do it like this: hc = a.

Mark44
Mentor
i still dont understand why you need to type hc1 = [a(i)...] meanwhile we can do it like this: hc = a.
I agree, with a slight change to hc_found = a. Make sure the hc_found and a arrays are the same size, both with 50 elements or both with 150 elements, or whatever you decide.

Also, I agree completely that you DON'T want to change the line that said final_result(i) to final_result(150). All that does is repeatedly store different values in a single cell of your array, without touching any of the others.

IOW, you shouldn't have to to this:
Hells_Kitchen said:
hc_found = [a(1),a(2),a(3),a(4),a(5),a(6),a(7),a(8),a(9),a(10) ,a(11),a(12),a(13),a(14),a(15),a(16),a(17),a(18),a (19),a(20),a(21),a(22),a(23),a(24),a(25),a(26),a(2 7),a(28),a(29),a(30),a(31),a(32),a(33),a(34),a(35) ,a(36),a(37),a(38),a(39),a(40),a(41),a(42),a(43),a (44),a(45),a(46),a(47),a(48),a(49),a(50)]

And as ApexOfDE already said, you can get a graph by doing this:
Code:
plot(gamma_range,hc_found)
The only thing is that both arrays need to be the same size (same number of elements).

As far as plotting 3D graphs, I don't know. As I already said, I don't have matlab and have never used it. I've been getting a lot of information from this tutorial: http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/getstart.pdf. Chapter 3 is a basic overview of plotting, and might have what you need. If not, I'm sure there is more detailed information online somewhere.

Yeah, I absolutely agree it is definately easier to do hc_found = a and that is what I did at the end. I just wanted to show that that's what happens when you don't know what you're doing. You end up typing 150 times the same thing for something that you just need to type one letter.

Thankfully, now everything is all set. I was able to plot the way that I needed too.

I just wanted to thank the both of you for all your help and contribution.

Regards,
-HK

Mark44
Mentor
Sure, you're welcome.