Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/rings/contfrac.py
4097 views
1
r"""
2
Continued Fractions
3
4
Sage implements the field ``ContinuedFractionField`` (or ``CFF``
5
for short) of finite simple continued fractions. This is really
6
isomorphic to the field `\QQ` of rational numbers, but with different
7
printing and semantics. It should be possible to use this field in
8
most cases where one could use `\QQ`, except arithmetic is slower.
9
10
The ``continued_fraction(x)`` command returns an element of
11
``CFF`` that defines a continued fraction expansion to `x`. The
12
command ``continued_fraction(x,bits)`` computes the continued
13
fraction expansion of an approximation to `x` with given bits of
14
precision. Use ``show(c)`` to see a continued fraction nicely
15
typeset, and ``latex(c)`` to obtain the typeset version, e.g., for
16
inclusion in a paper.
17
18
EXAMPLES:
19
We create some example elements of the continued fraction field::
20
21
sage: c = continued_fraction([1,2]); c
22
[1, 2]
23
sage: c = continued_fraction([3,7,15,1,292]); c
24
[3, 7, 15, 1, 292]
25
sage: c = continued_fraction(pi); c
26
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14]
27
sage: c.value()
28
80143857/25510582
29
sage: QQ(c)
30
80143857/25510582
31
sage: RealField(200)(QQ(c) - pi)
32
-5.7908701643756732744264903067012149647564522968979302505514e-16
33
34
We can also create matrices, polynomials, vectors, etc., over the continued
35
fraction field.
36
37
::
38
39
sage: a = random_matrix(CFF, 4)
40
sage: a
41
[ [-1, 2] [-1, 1, 94] [0, 2] [-12]]
42
[ [-1] [0, 2] [-1, 1, 3] [0, 1, 2]]
43
[ [-3, 2] [0] [0, 1, 2] [-1]]
44
[ [1] [-1] [0, 3] [1]]
45
sage: f = a.charpoly()
46
sage: f
47
[1]*x^4 + ([-2, 3])*x^3 + [14, 1, 1, 1, 9, 1, 8]*x^2 + ([-13, 4, 1, 2, 1, 1, 1, 1, 1, 2, 2])*x + [-6, 1, 5, 9, 1, 5]
48
sage: f(a)
49
[[0] [0] [0] [0]]
50
[[0] [0] [0] [0]]
51
[[0] [0] [0] [0]]
52
[[0] [0] [0] [0]]
53
sage: vector(CFF, [1/2, 2/3, 3/4, 4/5])
54
([0, 2], [0, 1, 2], [0, 1, 3], [0, 1, 4])
55
56
AUTHORS:
57
58
- Niles Johnson (2010-08): Trac #3893: ``random_element()`` should pass on ``*args`` and ``**kwds``.
59
60
"""
61
from sage.structure.element import FieldElement
62
from sage.structure.parent_gens import ParentWithGens
63
from sage.libs.pari.all import pari
64
65
from field import Field
66
from rational_field import QQ
67
from integer_ring import ZZ
68
from infinity import infinity
69
from real_mpfr import is_RealNumber, RealField
70
from real_double import RDF
71
from arith import (continued_fraction_list,
72
convergent, convergents)
73
74
75
class ContinuedFractionField_class(Field):
76
"""
77
The field of all finite continued fraction of real numbers.
78
79
EXAMPLES::
80
81
sage: CFF
82
Field of all continued fractions
83
84
The continued fraction field inherits from the base class
85
:class:`sage.rings.ring.Field`. However it was initialised
86
as such only since trac ticket #11900::
87
88
sage: CFF.category()
89
Category of fields
90
91
"""
92
def __init__(self):
93
"""
94
EXAMPLES::
95
96
sage: ContinuedFractionField()
97
Field of all continued fractions
98
"""
99
Field.__init__(self, self)
100
self._assign_names(('x'),normalize=False)
101
102
def __cmp__(self, right):
103
"""
104
EXAMPLES::
105
106
sage: CFF == ContinuedFractionField()
107
True
108
sage: CFF == CDF
109
False
110
sage: loads(dumps(CFF)) == CFF
111
True
112
"""
113
return cmp(type(self), type(right))
114
115
def __iter__(self):
116
"""
117
EXAMPLES::
118
119
sage: i = 0
120
sage: for a in CFF:
121
... print a
122
... i += 1
123
... if i > 5: break
124
...
125
[0]
126
[1]
127
[-1]
128
[0, 2]
129
[-1, 2]
130
[2]
131
"""
132
for n in QQ:
133
yield self(n)
134
135
136
def _latex_(self):
137
r"""
138
EXAMPLES::
139
140
sage: latex(CFF)
141
\Bold{CFF}
142
"""
143
return "\\Bold{CFF}"
144
145
def _is_valid_homomorphism_(self, codomain, im_gens):
146
"""
147
Return whether or not the map to codomain by sending the
148
continued fraction [1] of self to im_gens[0] is a
149
homomorphism.
150
151
EXAMPLES::
152
153
sage: CFF._is_valid_homomorphism_(ZZ,[ZZ(1)])
154
False
155
sage: CFF._is_valid_homomorphism_(CFF,[CFF(1)])
156
True
157
"""
158
try:
159
return im_gens[0] == codomain._coerce_(self(1))
160
except TypeError:
161
return False
162
163
def _repr_(self):
164
"""
165
EXAMPLES::
166
167
sage: CFF
168
Field of all continued fractions
169
"""
170
return "Field of all continued fractions"
171
172
def _coerce_impl(self, x):
173
"""
174
Anything that implicitly coerces to the rationals or a real
175
field, implicitly coerces to the continued fraction field.
176
177
EXAMPLES:
178
179
The additions below call _coerce_impl implicitly::
180
181
sage: a = CFF(3/5); a
182
[0, 1, 1, 2]
183
sage: a + 2/5
184
[1]
185
sage: 2/5 + a
186
[1]
187
sage: 1.5 + a
188
[2, 10]
189
sage: a + 1.5
190
[2, 10]
191
"""
192
if is_RealNumber(x):
193
return self(x)
194
return self._coerce_try(x, [QQ, RDF])
195
196
def __call__(self, x, bits=None, nterms=None):
197
"""
198
INPUT:
199
200
- `x` -- a number
201
202
- ``bits`` -- integer (optional) the number of bits of the
203
input number to use when computing the continued fraction.
204
205
EXAMPLES::
206
207
sage: CFF(1.5)
208
[1, 2]
209
sage: CFF(e)
210
[2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1]
211
sage: CFF(pi)
212
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14]
213
sage: CFF([1,2,3])
214
[1, 2, 3]
215
sage: CFF(15/17)
216
[0, 1, 7, 2]
217
sage: c2 = loads(dumps(CFF))
218
sage: c2(CFF(15/17)).parent() is c2
219
True
220
221
We illustrate varying the bits parameter::
222
223
sage: CFF(pi)
224
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14]
225
sage: CFF(pi, bits=20)
226
[3, 7]
227
sage: CFF(pi, bits=80)
228
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, 1]
229
sage: CFF(pi, bits=100)
230
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, 1, 84, 2, 1, 1, 15, 3]
231
232
And varying the nterms parameter::
233
234
sage: CFF(pi, nterms=3)
235
[3, 7, 15]
236
sage: CFF(pi, nterms=10)
237
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1]
238
sage: CFF(pi, bits=10, nterms=10)
239
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1]
240
"""
241
return ContinuedFraction(self, x, bits, nterms)
242
243
def __len__(self):
244
"""
245
EXAMPLES::
246
247
sage: len(CFF)
248
Traceback (most recent call last):
249
...
250
TypeError: len() of unsized object
251
"""
252
raise TypeError, 'len() of unsized object'
253
254
def gens(self):
255
"""
256
EXAMPLES::
257
258
sage: CFF.gens()
259
([1],)
260
"""
261
return (self(1), )
262
263
def gen(self, n=0):
264
"""
265
EXAMPLES::
266
267
sage: CFF.gen()
268
[1]
269
sage: CFF.0
270
[1]
271
"""
272
273
if n == 0:
274
return self(1)
275
else:
276
raise IndexError, "n must be 0"
277
278
def degree(self):
279
"""
280
EXAMPLES::
281
282
sage: CFF.degree()
283
1
284
"""
285
return 1
286
287
def ngens(self):
288
"""
289
EXAMPLES::
290
291
sage: CFF.ngens()
292
1
293
"""
294
return 1
295
296
def is_field(self, proof = True):
297
"""
298
Return True, since the continued fraction field is a field.
299
300
EXAMPLES::
301
302
sage: CFF.is_field()
303
True
304
"""
305
return True
306
307
def is_finite(self):
308
"""
309
Return False, since the continued fraction field is not finite.
310
311
EXAMPLES::
312
313
sage: CFF.is_finite()
314
False
315
"""
316
return False
317
318
def is_atomic_repr(self):
319
"""
320
Return False, since continued fractions are not atomic.
321
322
EXAMPLES::
323
324
sage: CFF.is_atomic_repr()
325
False
326
"""
327
return False
328
329
def characteristic(self):
330
"""
331
Return 0, since the continued fraction field has characteristic 0.
332
333
EXAMPLES::
334
335
sage: c = CFF.characteristic(); c
336
0
337
sage: parent(c)
338
Integer Ring
339
"""
340
return ZZ(0)
341
342
def order(self):
343
"""
344
EXAMPLES::
345
346
sage: CFF.order()
347
+Infinity
348
"""
349
return infinity
350
351
def random_element(self, *args, **kwds):
352
"""
353
EXAMPLES::
354
355
sage: CFF.random_element(10,10)
356
[0, 4]
357
358
Passes extra positional or keyword arguments through::
359
360
sage: [CFF.random_element(den_bound=10, num_bound=2) for x in range(4)]
361
[[-1, 1, 3], [0, 7], [0, 3], [0, 4]]
362
363
364
365
"""
366
return self(QQ.random_element(*args, **kwds))
367
368
369
class ContinuedFraction(FieldElement):
370
"""
371
A continued fraction object.
372
373
EXAMPLES::
374
375
sage: continued_fraction(pi)
376
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14]
377
sage: CFF(pi)
378
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14]
379
"""
380
def __init__(self, parent, x, bits=None, nterms=None):
381
"""
382
EXAMPLES::
383
384
sage: sage.rings.contfrac.ContinuedFraction(CFF,[1,2,3,4,1,2])
385
[1, 2, 3, 4, 1, 2]
386
sage: sage.rings.contfrac.ContinuedFraction(CFF,[1,2,3,4,-1,2])
387
Traceback (most recent call last):
388
...
389
ValueError: each entry except the first must be positive
390
"""
391
FieldElement.__init__(self, parent)
392
if isinstance(x, ContinuedFraction):
393
self._x = list(x._x)
394
elif isinstance(x, (list, tuple)):
395
x = [ZZ(a) for a in x]
396
for i in range(1,len(x)):
397
if x[i] <= 0:
398
raise ValueError, "each entry except the first must be positive"
399
self._x = list(x)
400
else:
401
self._x = [ZZ(a) for a in continued_fraction_list(x, bits=bits, nterms=nterms)]
402
403
def __getitem__(self, n):
404
"""
405
Returns `n`-th term of the continued fraction.
406
407
OUTPUT:
408
- an integer or a a continued fraction
409
410
EXAMPLES::
411
412
sage: a = continued_fraction(pi); a
413
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14]
414
sage: a[4]
415
292
416
sage: a[-1]
417
14
418
sage: a[2:5]
419
[15, 1, 292]
420
sage: a[:3]
421
[3, 7, 15]
422
sage: a[4:]
423
[292, 1, 1, 1, 2, 1, 3, 1, 14]
424
sage: a[4::2]
425
[292, 1, 2, 3, 14]
426
"""
427
if isinstance(n, slice):
428
start, stop, step = n.indices(len(self))
429
return ContinuedFraction(self.parent(), self._x[start:stop:step])
430
else:
431
return self._x[n]
432
433
def _repr_(self):
434
"""
435
EXAMPLES::
436
437
sage: a = continued_fraction(pi); a
438
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14]
439
sage: a.rename('continued fraction of pi')
440
sage: a
441
continued fraction of pi
442
"""
443
return str(self._x)
444
445
def convergents(self):
446
"""
447
Return a list of rational numbers, which are the partial
448
convergents of this continued fraction.
449
450
OUTPUT:
451
452
- list of rational numbers
453
454
EXAMPLES::
455
456
sage: a = CFF(pi, bits=34); a
457
[3, 7, 15, 1, 292]
458
sage: a.convergents()
459
[3, 22/7, 333/106, 355/113, 103993/33102]
460
sage: a.value()
461
103993/33102
462
sage: a[:-1].value()
463
355/113
464
"""
465
return convergents(self._x)
466
467
def convergent(self, n):
468
"""
469
Return the `n`-th partial convergent to self.
470
471
OUTPUT:
472
473
rational number
474
475
EXAMPLES::
476
477
sage: a = CFF(pi, bits=34); a
478
[3, 7, 15, 1, 292]
479
sage: a.convergents()
480
[3, 22/7, 333/106, 355/113, 103993/33102]
481
sage: a.convergent(0)
482
3
483
sage: a.convergent(1)
484
22/7
485
sage: a.convergent(4)
486
103993/33102
487
"""
488
return convergent(self._x, n)
489
490
def __len__(self):
491
"""
492
Return the number of terms in this continued fraction.
493
494
EXAMPLES::
495
496
sage: len(continued_fraction([1,2,3,4,5]) )
497
5
498
"""
499
return len(self._x)
500
501
def pn(self, n):
502
"""
503
Return the numerator of the `n`-th partial convergent, computed
504
using the recurrence.
505
506
EXAMPLES::
507
508
sage: c = continued_fraction(pi); c
509
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14]
510
sage: c.pn(0), c.qn(0)
511
(3, 1)
512
sage: len(c)
513
13
514
sage: c.pn(12), c.qn(12)
515
(80143857, 25510582)
516
"""
517
if n < -2:
518
raise ValueError, "n must be at least -2"
519
if n > len(self._x):
520
raise ValueError, "n must be at most %s"%len(self._x)
521
try:
522
return self.__pn[n+2]
523
except AttributeError:
524
self.__pn = [0, 1, self._x[0]]
525
self.__qn = [1, 0, 1]
526
except IndexError:
527
pass
528
for k in range(len(self.__pn), n+3):
529
self.__pn.append(self._x[k-2]*self.__pn[k-1] + self.__pn[k-2])
530
self.__qn.append(self._x[k-2]*self.__qn[k-1] + self.__qn[k-2])
531
return self.__pn[n+2]
532
533
def qn(self, n):
534
"""
535
Return the denominator of the `n`-th partial convergent, computed
536
using the recurrence.
537
538
EXAMPLES::
539
540
sage: c = continued_fraction(pi); c
541
[3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14]
542
sage: c.qn(0), c.pn(0)
543
(1, 3)
544
sage: len(c)
545
13
546
sage: c.pn(12), c.qn(12)
547
(80143857, 25510582)
548
"""
549
if n < -2:
550
raise ValueError, "n must be at least -2"
551
if n > len(self._x):
552
raise ValueError, "n must be at most %s"%len(self._x)
553
try:
554
return self.__qn[n+2]
555
except (AttributeError, IndexError):
556
pass
557
self.pn(n)
558
return self.__qn[n+2]
559
560
def _rational_(self):
561
"""
562
EXAMPLES::
563
564
sage: a = CFF(-17/389); a
565
[-1, 1, 21, 1, 7, 2]
566
sage: a._rational_()
567
-17/389
568
sage: QQ(a)
569
-17/389
570
"""
571
try:
572
return self.__rational
573
except AttributeError:
574
r = convergents(self._x)[-1]
575
self.__rational =r
576
return r
577
578
def value(self):
579
"""
580
EXAMPLES::
581
582
sage: a = CFF(-17/389); a
583
[-1, 1, 21, 1, 7, 2]
584
sage: a.value()
585
-17/389
586
sage: QQ(a)
587
-17/389
588
"""
589
return self._rational_()
590
591
def numerator(self):
592
"""
593
EXAMPLES::
594
595
sage: a = CFF(-17/389); a
596
[-1, 1, 21, 1, 7, 2]
597
sage: a.numerator()
598
-17
599
"""
600
return self._rational_().numerator()
601
602
def denominator(self):
603
"""
604
EXAMPLES::
605
606
sage: a = CFF(-17/389); a
607
[-1, 1, 21, 1, 7, 2]
608
sage: a.denominator()
609
389
610
"""
611
return self._rational_().denominator()
612
613
def __int__(self):
614
"""
615
EXAMPLES::
616
617
sage: a = CFF(-17/389); a
618
[-1, 1, 21, 1, 7, 2]
619
sage: int(a)
620
-1
621
"""
622
return int(self._rational_())
623
624
def __long__(self):
625
"""
626
EXAMPLES::
627
628
sage: a = CFF(-17/389); a
629
[-1, 1, 21, 1, 7, 2]
630
sage: long(a)
631
-1L
632
"""
633
return long(self._rational_())
634
635
def __float__(self):
636
"""
637
EXAMPLES::
638
639
sage: a = CFF(-17/389); a
640
[-1, 1, 21, 1, 7, 2]
641
sage: float(a)
642
-0.04370179948586118
643
"""
644
return float(self._rational_())
645
646
def _add_(self, right):
647
"""
648
EXAMPLES::
649
650
sage: a = CFF(-17/389)
651
sage: b = CFF(1/389)
652
sage: c = a+b; c
653
[-1, 1, 23, 3, 5]
654
sage: c.value()
655
-16/389
656
"""
657
return ContinuedFraction(self.parent(),
658
self._rational_() + right._rational_())
659
660
def _sub_(self, right):
661
"""
662
EXAMPLES::
663
664
sage: a = CFF(-17/389)
665
sage: b = CFF(1/389)
666
sage: c = a - b; c
667
[-1, 1, 20, 1, 1, 1, 1, 3]
668
sage: c.value()
669
-18/389
670
"""
671
return ContinuedFraction(self.parent(),
672
self._rational_() - right._rational_())
673
674
def _mul_(self, right):
675
"""
676
EXAMPLES::
677
678
sage: a = CFF(-17/389)
679
sage: b = CFF(1/389)
680
sage: c = a * b; c
681
[-1, 1, 8900, 4, 4]
682
sage: c.value(), (-1/389)*(17/389)
683
(-17/151321, -17/151321)
684
"""
685
return ContinuedFraction(self.parent(),
686
self._rational_() * right._rational_())
687
688
def _div_(self, right):
689
"""
690
EXAMPLES::
691
692
sage: a = CFF(-17/389)
693
sage: b = CFF(1/389)
694
sage: c = a / b; c
695
[-17]
696
sage: c.value(), (17/389) / (-1/389)
697
(-17, -17)
698
"""
699
return ContinuedFraction(self.parent(),
700
self._rational_() / right._rational_())
701
702
def __cmp__(self, right):
703
"""
704
EXAMPLES::
705
706
sage: a = CFF(-17/389)
707
sage: b = CFF(1/389)
708
sage: a < b
709
True
710
sage: QQ(a) < QQ(b)
711
True
712
sage: QQ(a)
713
-17/389
714
sage: QQ(b)
715
1/389
716
"""
717
return cmp(self._rational_(), right._rational_())
718
719
def _latex_(self):
720
"""
721
EXAMPLES::
722
723
sage: a = CFF(-17/389)
724
sage: latex(a)
725
-1+ \frac{\displaystyle 1}{\displaystyle 1+ \frac{\displaystyle 1}{\displaystyle 21+ \frac{\displaystyle 1}{\displaystyle 1+ \frac{\displaystyle 1}{\displaystyle 7+ \frac{\displaystyle 1}{\displaystyle 2}}}}}
726
"""
727
v = self._x
728
if len(v) == 0:
729
return '0'
730
s = str(v[0])
731
for i in range(1,len(v)):
732
s += '+ \\frac{\\displaystyle 1}{\\displaystyle %s'%v[i]
733
s += '}'*(len(v)-1)
734
return s
735
736
def sqrt(self, prec=53, all=False):
737
"""
738
Return continued fraction approximation to square root of the
739
value of this continued fraction.
740
741
INPUT:
742
743
- `prec` -- integer (default: 53) precision of square root
744
that is approximated
745
746
- `all` -- bool (default: False); if True, return all square
747
roots of self, instead of just one.
748
749
EXAMPLES::
750
751
sage: a = CFF(4/19); a
752
[0, 4, 1, 3]
753
sage: b = a.sqrt(); b
754
[0, 2, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1]
755
sage: b.value()
756
4508361/9825745
757
sage: float(b.value()^2 - a)
758
-5.451492525672688e-16
759
sage: b = a.sqrt(prec=100); b
760
[0, 2, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5]
761
sage: b^2
762
[0, 4, 1, 3, 7849253184229368265220252099, 1, 3]
763
sage: a.sqrt(all=True)
764
[[0, 2, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1],
765
[-1, 1, 1, 5, 1, 1, 2, 1, 16, 1, 2, 1, 1, 5, 4, 5, 1, 1, 2, 1]]
766
sage: a = CFF(4/25).sqrt(); a
767
[0, 2, 2]
768
sage: a.value()
769
2/5
770
"""
771
r = self._rational_()
772
if r < 0:
773
raise ValueError, "self must be positive"
774
X = r.sqrt(all=all, prec=prec)
775
if not all:
776
return ContinuedFraction(self.parent(), X)
777
else:
778
return [ContinuedFraction(self.parent(), x) for x in X]
779
780
def list(self):
781
"""
782
Return copy of the underlying list of this continued fraction.
783
784
EXAMPLES::
785
786
sage: a = CFF(e); v = a.list(); v
787
[2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1]
788
sage: v[0] = 5
789
sage: a
790
[2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1]
791
"""
792
return list(self._x)
793
794
def __hash__(self):
795
"""
796
Return hash of self, which is the same as the hash of the value
797
of self, as a rational number.
798
799
EXAMPLES::
800
801
sage: a = CFF(e)
802
sage: hash(a)
803
19952398
804
sage: hash(QQ(a))
805
19952398
806
"""
807
return hash(self._rational_())
808
809
def __invert__(self):
810
"""
811
Return the multiplicative inverse of self.
812
813
EXAMPLES::
814
815
sage: a = CFF(e)
816
sage: b = ~a; b
817
[0, 2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 2]
818
sage: b*a
819
[1]
820
"""
821
return ContinuedFraction(self.parent(),
822
self._rational_().__invert__())
823
824
def __pow__(self, n):
825
"""
826
Return self to the power of `n`.
827
828
EXAMPLES::
829
830
sage: a = CFF([1,2,3]); a
831
[1, 2, 3]
832
sage: a^3
833
[2, 1, 10, 1, 4, 1, 4]
834
sage: QQ(a)^3 == QQ(a^3)
835
True
836
sage: a^(-3)
837
[0, 2, 1, 10, 1, 4, 1, 4]
838
sage: QQ(a)^(-3) == QQ(a^(-3))
839
True
840
"""
841
return ContinuedFraction(self.parent(),
842
self._rational_()**n)
843
844
def __neg__(self):
845
"""
846
Return additive inverse of self.
847
848
EXAMPLES::
849
850
sage: a = CFF(-17/389); a
851
[-1, 1, 21, 1, 7, 2]
852
sage: -a
853
[0, 22, 1, 7, 2]
854
sage: QQ(-a)
855
17/389
856
"""
857
return ContinuedFraction(self.parent(),
858
self._rational_().__neg__())
859
860
def __abs__(self):
861
"""
862
Return absolute value of self.
863
864
EXAMPLES::
865
866
sage: a = CFF(-17/389); a
867
[-1, 1, 21, 1, 7, 2]
868
sage: abs(a)
869
[0, 22, 1, 7, 2]
870
sage: QQ(abs(a))
871
17/389
872
"""
873
return ContinuedFraction(self.parent(),
874
self._rational_().__abs__())
875
876
def is_one(self):
877
"""
878
Return True if self is one.
879
880
EXAMPLES::
881
882
sage: continued_fraction(1).is_one()
883
True
884
sage: continued_fraction(2).is_one()
885
False
886
"""
887
return self._rational_().is_one()
888
889
def __nonzero__(self):
890
"""
891
Return False if self is zero.
892
893
EXAMPLES::
894
895
sage: continued_fraction(0).is_zero()
896
True
897
sage: continued_fraction(1).is_zero()
898
False
899
"""
900
return not self._rational_().is_zero()
901
902
def _pari_(self):
903
"""
904
Return PARI list corresponding to this continued fraction.
905
906
EXAMPLES::
907
908
sage: c = continued_fraction(0.12345); c
909
[0, 8, 9, 1, 21, 1, 1]
910
sage: pari(c)
911
[0, 8, 9, 1, 21, 1, 1]
912
"""
913
return pari(self._x)
914
915
def _interface_init_(self, I=None):
916
"""
917
Return list representation for other systems corresponding to
918
this continued fraction.
919
920
EXAMPLES::
921
922
sage: c = continued_fraction(0.12345); c
923
[0, 8, 9, 1, 21, 1, 1]
924
sage: gp(c)
925
[0, 8, 9, 1, 21, 1, 1]
926
sage: gap(c)
927
[ 0, 8, 9, 1, 21, 1, 1 ]
928
sage: maxima(c)
929
[0,8,9,1,21,1,1]
930
"""
931
return str(self._x)
932
933
def additive_order(self):
934
"""
935
Return the additive order of this continued fraction,
936
which we defined to be the additive order of its value.
937
938
EXAMPLES::
939
940
sage: CFF(-1).additive_order()
941
+Infinity
942
sage: CFF(0).additive_order()
943
1
944
"""
945
return self.value().additive_order()
946
947
def multiplicative_order(self):
948
"""
949
Return the multiplicative order of this continued fraction,
950
which we defined to be the multiplicative order of its value.
951
952
EXAMPLES::
953
954
sage: CFF(-1).multiplicative_order()
955
2
956
sage: CFF(1).multiplicative_order()
957
1
958
sage: CFF(pi).multiplicative_order()
959
+Infinity
960
"""
961
return self.value().multiplicative_order()
962
963
964
CFF = ContinuedFractionField_class()
965
966
def ContinuedFractionField():
967
"""
968
Return the (unique) field of all continued fractions.
969
970
EXAMPLES::
971
972
sage: ContinuedFractionField()
973
Field of all continued fractions
974
"""
975
return CFF
976
977
def continued_fraction(x, bits=None, nterms=None):
978
"""
979
Return the truncated continued fraction expansion of the real number
980
`x`, computed with an interval floating point approximation of `x`
981
to the given number of bits of precision. The returned continued
982
fraction is a list-like object, with a value method and partial
983
convergents method.
984
985
If bits is not given, then use the number of valid bits of
986
precision of `x`, if `x` is a floating point number, or 53 bits
987
otherwise. If nterms is given, the precision is increased until
988
the specified number of terms can be computed, if possible.
989
990
INPUT:
991
992
- `x` -- number
993
994
- ``bits`` -- None (default) or a positive integer
995
996
- ``nterms`` -- None (default) or a positive integer
997
998
OUTPUT:
999
1000
- a continued fraction
1001
1002
EXAMPLES::
1003
1004
sage: v = continued_fraction(sqrt(2)); v
1005
[1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
1006
sage: v = continued_fraction(sqrt(2), nterms=22); v
1007
[1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
1008
sage: type(v)
1009
<class 'sage.rings.contfrac.ContinuedFraction'>
1010
sage: parent(v)
1011
Field of all continued fractions
1012
sage: v.value()
1013
131836323/93222358
1014
sage: RR(v.value()) == RR(sqrt(2))
1015
True
1016
sage: v.convergents()
1017
[1, 3/2, 7/5, 17/12, 41/29, 99/70, 239/169,...131836323/93222358]
1018
sage: [RR(x) for x in v.convergents()]
1019
[1.00000000000000, 1.50000000000000, 1.40000000000000, 1.41666666666667, ...1.41421356237310]
1020
sage: continued_fraction(sqrt(2), 10)
1021
[1, 2, 2]
1022
sage: v.numerator()
1023
131836323
1024
sage: v.denominator()
1025
93222358
1026
sage: [v.pn(i) for i in range(10)]
1027
[1, 3, 7, 17, 41, 99, 239, 577, 1393, 3363]
1028
sage: [v.qn(i) for i in range(10)]
1029
[1, 2, 5, 12, 29, 70, 169, 408, 985, 2378]
1030
1031
Here are some more examples::
1032
1033
sage: continued_fraction(e, bits=20)
1034
[2, 1, 2, 1, 1, 4, 1, 1]
1035
sage: continued_fraction(e, bits=30)
1036
[2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8]
1037
sage: continued_fraction(RealField(200)(e))
1038
[2, 1, 2, 1, 1, 4, 1, 1, 6, ...36, 1, 1, 38, 1, 1]
1039
1040
Initial rounding can result in incorrect trailing digits::
1041
1042
sage: continued_fraction(RealField(39)(e))
1043
[2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 2]
1044
sage: continued_fraction(RealIntervalField(39)(e))
1045
[2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10]
1046
"""
1047
return CFF(x, bits=bits, nterms=nterms)
1048
1049
1050
1051
1052
1053