Rational comparison w/ continued fractions

I interrupted some thread about how Wave processed numbers it read. I mentioned using bignums someday. The thread drifted to bignum representations, including "exact reals." One of the exact-real library web sites mentioned continued fractions, which lead me to the HAKMEM paper. You can find out more at <http://en.wikipedia.org/wiki/HACKMEM>. I was thinking of creating a continued fraction class for us, but then I saw a note about how continued fraction comparison is easier than regular fraction comparison. More importantly, c.f. comparison is just list entry checking, no arithmetic operations. Conversion from r.f. to c.f. involves only division and remainders. These facts combine to make a r.f. comparison that doesn't need multiplications, and therefore avoids overflow. Continued fractions have a form like: p0 + q0 / (p1 + q1 / (p2 + q2 / ... )) where all the p's and q's are integers. We usually simplify the representation by factoring out all the q's to 1's: r0 + 1 / (r1 + 1 / (r2 + 1 / ... )) (The p's change values, except for p0, because of the re-factoring.) We can type out these simplified fractions easily with "[r0; r1, r2, ...]". Rational and irrational numbers map to finite- and infinite-length fraction lists, respectively. Irrational numbers have a unique representation; rational numbers are unique to two forms, where the minor form reduces the last number by 1 and appends a 1 to the list. [x0; x1, x2, ..., xn] == [x0; x1, x2, ..., (xn - 1), 1] Continued fractions are typically difficult to manipulate, but two operations are very easy. 1. Reciprocal [0; x1, x2, x3, ...] <-> [x1; x2, x3, ...] 2. Comparison of two values (as represented by their lists) a. Make sure to normalize the fraction 1. Convert away from the trailing-1 minor form (if rational) 2. Remove any interior zeros with [... x, 0, y, ...] <-> [... (x + y) ...] But note that if x == -y, you'll create another zero and you'll have to do another round. 3. Keep the sign consistent, make sure every integer in the series is non-negative or non-positive. (Keeping the previous rule in mind, only the first list entry can be a zero.) I don't know how to correct lists that violate this. I don't think that normal conversion from a numerator & denominator pair will cause these problems; a conversion will create a list that's already normalized. The conversion involves applying Euclid's GCD algorithm, which needs the "%" operator, which is iffy for negative values, so it would be better to take the absolute values, track the signs separately, and flip the result as appropriate. (Lists with these problems could occur if the list is generated from a rule formula.) b. (I'm assuming that you're using absolute values.) If every element of the two numbers' lists are equal, then the numbers are equal. Otherwise stop at the pair of list entries that are different, using infinity as the place-holder if one list is shorter than another. For that list index K, if K mod 2 is the same as the index for the first (i.e. the whole number part) entry's mod-2, then the less/greater-than status of the two entries is the same as the lists' status, else the statuses are reversed. Example 1: 7/6 (i.e. 1+1/6) vs. 1/2 7/6: [1; 6] 1/2: [0; 2] Difference at first entry 1 > 0 with odd# entry; so 7/6 > 1/2 Example 2: 1/4 vs. 1/3 1/4: [0; 4] 1/3: [0; 3] Difference at second entry 4 > 3 with even# entry; so 1/4 < 1/3 Example 3: 47/21: [2; 4, 5] 9/4: [2; 4] Difference at third entry 5 < Inf with odd# entry; so 47/21 < 9/4 Normal decimal fractions have even faster comparisons, but forming enough digits is harder, especially if they repeat. I'll try to come up with an actual improved member function for boost::rational in few days. -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com

I was thinking of creating a continued fraction class for us, but then I saw a note about how continued fraction comparison is easier than regular fraction comparison. More importantly, c.f. comparison is just list entry checking, no arithmetic operations. Conversion from r.f. to c.f. involves only division and remainders. These facts combine to make a r.f. comparison that doesn't need multiplications, and therefore avoids overflow.
My understanding is that continued fractions aren't very useful for anything that's involves actual arithmetic, but they can be used to solve specific problems like the one raised for rational. They're also extremely important for evaluating numeric approximations of various functions, but rather hard to compute unfortunately. Even so the modified Lenz's algorithm would be a useful addition to Boost at some point. John.

On 12/17/05 5:43 AM, "John Maddock" <john@johnmaddock.co.uk> wrote: [SNIP the lack of usefulness of continued fraction math outside of comparing (less v. equal v. greater) rational numbers]
[Continued fractions are] also extremely important for evaluating numeric approximations of various functions, but rather hard to compute unfortunately. Even so the modified Lenz's algorithm would be a useful addition to Boost at some point.
What's this algorithm? Is it related to the Lenz's Law for electromagnetic physics? (That all I found on Google.) -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com

What's this algorithm? Is it related to the Lenz's Law for electromagnetic physics? (That all I found on Google.)
No, the simplest explanation is that its a way of converting a continuous fraction to a real number while avoiding overflow/underflow/devide by zero. For instance given a function F(x,y,z), there is often a continued fraction that expresses the result of the function exactly: we can calculate the constants in the fraction [a1,b1 ... aN,bN] using some well known numerical formula, but then we need to figure out how to convert these into a real-number result. In particular you need to figure out how many terms to evaluate to obtain an accurate result (because the fraction goes on forever, albeit converging: well usually anyway!). You can think of the continued fraction representation as a more powerful version of a series approximation. It's used a lot for things like the incomplete Beta and Gamma functions, Bessel function etc. Getting back to the subject I mis-spelt the name! It's Lentz's algorithm, and there are very few references available, although Numerical Recipies is one source. Anyway, this is probably getting you sidetracked, numerical evaluation of continued fractions isn't really related to the manipulation of rationals, which is where we started :-) John.

In case want to sidetracked ... Numerical Receipes in C++ page 177-179 ISBN 0 521 75033 4 gives a readable-ish description of modified Lentz's method. The original paper is Lentz wj Applied Optics 15, pp 668-671. The now usual method is by Thompson IJ and Barnett AR (1986) Jo computational Physics, vol 64, pp 490-509. Paul -- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB Phone and SMS text +44 1539 561830, Mobile and SMS text +44 7714 330204 mailto: pbristow@hetp.u-net.com http://www.hetp.u-net.com/index.html http://www.hetp.u-net.com/Paul%20A%20Bristow%20info.html | -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of John Maddock | Sent: 19 December 2005 11:14 | To: boost@lists.boost.org | Subject: Re: [boost] What is Lenz's algorithm? (was: Re: | Rationalcomparison w/continued fractions) | | Anyway, this is probably getting you sidetracked, numerical | evaluation of | continued fractions isn't really related to the manipulation | of rationals, | which is where we started :-) | | John. | | _______________________________________________ | Unsubscribe & other changes: | http://lists.boost.org/mailman/listinfo.cgi/boost |

The now usual method is by Thompson IJ and Barnett AR (1986) Jo computational Physics, vol 64, pp 490-509.
That's also given a mostly-incomprehensible numerical recipies treatment, but appears to be specific to the modified Bessel functions? (see page 247). John.
participants (3)
-
Daryle Walker
-
John Maddock
-
Paul A Bristow