home *** CD-ROM | disk | FTP | other *** search
- (* Copyright 1988, Wolfram Research, Inc. *)
-
- (*:Version: Mathematica 2.0 *)
-
- (*:Name: NumberTheory`ContinuedFractions` *)
-
- (*:Author:
- *)
-
- (*:History:
- Modified Mar. 92 by John M. Novak:
- allow rational numbers
- fix behavior when partial fraction is finite, less than
- order requested.
- Modified May 92 by John M. Novak:
- allow non-rational non-floating point numbers (guesses precision)
- force machine numbers to bignums (machine precision) to reduce
- or eliminate roundoff error (with suggestions from J. Keiper).
- *)
-
- (*:Keywords:
- number theory, continued fractions
- *)
-
- (*:Requirements: none. *)
-
- (*:Discussion:
- ContinuedFraction[x,n] generates the first n quantities in the
- continued fraction expansion for the number x. The result is
- expressed as the object ContinuedFractionForm[ list ].
- All numbers are forced to bignums, minimizing roundoff error
- problems. Note that continued fraction may have order less
- than n, if sequence terminates before n is reached.
- If non-rational non-floating point number is given, the
- routine tries to guess the precision needed to evaluate
- the number to get a continued fraction of the correct
- order. From Jerry Keiper:
- "It turns out that each term in a continued fraction expansion
- requires an expected 0.429017 decimal digits (i.e.
- Log[10, Kinchin], cf Ilan Vardi's book, p163). Thus a
- comfortable overestimate might be to start with one decimal
- digit for every two continued fraction coefficients requested."
- Normal[ ContinuedFractionForm[ list ] ] returns a number
- very close to the original x given.
- *)
-
- BeginPackage["NumberTheory`ContinuedFractions`"]
-
- ContinuedFraction::usage =
- "ContinuedFraction[x,n] generates the continued fraction
- representation for the number x to order n. Note that the
- order returned may be less than n if the continued fraction
- terminates before n steps."
-
- ContinuedFractionForm::usage =
- "ContinuedFractionForm[{a0,a1,..}] is a continued-fraction;
- it is converted to an ordinary rational number using Normal."
-
- Begin["`Private`"]
-
- ContinuedFraction::incomp =
- "Warning: ContinuedFraction either terminated or argument was
- unable to be evaluated to sufficient precision in a reasonable
- number of attempts.";
-
- ContinuedFraction[x_?MachineNumberQ,n_Integer?Positive] :=
- ContinuedFraction[SetPrecision[x, $MachinePrecision],n]
-
- ContinuedFraction[x:(_Real | _Rational), n_Integer?Positive] :=
- ContinuedFractionForm[Floor[Prepend[cf[x,n - 1],x]]]
-
- ContinuedFraction[x_?(Not[NumberQ[#]] && NumberQ[N[#]] &),
- n_] :=
- Module[{nx, prec = n/2 + 10, out = {}, i = 1},
- While[Length[out] < n-1 && i++ < n,
- nx = N[x, prec];
- out = cf[nx, n-1];
- prec += (n - Length[out])/2 + 10
- ];
- If[Length[out] < n-1,
- Message[ContinuedFraction::incomp]
- ];
- ContinuedFractionForm[Floor[Prepend[out,nx]]]
- ]
-
- cf[num_,ord_] := {}/;((num - Floor[num]) == 0)
-
- cf[num_,0] := {}
-
- cf[num_, ord_] :=
- Module[{tmp = 1/(num - Floor[num])},
- Join[{tmp}, cf[tmp,ord - 1]]
- ]
-
- (*
- ContinuedFractionForm/: Normal[ContinuedFractionForm[a_List]] :=
- Last[Accumulate[ 1 / #1 + #2 &, Reverse[a]]]
- *)
-
- ContinuedFractionForm/: Normal[ContinuedFractionForm[a_List]] :=
- Fold[ 1 / #1 + #2 &, Last[a], Rest[ Reverse[a]]]
-
- End[] (* NumberTheory`ContinuedFractions`Private` *)
-
- Protect[ ContinuedFraction, ContinuedFractionForm ]
-
- EndPackage[] (* NumberTheory`ContinuedFractions` *)
-
- (*:Limitations: none known. *)
-
- (*:Examples:
-
- ContinuedFraction[ N[Pi], 4 ]
-
- Normal[ ContinuedFractionForm[{1, 1, 2, 2}] ]
- *)
-