1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

For loops in Matlab

  1. Oct 31, 2009 #1
    1. The problem statement, all variables and given/known data

    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!!!
     
  2. jcsd
  3. Nov 1, 2009 #2
    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.
     
  4. Nov 1, 2009 #3
    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
     
  5. Nov 1, 2009 #4

    Mark44

    Staff: Mentor

    You want your while loop to look something like this:

    Code (Text):

    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.
     
  6. Nov 1, 2009 #5
    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!
     
  7. Nov 1, 2009 #6

    Mark44

    Staff: 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 (Text):

    % 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
     
     
  8. Nov 2, 2009 #7
    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 (Text):
    % 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: Nov 2, 2009
  9. Nov 2, 2009 #8

    Mark44

    Staff: 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 (Text):

    % 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]',
     
     
  10. Nov 3, 2009 #9
    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: Nov 3, 2009
  11. Nov 3, 2009 #10
    can you give me all constant values and an error msg that you received?
     
  12. Nov 3, 2009 #11

    Mark44

    Staff: Mentor

    Second problem first. Change this line:
    Code (Text):
    gamma = i/150.0
    to this:
    Code (Text):
    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 (Text):
    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.
     
  13. Nov 4, 2009 #12
    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 (Text):
    % 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]',
     
  14. Nov 4, 2009 #13

    Mark44

    Staff: 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.
    3. Run your script.

    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.
     
  15. Nov 4, 2009 #14
    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.
     
  16. Nov 4, 2009 #15
    I dont understand this line. In array A, when you type A(i), it will return or write value of ith-member of A.
     
  17. Nov 4, 2009 #16
    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
     
  18. Nov 4, 2009 #17
    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
     
  19. Nov 4, 2009 #18
    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 (Text):

    hc_found = final_result;
    gamma_range = (0.01:0.01:1.5)';
    plot(gamma_range,hc_found)
     
     
    Last edited by a moderator: May 4, 2017
  20. Nov 4, 2009 #19
    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 (Text):
    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];
     
  21. Nov 4, 2009 #20
    i still dont understand why you need to type hc1 = [a(i)...] meanwhile we can do it like this: hc = a.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: For loops in Matlab
  1. MatLab for loops (Replies: 3)

Loading...