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!

MATLAB loops - hard question

  1. Jul 7, 2011 #1
    1. The problem statement, all variables and given/known data

    One interesting property of a Fibonacci sequence is that the ratio of the values of adjacent members of the sequence approach a number called “the golden ratio” or PHI. Create a program that accepts the first two numbers of a Fibonacci sequence as a user input and then calculates additional values in the sequence until the ratio of adjacent values converges to within 0.001. You can do this in a WHILE loop by comparing the ratio of element k to element k-1 and the ratio of element k-1 to element k-2. If you call your sequence x, then the code for the WHILE statement is

    while abs(x(k)/x(k-1) – x(k-1)/x(k-2))>0.001

    2. Relevant equations



    3. The attempt at a solution
    I thought this would work fine but sense MATLAB can only compute with so many digits I'm at a lost as to what to do

    Code (Text):
    a=input('Please enter the first two numbers of the Fibonacci sequence in "[# #]" form.');
    x=[a ones(realmax-2)];
    k=[3:1:realmax-1];
    while abs(x(k)/x(k-1)-x(k-1)/x(k-2))>.001
        x(k)=x(k-2).*x(k-1);
    end
    c(find(c>1));
    I'm at a lost as how to proceeds further at even coming up with some way to solve this problem besides some general ideas and a program that work like mine above. Thanks for any help you can provide!

    maybe the issue is that I don't know enough about the golden ratio and the math behind it and stuff or is it that I don't know enough about MATLAB probably a combination of the two lol
     
  2. jcsd
  3. Jul 7, 2011 #2
    Traditionally, A Fibonacci Sequence is this:

    0 1 1 2 3 5 8 13 21 .....

    So using the simple algorithm of, when given two numbers, the next number is the addition of the previous two. It sounds like your problem is asking for user input of two Fibonacci numbers. I'm a little confused at this part as to whether the question is asking for the first two numbers of the Fibonacci sequence, 0 and 1, or any two Fibonacci numbers to start with. If it is the latter, there are methods to check whether a number is a FN or not. I think it's the former option, though.

    That being said, what exactly are your x and k vectors doing? What exactly are you using the realmax function for? I suggest you think and post a pseudo-code so we can see where exactly you're trying to go with your algorithm.

    Note - All you need to do is calculate two things - the ratio and the next FN - and save four things - the current ratio and number and the previous of those two. You can create a separate variable to count how many additional integers have been used since the beginning.
     
  4. Jul 7, 2011 #3

    uart

    User Avatar
    Science Advisor



    I can't even begin to image what your thought processes are to write that code GreenPrint. Realmax is about 1E308 on my computer. You're trying to create two arrays bigger than 10^308, that's crazy mad. :)

    Let me just get you started with some simple code to generate elements <1000 of the Fib Seq.

    Code (Text):

    a=0;
    b=1;
    while b<1000
       t=a+b;
       a=b;
       b=t
    end
     
    Start with this and try to familiarize yourself with the while statement and how it works.
     
    Last edited: Jul 7, 2011
  5. Jul 7, 2011 #4

    CEL

    User Avatar

    the main error is in the statement:
    x(k)=x(k-2).*x(k-1);
    it should be:
    x(k)=x(k-2).+ x(k-1);
     
  6. Jul 7, 2011 #5
    Ok well here's were I'm at. I'll explain my logic to. If this program was executed the right way I believe this would work but for some reason it's not. I don't like the statement that follows the while command. Sorry if my code before was kind of crazy. After rethinking of the logic behind it I recreated a code that I believed should have worked and I explain my logic in it. My book does a god awful job explaining for and while loops so I wouldn't be surprised if my work below is not the standard way of doing things.

    Code (Text):
    a=input('Please enter the first two numbers of the Fibonacci sequence in "[# #]" form.');
    x=[a ones(1,98)];
    d=[1:100];
    z=3;
    while abs(x(z)/x(z-1)-x(z-1)/x(z-2))>0.001
        x(d(z))=x(d(z)-2)+x(d(z)-1)
        z=z+1
    end
    g=[a x(find(x>1))];
    So first off I prompted the user of the program to enter the first two numbers of the sequence and called it a. I then set up a vector x were the first two values were a and than a whole bunch of ones. I had originally used realmax because I didn't know how many ones that were needed, but a very large number that will ensure enough numbers are allowed for the sequence to occur should be fine. So I'm just going with 100, I don't know if this will be enough or not. Hopefully the ratios will converge after 100 numbers in the sequence. Second of all I defined a vector d that I will use in the loop to help create the sequence. This vector should contain enough values to ensure that the sequence can be reached just like x and should be of the same size. I defined a value z as 3 which I will use as a counting variable sort of thing in my loop.

    Within the loop
    x(d(z))=x(d(z)-2)+x(d(z)-1)
    This just simply redefines all the values in x so that they form the sequence. x(d(z)) when z=3 is x(d(3)) which is x(3) and is redefining the third value in x which is currently 1 to be a appropriate number to fit the sequence... x(d(z)-2)+x(d(z)-1) is going to simply evaluate the sum of the two preceding numbers. When z is 3, x(d(3)-2)+x(d(z)-1)=x(d(3)-2)+x(d(3)-1)=x(3-2)+x(3-1)=x(1)+x(2)

    hence
    x(d(z))=x(d(z)-2)+x(d(z)-1)
    should create the sequence if I increase z by 1 each time the loop is executed before the statement after the while command works, hence why added z=z+1 before the end command were it just adds one to the previous z value.

    g=[a x(find(x>1))] simply defines a vector g that would contain all the values in the vector x that were greater than 1 but excluding the first two values, just in case all the 1s that I used as place holders weren't used.

    So for some reason this code doesn't produce what I expected. I was expecting z to get redefined a whole bunch of times but for some reason it doesn't. I honestly think the statement after the while command is flawed because my code seems to jump out of the loop after one time through. I thought maybe could use a different statement something like
    x(z)/(x(z)-1)>= (1+5^(1/2))/2-.001 && x(z)/(x(z)-1)<= (1+5^(1/2))/2+.001
    but that's not what the book seems to want
     
    Last edited: Jul 7, 2011
  7. Jul 7, 2011 #6
    I think you need to take some intermediate steps.

    First you need to create a program that simply generates and outputs in a fashion that you and we can see, the Fibonacci sequence. It may be worth your time to see if you can spit out the appropriate numbers inside or outside the while loop.

    Remember, the input to the program are the numbers 0 and 1.

    After that then you can add the relatively simple step of seeing if it converges and you can attack the problem in bulk as you have above. Always program in self-made steps - it makes debugging so much easier since you know what works and what may not.
     
  8. Jul 7, 2011 #7
    Alright thanks for your help.

    I really have no idea how to further proceed. And ya I agree I got to take off the ":" from g=[a x(find(x>1))]; so that way we can both see it. And I actually think it can be any two numbers based off the wording of the problem. The problem before it even said "Prompt the user to enter the first two numbers in a Fibonacci sequence and the total number of elements requested for the sequence. That problem had me doing so with the for loop command the problem after it was the same thing accept using the while loop command. I was able to solve these problems but not this one were the number of elements needed is not known. I really have no clue were to go from here.
     
  9. Jul 7, 2011 #8
    Like I'm interpreting converge as the ratio of one value in the sequence and the value before it and the ratio of the two numbers before that are equal to each other right? So i don't really understand the while statement and why it's >.001 shouldn't it be less than?
     
    Last edited: Jul 7, 2011
  10. Jul 8, 2011 #9

    uart

    User Avatar
    Science Advisor

    Don't you read my posts? I already gave you code to generate the elements of the Fibonacci sequence back in reply #3. Take a good look at it and make sure you understand how it works.

    You DONT need to use vectors here. It's inefficient, especially given that you don't even know what size is required beforehand. Just do it sequentially (term by term) as I have shown you in post #3 above.

    Now all you need to do is to extend this so as to save the previous value of the ratio (from the previous iteration of the loop) and compare with the ratio found in the current iteration. Let me repeat NO VECTORS ARE REQUIRED.
     
  11. Jul 8, 2011 #10

    uart

    User Avatar
    Science Advisor

    Well for one thing, if you input the correct two numbers [0,1] to start the fibanacci sequence then you are going to get divide by zero.

    For a second thing, if you then decide to start at the second term of the sequence and enter [1,1] then you are going to get 1/1 - 1/1 = 0, so yes that will terminate the loop straight away.

    For a third thing, you are using x(3) ( and in general x(z) ) before that terms has even been calculated!.

    For a fourth thing, in your program d(z) = z (always), and so could simply be replaced by z. You definite;y want to try NOT to obfuscate your code like that.
     
  12. Jul 8, 2011 #11
    Sorry if I sort of did it in a roundabout way. I'm trying to teach myself. Sorry for any frustration I caused you. I do actually think it my code may work if I don't enter numbers that terminate right away. If I change the last command line and get rid of the "a" sense it's not needed than I believe it works. For example

    Code (Text):
    a=input('Please enter the first two numbers of the Fibonacci sequence in "[# #]" form.');
    x=[a ones(1,100000)];
    d=[1:100002];
    z=3;
    while abs(x(z)/x(z-1)-x(z-1)/x(z-2))>0.001
        x(d(z))=x(d(z)-2)+x(d(z)-1);
        z=z+1;
    end
    g=x(find(x>1));
    try it yourself, enter two numbers that wont make it terminate right away, I don't think there's anyway of entering those and doing what the book wants me to do sense they said do use that conditional statement, so use like enter "[3 7]" when prompted then view the defined variable g and I believe that would be a correct answer, as long as i don't enter [0 1] or [1 1]?

    I also edited my code slightly and made the vectors x and d longer sense 100 wasn't enough, I think the numbers I used will do it now
     
  13. Jul 8, 2011 #12

    uart

    User Avatar
    Science Advisor

    - You're still using x(z) (in the condition statement) before it is calculated.

    - You're still using d(z) despite the fact that d(z) is simply z.

    - You don't need to do it as a vector, you should do it term by term. It only actually needs about ten iterations.

    BTW. Did you look at my code in reply #3 yet? To see how it is done without using vectors.
     
  14. Jul 8, 2011 #13
    Ya, I did. It's three in the morning right now so I'm going to call it a night and get back on this problem in the morning. Thanks for your help! Hopefully after a nights sleep my head will be clear and I'll be able to get a correct code.

    I'm back at it... lets see...
     
    Last edited: Jul 8, 2011
  15. Jul 8, 2011 #14
    your code works

    Code (Text):
    a=0;
    b=1;
    while b<1000
       t=a+b;
       a=b;
       b=t
    end
    and creates a sequence. but I'm lost as how to proceed if you take into consideration that the first two numbers can be anything and that you have to prompt the user to input these two values, and I don't know how to get around the while statement

    Code (Text):
    disp('Please enter the first two numbers of the Fibonacci sequence.  Do not enter 0 & 1 or 1 & 1.');
    a=input('Please enter the first number');
    b=input('Please enter the second number');
    k=0;
    while abs(x(k)/x(k-1)-x(k-1)/x(k-2))>.001
       x=a+b;
       a=b;
       b=x
       k=k+1;
    end
    just simply wont work... you have to define k before you enter the loop? Or is there some other way? you can't let k=0 nor k=1 or in the while statement you will get things like x(-2) x(-1) x(0) which don't make any sense, I'm seeing the only option is setting k equal to 3 before entering the loop as this is the smallest value you can define k to be before the loop without getting nonsense stuff like x(0)... but even then if you set k=3 you leave x(3) undefined so you have to define it some how before entering the loop

    like i fully understand your code and it makes sense and produce a sequence... I'm just lost as to how to make a code that uses the while statement that they want us to use for the reasons above, and I don't see how you can not use a vector when you have to define the first two values, I guess technically 3, because of the while statement which requires that at least the first 3 be defined some how...

    like i can create a sequence and probably a correct code just not with that while statement that the book wants me to use...
     
  16. Jul 8, 2011 #15

    uart

    User Avatar
    Science Advisor

    - You don't need the "x" vector anymore.

    - You have to initialize things before you use them

    Try the following code. All I've left for you to do is to figure out suitable initial values for Ratio and LastRatio and to work out how to update them within the loop.

    Code (Text):

    a=input('Please enter the first number');
    b=input('Please enter the second number');
    LastRatio = ???;
    Ratio = ???;
    while abs(Ratio - LastRatio)>0.001
       x=a+b;
       a=b;
       b=x;
       LastRatio = ???;
       Ratio = ???;
    end
    Hints.
    1. "Ratio" is the ratio of b/a after the new term is calculated
    2. "LastRatio" is the previous value of Ratio
    3. With suitable initial values you should be able to start the sequence at any valid point, including 0,1 and 1,1

    BTW. Note that "x" is a scalar, not a vector, in this code!
     
    Last edited: Jul 8, 2011
  17. Jul 8, 2011 #16
    Alright well I believe that if I'm interpreted this correctly, that we avoided creating a vector by using "Ratio" and "LastRatio"

    hence the while statement
    abs(x(k)/x(k-1) - x(k-1)/x(k-2))>.001
    became
    abs(Ratio - LastRatio)>.001
    hence I conclude
    x(k)/x(k-1)=Ratio
    and
    x(k-1)/x(k-2)=LastRatio
    to make sense of this I set k=3
    x(3)/x(3-1)=x(3)/x(2)=Ratio
    x(3-1)/x(3-2)=x(2)/x(1)=LastRatio

    So I thought of the first three numbers in the sequence as being...
    a+b+x

    I then concluded that x(3) was just the new number currently undefined, to be defined in the loop, in this case, x, and sense I have to define it before entering the loop I can't use x, so I have to use a+b... and x(2) is just simply b... hence the ratio between the number defined in the loop and the one preceding it would be x/b = (a+b)/b = a/b+1

    the last ratio would just be b/a
    hence before the loop

    LastRatio=b/a;
    Ratio=a/b+1;

    than while in the loop
    x gets defined as a+b
    the new a gets defined as the old b
    the new b gets defined as x

    hence
    LastRatio=b/a;x/b
    Ratio=a/b+1=b/x+1

    but this doesn't seem to work =(
    so I just used this code, which I thought worked but apparently doesn't
    Code (Text):
    disp('Please enter the first two numbers of the Fibonacci sequence.  Do not enter 0 & 1 or 1 & 1.');
    a=input('Please enter the first number');
    b=input('Please enter the second number');
    LastRatio=b/a;
    Ratio=a/b+1;
    while abs(Ratio - LastRatio)>0.001
       x=a+b
       a=b;
       b=x;
       LastRatio=b/a;
       Ratio=a/b+1;
    end
    when i input the first two numbers as 1 and 2 the last three numbers that I get are 55, 34, and 21
    but |55/34 - 34/21|>.001
    shouldn't it have gone through the loop another time and produced 89 than the loop should of been terminated because than the while statement is no longer satisfied
     
  18. Jul 8, 2011 #17
    I guess I could just do this
    Code (Text):
    disp('Please enter the first two numbers of the Fibonacci sequence.  Do not enter 0 & 1 or 1 & 1.');
    a=input('Please enter the first number');
    b=input('Please enter the second number');
    LastRatio=b/a;
    Ratio=a/b+1;
    while abs(Ratio - LastRatio)>0.001
       x=a+b
       a=b;
       b=x;
       LastRatio=b/a;
       Ratio=a/b+1;
    end
    x=b+a
    this will work every single time as long as 0&1 and 1&1 aren't entered ^_^
    I just thought it was improper not to store an answer like this not in a vector so that way you don't produce answers like

    Code (Text):
    x =

         3


    x =

         5


    x =

         8


    x =

        13


    x =

        21


    x =

        34


    x =

        55


    x =

        89
    but i don't think there's anyway to store it as a vector
    like
    Code (Text):
    x =

         3     5     8    13    21    34    55    89
     
  19. Jul 8, 2011 #18
    I think this is much more delicious try using this program ^_^
    Code (Text):
    disp('Please enter the first two numbers of the Fibonacci sequence.  Do not enter 0 & 1 or 1 & 1.');
    a=input('Please enter the first number');
    b=input('Please enter the second number');
    LastRatio=b/a;
    Ratio=a/b+1;
    x(1)=a;
    x(2)=b;
    k=3;
    while abs(Ratio - LastRatio)>0.001
       x(k)=a+b;
       a=b;
       b=x(length(x));
       LastRatio=b/a;
       Ratio=a/b+1;
       k=k+1;
    end
    x(k)=b+a
     
  20. Jul 9, 2011 #19

    uart

    User Avatar
    Science Advisor

    I was thinking more of something like the following

    Code (Text):

    a=input('Please enter the first number');
    b=input('Please enter the second number');
    LastRatio = 0;
    Ratio = 0.5;
    while abs(Ratio - LastRatio)>0.001
       nextb=a+b;
       a=b;
       b=nextb
       LastRatio = Ratio;
       Ratio = b/a;
    end
    % show results
    Ratio - LastRatio
    Ratio
     
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: MATLAB loops - hard question
  1. For loops in Matlab (Replies: 22)

  2. MatLab for loops (Replies: 3)

Loading...