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