# Ticket #14567: trac_14567_rewiew-tm.patch

File trac_14567_rewiew-tm.patch, 7.3 KB (added by tmonteil, 6 years ago)
• ## sage/rings/continued_fractions.py

# HG changeset patch
# User Thierry Monteil <sage at lma.metelu.net>
# Date 1382189837 -7200
# Node ID d465d0ce205213b018245603661e17f60d7a425e
# Parent  54e74b4c72b9f5aee86a7c622db945d1021cdf3e
#14567 tmonteil's review

diff --git a/sage/rings/continued_fractions.py b/sage/rings/continued_fractions.py
 a number). It is quite remarkable that - finite expansions correspond to rationals - any real number admits a unique continued fraction expansion, - finite expansions correspond to rationals, - ultimately periodic expansions correspond to quadratic numbers (ie numbers of the form a + b \sqrt{D} with a and b rationals and D square free integer) integer), - two real numbers x and y have the same tail (up to a shift) if and only if there are integers a,b,c,d with |ad - bc| = 1 and such that y = (ax + b) / (cx + d). Moreover, the rational numbers obtained by truncation of the expansion of a real number gives its so-called best approximations. For more informations on number gives its so-called best approximations. For more information on continued fractions, you may have a look at :wikipedia:Continued_fraction. EXAMPLES: stands for real continued fraction) or t sage: -8 + 1/(4 + 1/4) -132/17 It is also possible to create a continued fraction from a list of digits:: It is also possible to create a continued fraction from a list of numbers corresponding to its quotients:: sage: cf = CFF([-3,1,2,3,4,1,2,1]) sage: cf = CFF([-3, 1, 2, 3, 4, 1, 2, 1]) sage: cf.value() -465/202 represented as a pair of tuples, the pre sage: (3*sqrt2 + 1/2).continued_fraction() [4; (1, 2, 1, 7)*] sage: cf = CFF([(1,2,3),(1,4)]); cf sage: cf = CFF([(1, 2, 3), (1, 4)]); cf [1; 2, 3, (1, 4)*] sage: cf.value() -2/23*sqrt2 + 36/23 quadratic field:: Nevertheless, the tail is preserved under invertible integer homographies:: sage: apply_homography =  lambda m,z: (m[0,0]*z + m[0,1]) / (m[1,0]*z+m[1,1]) sage: apply_homography =  lambda m,z: (m[0,0]*z + m[0,1]) / (m[1,0]*z + m[1,1]) sage: m1 = SL2Z.random_element() sage: m2 = SL2Z.random_element() sage: a = sqrt2/3 Nevertheless, the tail is preserved unde sage: c = apply_homography(m2, a) sage: c.continued_fraction() [0; 1, 26, 1, 2, 2, (8, 4)*] sage: d = apply_homography(m1**2*m2**3, a) sage: d = apply_homography(m1**2 * m2**3, a) sage: d.continued_fraction() [0; 1, 2, 1, 1, 1, 1, 5, 2, 1, 1, 1, 1, 5, 26, 1, 2, 1, 26, 1, 2, 1, 26, 1, 2, 2, (8, 4)*] It is possible to make arithmetic operations on continued fractions:: sage: c1 = CFF([0,3,3,2,1,4,2]); c1 sage: c1 = CFF([0, 3, 3, 2, 1, 4, 2]); c1 [0; 3, 3, 2, 1, 4, 2] sage: c2 = CFF([-4,2,1,3]); c2 sage: c2 = CFF([-4, 2, 1, 3]); c2 [-4; 2, 1, 3] sage: c3 = -c1; c3 [-1; 1, 2, 3, 2, 1, 4, 2] sage: c1+c2 sage: c1 + c2 [-4; 1, 2, 628, 2] sage: c1+c3 sage: c1 + c3 [0] sage: c1/c2 And they can be used to create matrices, ([0; 2], [0; 1, 2], [0; 1, 3], [0; 1, 4]) The unary operations (negative and inversion) are quite fast but binary operations are quite slow. It is then not adviced, if speed is needed, to use operations are quite slow. It is then not advised, if speed is needed, to use them as the base class in a computation. .. TODO:: them as the base class in a computation. same method for an element of a number field) - Make a class for infinite precision real number built from an infinite list (ie an infinite word) list (i.e. an infinite word) - Make a class for non standard continued fractions of the form a_0 + b_0/(a_1 + b_1/(...)) (the standard continued fractions are when all b_n= 1 while the Hirzebruch-Jung continued fractions are the one for b_n = 1 while the Hirzebruch-Jung continued fractions are the one for which b_n = -1 for all n). See :wikipedia:Generalized_continued_fraction. def two_last_convergents(x): (0, 1, 1, 0) sage: two_last_convergents([0]) (1, 0, 0, 1) sage: two_last_convergents([-1,1,3,2]) sage: two_last_convergents([-1 , 1, 3, 2]) (-1, 4, -2, 9) """ p0, p1 = 0, 1 q0, q1 = 1, 0 for a in x: p0, p1 = p1, a*p1+p0 q0, q1 = q1, a*q1+q0 p0, p1 = p1, a*p1 + p0 q0, q1 = q1, a*q1 + q0 return p0, q0, p1, q1 class ContinuedFraction_generic(FieldEle def __abs__(self): """ Return absolute value of self. Return the absolute value of self. EXAMPLES:: class ContinuedFraction_generic(FieldEle 0.500000000000000 sage: continued_fraction([0,4]).n() 0.250000000000000 sage: continued_fraction([12,1,3,4,2,2,3,1,2]).n(digits=4) sage: continued_fraction([12, 1, 3, 4, 2, 2, 3, 1, 2]).n(digits=4) 12.76 sage: continued_fraction(12/7).n(digits=13) == (12/7).n(digits=13) class ContinuedFraction_generic(FieldEle sage: for _ in xrange(100): ....:     a = QQ.random_element(num_bound=1<<64) ....:     cf = continued_fraction(a) ....:     for prec in 17,24,53,128,256: ....:         for rnd in 'RNDN','RNDD','RNDU','RNDZ': ....:     for prec in 17, 24, 53, 128, 256: ....:         for rnd in 'RNDN', 'RNDD', 'RNDU', 'RNDZ': ....:             R = RealField(prec=prec, rnd=rnd) ....:             assert R(cf) == R(a) """ def continued_fraction_list(x, type="std OUTPUT: A lits of integers, the coefficients in the continued fraction expansion of A list of integers, the coefficients in the continued fraction expansion of x. If partial_convergents is set to True, then return a pair containing the coefficient list and the partial convergents list is returned. def continued_fraction(x, bits=None, nte sage: pi.n() 3.14159265358979 When possible, it is adviced to use anything else but the symbolic ring. When possible, it is advised to use anything else but the symbolic ring. Here we present an other way of dealing with the golden mean and the cube root of 2:: def Hirzebruch_Jung_continued_fraction_l OUTPUT: A lits of integers, the coefficients in the Hirzebruch-Jung continued A list of integers, the coefficients in the Hirzebruch-Jung continued fraction expansion of x. EXAMPLES:: def Hirzebruch_Jung_continued_fraction_l # sage.rings.continued_fractions in #14567 from sage.structure.sage_object import register_unpickle_override register_unpickle_override('sage.rings.contfrac', 'ContinuedFractionField_class',ContinuedFractionField) register_unpickle_override('sage.rings.contfrac', 'ContinuedFractionField_class', ContinuedFractionField)