Re: Continued Fractions
- To: mathgroup at smc.vnet.net
- Subject: [mg75098] Re: Continued Fractions
- From: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>
- Date: Mon, 16 Apr 2007 20:21:42 -0400 (EDT)
- Organization: The Open University, Milton Keynes, UK
- References: <evvbni$b5u$1@smc.vnet.net>
Wu Weidong wrote: > Hi, > I'm working on a function which takes 2 integer values as input, a and b an= > d outputs a list of integers corresponding to the continued fraction repres= > entation of the rational number a/b. > > My function is as follows: > > build[a_Integer,b_Integer, l_List] :== Module[{r==1,q,temp}, > While[r!==0, > If[a>==b, > q==Quotient[a,b]; > l==Append[l,q]; > r == a-b*q; > a == r, > > temp == a; > a == b; > b == temp; > ]; > ]; > l > ]; > > Essentially, if the fraction given is less than 1, the first number in the = > list is 0. The function then proceeds to find the quotient of the numerator= > and denominator (and add that to the list) and the remainder. If the remai= > nder is less than one, it takes the reciprocal and splits it into a whole-n= > umber part plus another fraction which will be less than 1 and repeat. It s= > tops when the remainder is 0. > > When I tried to run the program, I get the following error messages: > > Set::shape: Lists {} and {2} are not the same shape. > > Set::setraw: Cannot assign to raw object 45. > > Set::shape: Lists {} and {2} are not the same shape. > > Set::setraw: Cannot assign to raw object 45. > > Set::shape: Lists {} and {2} are not the same shape. > > General::stop: Further output of Set::shape > will be suppressed during this calculation. > > Set::setraw: Cannot assign to raw object 45. > > General::stop: Further output of Set::setraw > will be suppressed during this calculation. > > > However, if I just run the While part of the function with a==45, b==16, l= > =={}, r==1 (so I can enter the while loop), I can find the right result (2,= > 1,4,3), so I believe my algorithm should be correct. The errors only appear= > when I put the while loop under the Module structure. > > What is wrong with my program? > > Thank you. > > Regards, > Rayne > Hi Rayne, Contrary to conventional programming language, the list of arguments to a function (a, b, and l, in your case) does declare neither some local variables nor some references to global variables. The list of arguments is a list of patterns, indeed; patterns that are going to be replaced in the right-hand side of the expression before evaluation. Say you ask Mathematica to evaluate build[45, 16, {}]. First, Mathematica replaces any occurrence of the pattern a by 45, b by 16, and l by {}. Only then it enters the Module and evaluates (executes) the While loop. So everything is fine until Mathematica reaches the line "l = Append[l, q]" in your code, which is now {} = Append[{}, 2]. This means that you have lost the name l and it has been replaced by its value (the empty list). (It is like to attempt to evaluate 1 = 2.) You can see what is going on by using, among many others, the *Trace* command, as in build[45, 16, {}]//Trace Now, you will find below a fixed version of the code you posted. Note that I have renamed the original arguments m and n and created two local variables a and b within the Module. Also, it seems that it is not necessary to give the list l as argument: you can just defined and initialize it inside the Module. In[1]:= build[m_Integer, n_Integer] := Module[{a = m, b = n, r = 1, q, temp, lst = {}}, While[r != 0, If[a >= b, q = Quotient[a, b]; lst = Append[lst, q]; r = a - b*q; a = r, temp = a; a = b; b = temp; ]; ]; lst ]; In[2]:= build[45,16] Out[2]= {2,1,4,3} From here, of course, you have to test your code to check if the results are consistent. Regards, Jean-Marc