Matlab pain in the neck

edited February 2009 in Science & Tech
Consider the following sequence:
x<SUB>1</SUB> = 1
x<SUB>i+1</SUB> = x<SUB>i</SUB> - 1 + y * e<SUP>-x<SUB>i</SUB></SUP> (That's e to the power -x<SUB>i</SUB>. Note the minus sign.)

Note that e<SUP>a</SUP> is written as exp(a) in matlab.
For this series, x<SUB>i</SUB> converges on log<SUB>e</SUB>(y). E.g., if y =1, x<SUB>i</SUB> gets closer and closer to 0 as i gets larger. Also, x<SUB>i-1</SUB> and x<SUB>i</SUB> get closer and closer together. Write a function named natlog that takes y as its argument, computes x<SUB>i</SUB> for i starting at 1 and continuing until abs(x<SUB>i-1</SUB>-x<SUB>i</SUB>) < .0001. Natlog should return the final value of x<SUB>i</SUB> as its value.

Here is my function, but it doesn't make sense..i.e. for natlog(5), it gives 1.8384 and it returns values of natlog for negative numbers....I'm not sure if it's supposed to give the same answers as ln(some number), but yeah...can anyone help me fix my program?
function naturallog=natlog(y)
xi=1;
xiplusone=xi-1+y*exp(-xi)
while abs(xi-xiplusone)<.0001&&xi>=1;
naturallog=naturallog+1
end

Comments

  • MyrmidonMyrmidon Baron von Puttenham California Icrontian
    edited February 2009
    The reason you're getting 1.8384 for natlog(5) is because you don't have a semicolon after the third line. That is, the number 1.8384 is the value of xiplusone. A semicolon says 'continue to the next line and DON'T output the result of this line to the screen.' Without your S/C, it's just spitting out xiplusone after one iteration.

    You should also be getting an error because you have no initial value of naturallog. How can naturallog = naturallog + 1 when naturallog never had a value to begin with? For all the program knows, naturallog is actually a string. Now, I'm not too keen on while loops, but I think the reason you don't get an error with natlog(5) is because 5-1.8384 is greater than 0.0001 (therefore the 'while' loop's end criteria are always met and it is being skipped entirely). Like I said, not to keen on while loops, so I might be reading this wrong (and I haven't reinstalled matlab since I formatted, so I can't check).

    Your while loop is pretty shaky as it is. You NEED to change xi or xiplusone inside the loop, or the loop's end criteria will never be met - infinite loop issue. This should always be a criteria when you write a loop.

    Now then:

    1. Your while loop is not consistent with the stated problem. abs(xi-xiplusone) > 0.0001 should be the criteria. I have no idea what that xi >=1 is. Remember: while loops say "IF this criteria is true, RUN my loop. Then check back with me!" Therefore, IF abs(xi-xiplusone) < 0.0001, your loop will run, and mine will stop. IF abs(xi-xiplusone) > 0.0001, your loop will stop and mine will run.

    2. To make matlab work properly, I think you actually need the value 'xiplusone' to be 'naturallog.' The way you've set up the function, it's going to return whatever is in the 'naturallog' variable as its 'answer.' According to your sequence, the 'answer' is supposed to be the last iteration of xi. Therefore naturallog needs to be the final iteration of xiplusone.

    3. Move the while loop one line up. Add another line before the while loop that says 'naturallog = xiplusone' and another after that that says 'xi = xiplusone.' Now make your while loop evaluate abs(xi-naturallog).

    That should be:

    function naturallog=natlog(y)
    xi=1;
    naturallog = 10000; //this junk value ensures the loop will run at least once
    while abs(xi-naturallog)>.0001
    xiplusone=xi-1+y*exp(-xi); //This calculates xiplusone
    naturallog = xiplusone; //this hides the value 'xiplusone' in 'naturallog'
    xi = xiplusone; //This sets the stage for the next loop to calculate xiplustwo.
    end

    end

    This is all off the top of my head, so someone correct me if I'm wrong.
  • edited February 2009
    I tried your function and, i.e., it gives natlog(5)=1.8394, but thanks for the advice anyways...I'll keep working at it....I might be able to work it out from yours, I'll let you know.

    Myrmidon wrote:
    The reason you're getting 1.8384 for natlog(5) is because you don't have a semicolon after the third line. That is, the number 1.8384 is the value of xiplusone. A semicolon says 'continue to the next line and DON'T output the result of this line to the screen.' Without your S/C, it's just spitting out xiplusone after one iteration.

    You should also be getting an error because you have no initial value of naturallog. How can naturallog = naturallog + 1 when naturallog never had a value to begin with? For all the program knows, naturallog is actually a string. Now, I'm not too keen on while loops, but I think the reason you don't get an error with natlog(5) is because 5-1.8384 is greater than 0.0001 (therefore the 'while' loop's end criteria are always met and it is being skipped entirely). Like I said, not to keen on while loops, so I might be reading this wrong (and I haven't reinstalled matlab since I formatted, so I can't check).

    Your while loop is pretty shaky as it is. You NEED to change xi or xiplusone inside the loop, or the loop's end criteria will never be met - infinite loop issue. This should always be a criteria when you write a loop.

    Now then:

    1. Your while loop is not consistent with the stated problem. abs(xi-xiplusone) > 0.0001 should be the criteria. I have no idea what that xi >=1 is. Remember: while loops say "IF this criteria is true, RUN my loop. Then check back with me!" Therefore, IF abs(xi-xiplusone) < 0.0001, your loop will run, and mine will stop. IF abs(xi-xiplusone) > 0.0001, your loop will stop and mine will run.

    2. To make matlab work properly, I think you actually need the value 'xiplusone' to be 'naturallog.' The way you've set up the function, it's going to return whatever is in the 'naturallog' variable as its 'answer.' According to your sequence, the 'answer' is supposed to be the last iteration of xi. Therefore naturallog needs to be the final iteration of xiplusone.

    3. Move the while loop one line up. Add another line before the while loop that says 'naturallog = xiplusone' and another after that that says 'xi = xiplusone.' Now make your while loop evaluate abs(xi-naturallog).

    That should be:

    function naturallog=natlog(y)
    xi=1;
    naturallog = 10000; //this junk value ensures the loop will run at least once
    while abs(xi-naturallog)>.0001
    xiplusone=xi-1+y*exp(-xi); //This calculates xiplusone
    naturallog = xiplusone; //this hides the value 'xiplusone' in 'naturallog'
    xi = xiplusone; //This sets the stage for the next loop to calculate xiplustwo.
    end

    end

    This is all off the top of my head, so someone correct me if I'm wrong.
  • MyrmidonMyrmidon Baron von Puttenham California Icrontian
    edited February 2009
    Whoop, yeah, I screwed it up. The reason it didn't work is because xi - naturallog = 0, since both xi and naturallog are set to xiplusone before evaluating the next while loop. Therefore the loop only runs once.

    Try this.

    function naturallog=natlog(y)
    xi=1;
    test = 1;
    naturallog=xi-1+y*exp(-xi); //This calculates xiplusone the first time
    while abs(test-naturallog)>.0001
    test = naturallog; //this will store x(2,3,4... n) for the next while loop
    naturallog=xi-1+y*exp(-xi); //This calculates x(3,4,5... n+1) for the next while loop
    xi = naturallog; //This stores x(3,4,5...n+1) for while loop calculations after THAT.

    end

    end


    Let me say this clearly one more time: the reason natlog is giving back 1.8384 is because that's the FIRST ITERATION OF xiplusone=xi-1+y*exp(-xi). If you do natlog(5) and get 1.8384, it means the program is only running that line ONCE. So look in your code and say 'why isn't it doing it twice?'

    I would suggest that if you're not too good at loops, try using For/Next loops. Whiles just suck. :)
  • edited February 2009
    Hmm...it's still giving natlog(5) as 1.8394, natlog(2) as .7358....I can't figure out how to fix this at all, I keep trying to toy with it, and it won't give appropriate answers. Sigh...if I want natlogs I will use my calculator lol.....any suggestions? And thanks by the way for trying.


    Myrmidon wrote:
    Whoop, yeah, I screwed it up. The reason it didn't work is because xi - naturallog = 0, since both xi and naturallog are set to xiplusone before evaluating the next while loop. Therefore the loop only runs once.

    Try this.

    function naturallog=natlog(y)
    xi=1;
    test = 1;
    naturallog=xi-1+y*exp(-xi); //This calculates xiplusone the first time
    while abs(test-naturallog)>.0001
    test = naturallog; //this will store x(2,3,4... n) for the next while loop
    naturallog=xi-1+y*exp(-xi); //This calculates x(3,4,5... n+1) for the next while loop
    xi = naturallog; //This stores x(3,4,5...n+1) for while loop calculations after THAT.

    end

    end


    Let me say this clearly one more time: the reason natlog is giving back 1.8384 is because that's the FIRST ITERATION OF xiplusone=xi-1+y*exp(-xi). If you do natlog(5) and get 1.8384, it means the program is only running that line ONCE. So look in your code and say 'why isn't it doing it twice?'

    I would suggest that if you're not too good at loops, try using For/Next loops. Whiles just suck. :)
  • MyrmidonMyrmidon Baron von Puttenham California Icrontian
    edited February 2009
    The problem is I'm not checking my work, just posting what I think of off the bat. Sorry.

    In this case... the first iteration of the while loop doesn't change naturallog, and therefore doesn't change xi. Give me a half hour and I'll be back with something that works for sure.

    And THIS time I'll check it for reals. Promise. :)
  • MyrmidonMyrmidon Baron von Puttenham California Icrontian
    edited February 2009
    function naturallog=natlog(y)
    xi=1;
    test = 1;
    naturallog=xi-1+y*exp(-xi); //Computes first iteration of naturallog
    xi = naturallog; //sets xi to x2
    while abs(test-naturallog)>.0001
    test = naturallog; //this will store xi for the next while loop testing
    naturallog=xi-1+y*exp(-xi); //This calculates x(i+1) for the next while loop
    xi = naturallog; //This stores x(i+1) for further while loop calculations

    end

    end

    Just missed a line last time, I forgot to set xi for the while loop. Sorry for the two wrong-ies. I've tested an equivalent function in Turbopascal - the only compiler I have at my computer right now (don't ask). It works in TP.

    Two stupid mistakes in a row. If this function doesn't work, I'm taking the title 'sloppiest programmer ever.'

    More importantly, do you understand what I'm doing in the program? It's way more important to understand that than just get it to work right.
  • edited February 2009
    Ok, it certainly works now, thank you. I just have one thing I don't quite understand. My professor never uses a "test" and he never mentioned the use of them as you have there. Is it possible this will work without the "test"? Thank you again.
    Myrmidon wrote:
    function naturallog=natlog(y)
    xi=1;
    test = 1;
    naturallog=xi-1+y*exp(-xi); //Computes first iteration of naturallog
    xi = naturallog; //sets xi to x2
    while abs(test-naturallog)>.0001
    test = naturallog; //this will store xi for the next while loop testing
    naturallog=xi-1+y*exp(-xi); //This calculates x(i+1) for the next while loop
    xi = naturallog; //This stores x(i+1) for further while loop calculations

    end

    end

    Just missed a line last time, I forgot to set xi for the while loop. Sorry for the two wrong-ies. I've tested an equivalent function in Turbopascal - the only compiler I have at my computer right now (don't ask). It works in TP.

    Two stupid mistakes in a row. If this function doesn't work, I'm taking the title 'sloppiest programmer ever.'

    More importantly, do you understand what I'm doing in the program? It's way more important to understand that than just get it to work right.
  • MyrmidonMyrmidon Baron von Puttenham California Icrontian
    edited February 2009
    Yes, I can. "Test" is a dummy third variable that I use because I like to think with variables and because I'm an inelegant programmer. But now that you've asked me to, I think I have a much more elegant solution.

    HOWEVER - I didn't realize you were doing this for a class. Since I've already given you the code, there's no sense withholding the code and 'pushing' you to get it yourself, so I'll post my more elegant solution... but I challenge you to find your own.

    function naturallog=natlog(y)
    xi=1;
    naturallog=xi-1+y*exp(-xi);
    while abs(test-naturallog)>.0001
    xi = naturallog;
    naturallog=naturallog-1+y*exp(-naturallog);

    end

    end

    I've removed the comments. If you want, you can explain what I've done so that I don't feel like I've helped someone cheat. :P
  • edited February 2009
    I assume where you have abs(test-naturallog) you meant (xi-naturallog)


    I can put comments if it makes you feel better:

    function naturallog=natlog(y).......names the function lol
    xi=1;..............summary variable set
    naturallog=xi-1+y*exp(-xi);.............first computation of ln
    while abs(xi-naturallog)>.0001...........clearly our while
    xi = naturallog;...................sets xi to naturallog so we can continue the computation below
    naturallog=naturallog-1+y*exp(-naturallog);........computes natlog for xi+1

    end

    end
    Myrmidon wrote:
    Yes, I can. "Test" is a dummy third variable that I use because I like to think with variables and because I'm an inelegant programmer. But now that you've asked me to, I think I have a much more elegant solution.

    HOWEVER - I didn't realize you were doing this for a class. Since I've already given you the code, there's no sense withholding the code and 'pushing' you to get it yourself, so I'll post my more elegant solution... but I challenge you to find your own.



    I've removed the comments. If you want, you can explain what I've done so that I don't feel like I've helped someone cheat. :P
  • MyrmidonMyrmidon Baron von Puttenham California Icrontian
    edited February 2009
    I assume where you have abs(test-naturallog) you meant (xi-naturallog)

    see? There's me making retarded mistakes again. :)
Sign In or Register to comment.