[Python-Dev] Re: PEP239 (Rational Numbers) Reference Implementation
and new issues
M.-A. Lemburg
mal@lemburg.com
Fri, 04 Oct 2002 19:04:48 +0200
Tim Peters wrote:
> [Fran=E7ois Pinard]
>=20
>>...
>>Interesting, I'll save it. I use continued fraction expansion to get
>>the "best" rational fitting a float within a tolerance, and wonder how
>>Farey will be similar/different. Tim will surely tell us, out of his
>>head! :-)
>=20
>=20
> Your wish is granted <wink>: Moshe Zadka's prototype implementation of
> rationals is still sitting in Python CVS nondist/sandox/rational/. Its
> _trim function is one I worked on with him, and uses c.f. expansion to =
find
> "the best" rational approximating a given rational, among all rationals=
with
> denominator no larger than argument max_d. The Farey method is almost
> identical, except potentially much slower. It's almost what "the usual=
"
> continued fraction algorithm would do if you couldn't use integer divis=
ion
> to do a whole bunch of steps in one gulp; e.g., whenever the c.f. expan=
sion
> gets a partial quotient of N, the Farey method does N distinct steps.=20
But isn't division much more costly than addition and multiplication
if you have long integers to deal with ? (I can't tell, because the
works are done by GMP in mxNumber)
> About
> "almost identical": c.f. expansion produces a sequence of rationals
> alternately smaller and larger than the target, each one (much) closer =
than
> the last. The Farey method also looks at rationals "between" those; _t=
rim
> does too, but only at the endpoint, when max_d is between the denominat=
ors
> of two successive c.f. convergents.
>=20
> Moshe's package also has an _approximate function, to find "the smalles=
t"
> rational within a given absolute distance of an input rational; that's
> probably closest to what you're doing now. _trim answers questions lik=
e
> "what's the best approximation to pi with denominator no greater than 6=
?".
> Neither of the adjacent convergents 3/1 and 22/7 is the correct answer =
to
> that; 19/6 is correct. Note that the c.f. expansion gets 22/7 because =
the
> previous two convergents were 1/0 and 3/1, the next partial quotient is=
7,
> and then the next convergent is
>=20
> 1 + 3*7 22
> ------- =3D --
> 0 + 1*7 7
>=20
> If the partial quotient *had* been 6, it would have given 19/6 instead.
> That's what the tail end of _trim deduces.
>=20
> The Farey method does this one step at a time, going from (and skipping=
to
> then end of process)
>=20
> 1/0 3/1
>=20
> as bounds to
>=20
> 3/1 4/1
>=20
> and then
>=20
> 3/1 7/2
>=20
> and then
>=20
> 3/1 10/3
>=20
> and then
>=20
> 3/1 13/4
>=20
> and then
>=20
> 3/1 16/5
>=20
> and then, finally
>=20
> 3/1 19/6
>=20
> Especially when coded in Python, it's much more efficient to deduce thi=
s in
> one gulp (via exploiting division).
How useful are .trim() and .approximate() in practice ? If they
are, then I could put them on the TODO list for mxNumber.
--=20
Marc-Andre Lemburg
CEO eGenix.com Software GmbH
_______________________________________________________________________
eGenix.com -- Makers of the Python mx Extensions: mxDateTime,mxODBC,...
Python Consulting: http://www.egenix.com/
Python Software: http://www.egenix.com/files/python/