On Wed, 3 Jan 2007, Dick Moores wrote: > Be that as it may, farey() is an amazing program.
Not to beat this subject to death, but the comment at the bottom of http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52317 about continued fractions piqued my interest. I'm no mathematician, but I encountered continued fractions a long time ago and was fascinated by them. So I read the URL pointed to, http://mathworld.wolfram.com/ContinuedFraction.html , and came up with the following: ##################################################### def cf(x, tol=0.0001, Trace=False): """ Calculate rational approximation of x to within tolerance of tol; returns a tuple consisting of numerator and denominator p/q Trace=True causes iterated results to be shown """ a, r, p, q = [], [], [], [] Done = False n = 0 if Trace: print "x:%f tol:%f" % (x, tol) while not Done: a.append(None) r.append(None) p.append(None) q.append(None) if n == 0: r[n] = x else: r[n] = 1/(r[n-1]-a[n-1]) a[n] = int(r[n]) if n == 0: p[n] = a[0] q[n] = 1 elif n ==1: p[n] = a[n]*p[n-1] + 1 q[n] = a[n] else: p[n] = a[n]*p[n-1] + p[n-2] q[n] = a[n]*q[n-1] + q[n-2] if Trace: print "n:%d a:%d p:%d q:%d approx:%f" % \ (n, a[n], p[n], q[n], float(p[n])/q[n]) if abs(float(p[n])/q[n] - x) < tol: Done = True num = p[n]; denom = q[n] n += 1 return (num, denom) ##################################################### Here's a result for pi: >>> print cf(3.14159265357989,0.0000001, Trace=True) x:3.141593 tol:0.000000 n:0 a:3 p:3 q:1 approx:3.000000 n:1 a:7 p:22 q:7 approx:3.142857 n:2 a:15 p:333 q:106 approx:3.141509 n:3 a:1 p:355 q:113 approx:3.141593 n:4 a:292 p:103993 q:33102 approx:3.141593 (103993, 33102) i.e., the first 5 approximations it came up with were 3/1, 22/7, 333/106, 355/113 and a whopping 103993/33102. For the 0.36 example you used earlier: >>> print cf(0.36, .01, Trace= True) x:0.360000 tol:0.010000 n:0 a:0 p:0 q:1 approx:0.000000 n:1 a:2 p:1 q:2 approx:0.500000 n:2 a:1 p:1 q:3 approx:0.333333 n:3 a:3 p:4 q:11 approx:0.363636 (4, 11) >>> it went right from 1/3 to 4/11 (0.363636), skipping the 3/8 (0.375) option from the farey series. But this continued fraction algorithm is ill-suited to answer the question "what's the closest fraction with a denominator < N", because it doesn't try to find that, it jumps further ahead with each iteration. Anyway, I thought you might find it interesting based on our discussion. (Yeah, I know, I didn't choose the formats well on those print statements.) _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor