Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/databases/oeis.py
8814 views
1
r"""
2
The On-Line Encyclopedia of Integer Sequences (OEIS)
3
4
You can query the OEIS (Online Database of Integer Sequences) through Sage in
5
order to:
6
7
- identify a sequence from its first terms.
8
- obtain more terms, formulae, references, etc. for a given sequence.
9
10
11
AUTHORS:
12
13
- Thierry Monteil (2012-02-10 -- 2013-06-21): initial version.
14
15
EXAMPLES::
16
17
sage: oeis
18
The On-Line Encyclopedia of Integer Sequences (http://oeis.org/)
19
20
What about a sequence starting with `3, 7, 15, 1` ?
21
22
::
23
24
sage: search = oeis([3, 7, 15, 1], max_results=4) ; search # optional -- internet
25
0: A001203: Continued fraction expansion of Pi.
26
1: A165416: Irregular array read by rows: The n-th row contains those distinct positive integers that each, when written in binary, occurs as a substring in binary n.
27
2: A193583: Number of fixed points under iteration of sum of squares of digits in base b.
28
3: A082495: (2^n-1) mod n.
29
30
sage: c = search[0] ; c # optional -- internet
31
A001203: Continued fraction expansion of Pi.
32
33
::
34
35
sage: c.first_terms(15) # optional -- internet
36
(3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1)
37
38
sage: c.examples() # optional -- internet
39
0: Pi = 3.1415926535897932384...
40
1: = 3 + 1/(7 + 1/(15 + 1/(1 + 1/(292 + ...))))
41
2: = [a_0; a_1, a_2, a_3, ...] = [3; 7, 15, 292, ...]
42
43
sage: c.comments() # optional -- internet
44
0: The first 5,821,569,425 terms were computed by _Eric W. Weisstein_ on Sep 18 2011.
45
1: The first 10,672,905,501 terms were computed by _Eric W. Weisstein_ on Jul 17 2013.
46
2: The first 15,000,000,000 terms were computed by _Eric W. Weisstein_ on Jul 27 2013.
47
48
::
49
50
sage: x = c.natural_object() ; x.parent() # optional -- internet
51
Field of all continued fractions
52
53
sage: x.convergents()[:7] # optional -- internet
54
[3, 22/7, 333/106, 355/113, 103993/33102, 104348/33215, 208341/66317]
55
56
sage: RR(x.value()) # optional -- internet
57
3.14159265358979
58
sage: RR(x.value()) == RR(pi) # optional -- internet
59
True
60
61
What about posets ? Are they hard to count ? To which other structures are they
62
related ?
63
64
::
65
66
sage: [Posets(i).cardinality() for i in range(10)]
67
[1, 1, 2, 5, 16, 63, 318, 2045, 16999, 183231]
68
sage: oeis(_) # optional -- internet
69
0: A000112: Number of partially ordered sets ("posets") with n unlabeled elements.
70
sage: p = _[0] # optional -- internet
71
72
::
73
74
sage: 'hard' in p.keywords() # optional -- internet
75
True
76
sage: len(p.formulas()) # optional -- internet
77
0
78
sage: len(p.first_terms()) # optional -- internet
79
17
80
81
::
82
83
sage: p.cross_references(fetch=True) # optional -- internet
84
0: A000798: Number of different quasi-orders (or topologies, or transitive digraphs) with n labeled elements.
85
1: A001035: Number of partially ordered sets ("posets") with n labeled elements (or labeled acyclic transitive digraphs).
86
2: A001930: Number of topologies, or transitive digraphs with n unlabeled nodes.
87
3: A006057: Number of labeled topologies with n points.
88
4: A079263: Number of constrained mixed models with n factors.
89
5: A079265: Number of antisymmetric transitive binary relations on n unlabeled points.
90
91
92
What does the Taylor expansion of the `e^(e^x-1)`` function have to do with
93
primes ?
94
95
::
96
97
sage: x = var('x') ; f(x) = e^(e^x - 1)
98
sage: L = [a*factorial(b) for a,b in taylor(f(x), x, 0, 20).coeffs()] ; L
99
[1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570, 4213597,
100
27644437, 190899322, 1382958545, 10480142147, 82864869804, 682076806159,
101
5832742205057, 51724158235372]
102
103
sage: oeis(L) # optional -- internet
104
0: A000110: Bell or exponential numbers: ways of placing n labeled balls into n indistinguishable boxes.
105
106
sage: b = _[0] # optional -- internet
107
108
sage: b.formulas()[0] # optional -- internet
109
'E.g.f.: exp( exp(x) - 1).'
110
111
sage: b.comments()[89] # optional -- internet
112
'Number n is prime if mod(a(n)-2,n) = 0. [From _Dmitry Kruchinin_, Feb 14 2012]'
113
114
sage: [n for n in range(2, 20) if (b(n)-2) % n == 0] # optional -- internet
115
[2, 3, 5, 7, 11, 13, 17, 19]
116
117
118
.. SEEALSO::
119
120
- If you plan to do a lot of automatic searches for subsequences, you
121
should consider installing :mod:`SloaneEncyclopedia
122
<sage.databases.sloane>`, a local partial copy of the OEIS.
123
- Some infinite OEIS sequences are implemented in Sage, via the
124
:mod:`sloane_functions <sage.combinat.sloane_functions>` module.
125
126
.. TODO::
127
128
- in case of flood, suggest the user to install the off-line database instead.
129
- interface with the off-line database (or reimplement it).
130
131
Classes and methods
132
-------------------
133
"""
134
135
#*****************************************************************************
136
# Copyright (C) 2012 Thierry Monteil <sage!lma.metelu.net>
137
#
138
# Distributed under the terms of the GNU General Public License (GPL)
139
# as published by the Free Software Foundation; either version 2 of
140
# the License, or (at your option) any later version.
141
# http://www.gnu.org/licenses/
142
#*****************************************************************************
143
144
from sage.structure.sage_object import SageObject
145
from sage.structure.sequence import Sequence
146
from sage.misc.lazy_import import lazy_import
147
lazy_import('sage.rings.semirings.non_negative_integer_semiring', 'NN')
148
from sage.rings.integer_ring import IntegerRing
149
from sage.rings.integer import Integer
150
from sage.rings.contfrac import ContinuedFractionField
151
from sage.rings.real_lazy import RealLazyField
152
from sage.misc.misc import verbose
153
from sage.misc.cachefunc import cached_method
154
from sage.misc.flatten import flatten
155
from sage.misc.unknown import Unknown
156
from sage.misc.misc import embedded
157
from sage.misc.html import html
158
from collections import defaultdict
159
from urllib import urlopen, urlencode
160
import re
161
162
oeis_url = 'http://oeis.org/'
163
164
def _fetch(url):
165
r"""
166
Fetch the given ``url``.
167
168
INPUT:
169
170
- ``url`` - a string corresponding to the URL to be fetched.
171
172
OUTPUT:
173
174
- a string representing the fetched web page.
175
176
TESTS::
177
178
sage: from sage.databases.oeis import _fetch, oeis_url
179
sage: _fetch(oeis_url + 'hints.html')[-8:-1] # optional -- internet
180
'</html>'
181
"""
182
try:
183
_ = verbose("Fetching URL %s ..." %url, caller_name='OEIS')
184
f = urlopen(url)
185
result = f.read()
186
f.close()
187
return result
188
except IOError, msg:
189
raise IOError, "%s\nError fetching %s." % (msg, url)
190
191
def _urls(html_string):
192
r"""
193
Return the list of URLs contained in ``html_string``.
194
195
Only URLs provided by HTML hyperlinks (``href`` attribute of ``<a>`` tags)
196
in are returned, not text strings starting with ``http://``.
197
198
INPUT:
199
200
- ``html_string`` - a string representing some HTML code.
201
202
OUTPUT:
203
204
- a list of (string) URLs contained in ``html_string``.
205
206
EXAMPLES::
207
208
sage: from sage.databases.oeis import _urls
209
sage: html = 'http://example.com is not a link, but <a href="http://sagemath.org/">sagemath</a> is'
210
sage: _urls(html)
211
['http://sagemath.org/']
212
213
"""
214
urls = []
215
from HTMLParser import HTMLParser
216
class MyHTMLParser(HTMLParser):
217
def handle_starttag(self, tag, attrs):
218
if tag == 'a':
219
for attr in attrs:
220
if attr[0] == 'href':
221
urls.append(attr[1])
222
MyHTMLParser().feed(html_string)
223
return urls
224
225
to_tuple = lambda string: tuple(Integer(x) for x in string.split(",") if x)
226
227
class OEIS:
228
r"""
229
The On-Line Encyclopedia of Integer Sequences.
230
231
``OEIS`` is a class representing the On-Line Encyclopedia of Integer
232
Sequences. You can query it using its methods, but ``OEIS`` can also be
233
called directly with three arguments:
234
235
- ``query`` - it can be:
236
237
- a string representing an OEIS ID (e.g. 'A000045').
238
- an integer representing an OEIS ID (e.g. 45).
239
- a list representing a sequence of integers.
240
- a string, representing a text search.
241
242
- ``max_results`` - (integer, default: 30) the maximum number of
243
results to return, they are sorted according to their relevance. In
244
any cases, the OEIS website will never provide more than 100 results.
245
246
- ``first_result`` - (integer, default: 0) allow to skip the
247
``first_result`` first results in the search, to go further.
248
This is useful if you are looking for a sequence that may appear
249
after the 100 first found sequences.
250
251
OUTPUT:
252
253
- if ``query`` is an integer or an OEIS ID (e.g. 'A000045'), returns
254
the associated OEIS sequence.
255
256
- if ``query`` is a string, returns a tuple of OEIS sequences whose
257
description corresponds to the query. Those sequences can be used
258
without the need to fetch the database again.
259
260
- if ``query`` is a list of integers, returns a tuple of OEIS sequences
261
containing it as a subsequence. Those sequences can be used without
262
the need to fetch the database again.
263
264
EXAMPLES::
265
266
sage: oeis
267
The On-Line Encyclopedia of Integer Sequences (http://oeis.org/)
268
269
A particular sequence can be called by its A-number or number::
270
271
sage: oeis('A000040') # optional -- internet
272
A000040: The prime numbers.
273
274
sage: oeis(45) # optional -- internet
275
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
276
277
The database can be searched by subsequence::
278
279
sage: search = oeis([1,2,3,5,8,13]) ; search # optional -- internet
280
0: A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
281
1: A027926: Triangular array T read by rows: T(n,0)=T(n,2n)=1 for n >= 0; ...
282
2: A001129: Iccanobif numbers: reverse digits of two previous terms and add.
283
284
sage: fibo = search[0] # optional -- internet
285
286
sage: fibo.name() # optional -- internet
287
'Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.'
288
289
sage: fibo.first_terms() # optional -- internet
290
(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987,
291
1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393,
292
196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887,
293
9227465, 14930352, 24157817, 39088169)
294
295
sage: fibo.cross_references()[0] # optional -- internet
296
'A039834'
297
298
sage: fibo == oeis(45) # optional -- internet
299
True
300
301
sage: sfibo = oeis('A039834') # optional -- internet
302
sage: sfibo.first_terms() # optional -- internet
303
(1, 1, 0, 1, -1, 2, -3, 5, -8, 13, -21, 34, -55, 89, -144, 233,
304
-377, 610, -987, 1597, -2584, 4181, -6765, 10946, -17711, 28657,
305
-46368, 75025, -121393, 196418, -317811, 514229, -832040, 1346269,
306
-2178309, 3524578, -5702887, 9227465, -14930352, 24157817)
307
308
sage: sfibo.first_terms(absolute_value=True)[2:20] == fibo.first_terms()[:18] # optional -- internet
309
True
310
311
sage: fibo.formulas()[3] # optional -- internet
312
'F(n) = F(n-1) + F(n-2) = -(-1)^n F(-n).'
313
314
sage: fibo.comments()[1] # optional -- internet
315
"F(n+2) = number of binary sequences of length n that have no
316
consecutive 0's."
317
318
sage: fibo.links()[0] # optional -- internet
319
'http://oeis.org/A000045/b000045.txt'
320
321
The database can be searched by description::
322
323
sage: oeis('prime gap factorization', max_results=4) # optional -- internet
324
0: A073491: Numbers having no prime gaps in their factorization.
325
1: A073490: Number of prime gaps in factorization of n.
326
2: A073492: Numbers having at least one prime gap in their factorization.
327
3: A073493: Numbers having exactly one prime gap in their factorization.
328
329
.. WARNING::
330
331
The following will fetch the OEIS database twice (once for searching the
332
database, and once again for creating the sequence ``fibo``)::
333
334
sage: oeis([1,2,3,5,8,13]) # optional -- internet
335
0: A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
336
1: A027926: Triangular array T read by rows: T(n,0)=T(n,2n)=1 for n >= 0; ...
337
2: A001129: Iccanobif numbers: reverse digits of two previous terms and add.
338
339
sage: fibo = oeis('A000045') # optional -- internet
340
341
Do not do this, it is slow, it costs bandwidth and server resources !
342
Instead, do the following, to reuse the result of the search to create
343
the sequence::
344
345
sage: oeis([1,2,3,5,8,13]) # optional -- internet
346
0: A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
347
1: A027926: Triangular array T read by rows: T(n,0)=T(n,2n)=1 for n >= 0; ...
348
2: A001129: Iccanobif numbers: reverse digits of two previous terms and add.
349
350
sage: fibo = _[0] # optional -- internet
351
"""
352
353
def __call__(self, query, max_results=3, first_result=0):
354
r"""
355
See the documentation of :class:`OEIS`.
356
357
TESTS::
358
359
sage: oeis()
360
Traceback (most recent call last):
361
...
362
TypeError: __call__() takes at least 2 arguments (1 given)
363
"""
364
if isinstance(query, str):
365
if re.match('^A[0-9]{6}$',query):
366
return self.find_by_id(query)
367
else:
368
return self.find_by_description(query, max_results, first_result)
369
elif isinstance(query, (int, Integer)):
370
return self.find_by_id(query)
371
elif isinstance(query, (list, tuple)):
372
return self.find_by_subsequence(query, max_results, first_result)
373
374
def __repr__(self):
375
r"""
376
Return the representation of ``self``.
377
378
TESTS::
379
380
sage: oeis
381
The On-Line Encyclopedia of Integer Sequences (http://oeis.org/)
382
"""
383
return "The On-Line Encyclopedia of Integer Sequences (%s)" % oeis_url
384
385
def find_by_id(self, ident):
386
r"""
387
388
INPUT:
389
390
- ``ident`` - a string representing the A-number of the sequence
391
or an integer representing its number.
392
393
OUTPUT:
394
395
- The OEIS sequence whose A-number or number corresponds to
396
``ident``.
397
398
EXAMPLES::
399
400
sage: oeis.find_by_id('A000040') # optional -- internet
401
A000040: The prime numbers.
402
403
sage: oeis.find_by_id(40) # optional -- internet
404
A000040: The prime numbers.
405
"""
406
if not isinstance(ident, str):
407
ident = str(ident)
408
ident = 'A000000'[:-len(ident)] + ident
409
options = {'q':ident, 'n':'1', 'fmt':'text'}
410
url = oeis_url + "search?" + urlencode(options)
411
sequence = _fetch(url).split('\n\n')[2]
412
return OEISSequence(sequence)
413
414
def find_by_description(self, description, max_results=3, first_result=0):
415
r"""
416
Search for OEIS sequences corresponding to the description.
417
418
INPUT:
419
420
- ``description`` - (string) the description the searched sequences.
421
422
- ``max_results`` - (integer, default: 3) the maximum number of results
423
we want. In any case, the on-line encyclopedia will not return more
424
than 100 results.
425
426
- ``first_result`` - (integer, default: 0) allow to skip the
427
``first_result`` first results in the search, to go further.
428
This is useful if you are looking for a sequence that may appear
429
after the 100 first found sequences.
430
431
OUTPUT:
432
433
- a tuple (with fancy formatting) of at most ``max_results`` OEIS
434
sequences. Those sequences can be used without the need to fetch the
435
database again.
436
437
EXAMPLES::
438
439
sage: oeis.find_by_description('prime gap factorization') # optional -- internet
440
0: A073491: Numbers having no prime gaps in their factorization.
441
1: A073490: Number of prime gaps in factorization of n.
442
2: A073492: Numbers having at least one prime gap in their factorization.
443
444
sage: prime_gaps = _[1] ; prime_gaps # optional -- internet
445
A073490: Number of prime gaps in factorization of n.
446
447
::
448
449
sage: oeis('beaver') # optional -- internet
450
0: A028444: Busy Beaver sequence, or Rado's sigma function: ...
451
1: A060843: Busy Beaver problem: a(n) = maximal number of steps ...
452
2: A131956: Busy Beaver variation: maximum number of steps for ...
453
454
sage: oeis('beaver', max_results=4, first_result=2) # optional -- internet
455
0: A131956: Busy Beaver variation: maximum number of steps for ...
456
1: A141475: Number of Turing machines with n states following ...
457
2: A131957: Busy Beaver sigma variation: maximum number of 1's ...
458
3: A052200: Number of n-state, 2-symbol, d+ in {LEFT, RIGHT}, ...
459
"""
460
options = {'q':description,
461
'n':str(max_results),
462
'fmt':'text',
463
'start':str(first_result)}
464
url = oeis_url + "search?" + urlencode(options)
465
sequence_list = _fetch(url).split('\n\n')[2:-1]
466
return FancyTuple(map(OEISSequence, sequence_list))
467
468
def find_by_subsequence(self, subsequence, max_results=3, first_result=0):
469
r"""
470
Search for OEIS sequences containing the given subsequence.
471
472
INPUT:
473
474
- ``subsequence`` - a list of integers.
475
476
- ``max_results`` - (integer, default: 3), the maximum of results requested.
477
478
- ``first_result`` - (integer, default: 0) allow to skip the
479
``first_result`` first results in the search, to go further.
480
This is useful if you are looking for a sequence that may appear
481
after the 100 first found sequences.
482
483
OUTPUT:
484
485
- a tuple (with fancy formatting) of at most ``max_results`` OEIS
486
sequences. Those sequences can be used without the need to fetch the
487
database again.
488
489
EXAMPLES::
490
491
sage: oeis.find_by_subsequence([2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]) # optional -- internet
492
0: A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
493
1: A177194: Fibonacci numbers whose decimal expression does not contain any digit 0.
494
2: A020695: Pisot sequence E(2,3).
495
496
sage: fibo = _[0] ; fibo # optional -- internet
497
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
498
"""
499
subsequence = str(subsequence)[1:-1]
500
return self.find_by_description(subsequence, max_results, first_result)
501
502
def browse(self):
503
r"""
504
Open the OEIS web page in a browser.
505
506
EXAMPLES::
507
508
sage: oeis.browse() # optional -- webbrowser
509
"""
510
import webbrowser
511
webbrowser.open(oeis_url)
512
513
def _imaginary_entry(self, keywords=''):
514
r"""
515
This is an imaginary entry of an OEIS sequence for offline tests.
516
517
INPUT:
518
519
- ``keywords`` - a string corresponding to the keyword field of the
520
sequence.
521
522
OUTPUT:
523
524
- a string representing the entry of the sequence.
525
526
TESTS::
527
528
sage: oeis._imaginary_entry().split('\n')[0]
529
'%I A999999 M9999 N9999'
530
531
sage: from sage.databases.oeis import OEISSequence
532
sage: keywords = 'simon,cussonet'
533
sage: s = OEISSequence(oeis._imaginary_entry(keywords))
534
sage: ','.join(s.keywords()) == keywords
535
True
536
537
"""
538
return ('%I A999999 M9999 N9999\n'
539
'%S A999999 1,1,1,1,1,1,1,1,\n'
540
'%T A999999 1,1,1,1,1,1,1,1,1,\n'
541
'%U A999999 1,1,1,1,1,1,1,1,1\n'
542
'%V A999999 1,1,1,1,-1,1,1,1,\n'
543
'%W A999999 1,1,1,1,1,1,1,1,1,\n'
544
'%X A999999 1,1,1,1,1,1,1,1,1\n'
545
'%N A999999 The opposite of twice the characteristic sequence of 42 plus one, starting from 38.\n'
546
'%D A999999 Lewis Carroll, Alice\'s Adventures in Wonderland.\n'
547
'%D A999999 Lewis Carroll, The Hunting of the Snark.\n'
548
'%D A999999 Deep Thought, The Answer to the Ultimate Question of Life, The Universe, and Everything.\n'
549
'%H A999999 Wikipedia, <a href="http://en.wikipedia.org/wiki/42_(number)">42 (number)</a>\n'
550
'%H A999999 See. also <a href="http://trac.sagemath.org/sage_trac/ticket/42">trac ticket #42</a>\n'
551
'%H A999999 Do not confuse with the sequence <a href="/A000042">A000042</a> or the sequence <a href="/A000024">A000024</a>\n'
552
'%H A999999 The string http://42.com is not a link.\n'
553
'%F A999999 For n big enough, s(n+1) - s(n) = 0.\n'
554
'%Y A999999 Related sequences are A000042 and its friend A000024.\n'
555
'%A A999999 Anonymous.\n'
556
'%O A999999 38,4\n'
557
'%E A999999 This sequence does not contain errors.\n'
558
'%e A999999 s(42) + s(43) = 0.\n'
559
'%p A999999 Do not even try, Maple is not able to produce such a sequence.\n'
560
'%t A999999 Mathematica neither.\n'
561
'%o A999999 (Python)\n'
562
'%o A999999 def A999999(n):\n'
563
'%o A999999 assert(isinstance(n, (int, Integer))), "n must be an integer."\n'
564
'%o A999999 if n < 38:\n'
565
'%o A999999 raise ValueError("The value %s is not accepted." %str(n)))\n'
566
'%o A999999 elif n == 42:\n'
567
'%o A999999 return -1\n'
568
'%o A999999 else:\n'
569
'%o A999999 return 1\n'
570
'%K A999999 ' + keywords + '\n'
571
'%C A999999 42 is the product of the first 4 prime numbers, except 5 and perhaps 1.\n'
572
'%C A999999 Apart from that, i have no comment.')
573
574
def _imaginary_sequence(self, keywords='sign,easy'):
575
r"""
576
This is the OEIS sequence corresponding to the imaginary entry.
577
Its main purpose is to allow offline doctesting.
578
579
INPUT:
580
581
- ``keywords`` - string (default: 'sign,easy'), a list of words
582
separated by commas.
583
584
OUTPUT:
585
586
- OEIS sequence.
587
588
TESTS::
589
590
sage: s = oeis._imaginary_sequence()
591
sage: s
592
A999999: The opposite of twice the characteristic sequence of 42 plus one, starting from 38.
593
sage: s[4]
594
-1
595
sage: s(42)
596
-1
597
"""
598
return OEISSequence(self._imaginary_entry(keywords))
599
600
class OEISSequence(SageObject):
601
r"""
602
The class of OEIS sequences.
603
604
This class implements OEIS sequences. Such sequences are produced from a
605
string in the OEIS format. They are usually produced by calls to the
606
On-Line Encyclopedia of Integer Sequences, represented by the class
607
:class:`OEIS`.
608
609
.. NOTE::
610
611
Since some sequences do not start with index 0, there is a difference
612
between calling and getting item, see :meth:`__call__` for more details
613
::
614
615
sage: sfibo = oeis('A039834') # optional -- internet
616
sage: sfibo.first_terms()[:10] # optional -- internet
617
(1, 1, 0, 1, -1, 2, -3, 5, -8, 13)
618
619
sage: sfibo(-2) # optional -- internet
620
1
621
sage: sfibo(3) # optional -- internet
622
2
623
sage: sfibo.offsets() # optional -- internet
624
(-2, 6)
625
626
sage: sfibo[0] # optional -- internet
627
1
628
sage: sfibo[6] # optional -- internet
629
-3
630
631
.. automethod:: __call__
632
"""
633
634
def __init__(self, entry):
635
r"""
636
Initializes an OEIS sequence.
637
638
TESTS::
639
640
sage: sfibo = oeis('A039834') # optional -- internet
641
642
sage: s = oeis._imaginary_sequence()
643
"""
644
self._raw = entry
645
self._id = entry[3:10]
646
self._fields = defaultdict(list)
647
for line in entry.splitlines():
648
self._fields[line[1]].append(line[11:])
649
650
def id(self, format='A'):
651
r"""
652
The ID of the sequence ``self`` is the A-number that identifies
653
``self``.
654
655
INPUT:
656
657
- ``format`` - (string, default: 'A').
658
659
OUTPUT:
660
661
- if ``format`` is set to 'A', returns a string of the form 'A000123'.
662
- if ``format`` is set to 'int' returns an integer of the form 123.
663
664
EXAMPLES::
665
666
sage: f = oeis(45) ; f # optional -- internet
667
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
668
669
sage: f.id() # optional -- internet
670
'A000045'
671
672
sage: f.id(format='int') # optional -- internet
673
45
674
675
TESTS::
676
677
sage: s = oeis._imaginary_sequence()
678
sage: s.id()
679
'A999999'
680
sage: s.id(format='int')
681
999999
682
"""
683
if format == 'A':
684
return self._id
685
elif format == 'int':
686
return Integer(self._id[1:].lstrip("0"))
687
688
def raw_entry(self):
689
r"""
690
Return the raw entry of the sequence ``self``, in the OEIS format.
691
692
OUTPUT:
693
694
- string.
695
696
EXAMPLES::
697
698
sage: f = oeis(45) ; f # optional -- internet
699
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
700
701
sage: print f.raw_entry() # optional -- internet
702
%I A000045 M0692 N0256
703
%S A000045 0,1,1,2,3,5,8,13,21,34,55,89,144,...
704
%T A000045 10946,17711,28657,46368,...
705
...
706
707
TESTS::
708
709
sage: s = oeis._imaginary_sequence()
710
sage: s.raw_entry() == oeis._imaginary_entry('sign,easy')
711
True
712
"""
713
return self._raw
714
715
def name(self):
716
r"""
717
Return the name of the sequence ``self``.
718
719
OUTPUT:
720
721
- string.
722
723
EXAMPLES::
724
725
sage: f = oeis(45) ; f # optional -- internet
726
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
727
728
sage: f.name() # optional -- internet
729
'Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.'
730
731
TESTS::
732
733
sage: s = oeis._imaginary_sequence()
734
sage: s.name()
735
'The opposite of twice the characteristic sequence of 42 plus one, starting from 38.'
736
"""
737
return self._fields['N'][0]
738
739
def old_IDs(self):
740
r"""
741
Returns the IDs of the sequence ``self`` corresponding to ancestors of OEIS.
742
743
OUTPUT:
744
745
- a tuple of at most two strings. When the string starts with `M`, it
746
corresponds to the ID of "The Encyclopedia of Integer Sequences" of
747
1995. When the string starts with `N`, it corresponds to the ID of
748
the "Handbook of Integer Sequences" of 1973.
749
750
EXAMPLES::
751
752
sage: f = oeis(45) ; f # optional -- internet
753
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
754
755
sage: f.old_IDs() # optional -- internet
756
('M0692', 'N0256')
757
758
TESTS::
759
760
sage: s = oeis._imaginary_sequence()
761
sage: s.old_IDs()
762
('M9999', 'N9999')
763
"""
764
return tuple(self._fields['I'][0].split(' '))
765
766
def offsets(self):
767
r"""
768
Return the offsets of the sequence ``self``.
769
770
The first offset is the subscript of the first term in the sequence
771
``self``. When, the sequence represents the decimal expansion of a real
772
number, it corresponds to the number of digits of its integer part.
773
774
The second offset is the first term in the sequence ``self`` (starting
775
from 1) whose absolute value is greater than 1. This is set to 1 if all
776
the terms are 0 or +-1.
777
778
OUTPUT:
779
780
- tuple of two elements.
781
782
EXAMPLES::
783
784
sage: f = oeis(45) ; f # optional -- internet
785
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
786
787
sage: f.offsets() # optional -- internet
788
(0, 4)
789
790
sage: f.first_terms()[:4] # optional -- internet
791
(0, 1, 1, 2)
792
793
TESTS::
794
795
sage: s = oeis._imaginary_sequence()
796
sage: s.offsets()
797
(38, 4)
798
"""
799
return to_tuple(self._fields['O'][0])
800
801
def author(self):
802
r"""
803
Returns the author of the sequence in the encyclopedia.
804
805
OUTPUT:
806
807
- string.
808
809
EXAMPLES::
810
811
sage: f = oeis(45) ; f # optional -- internet
812
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
813
814
sage: f.author() # optional -- internet
815
'_N. J. A. Sloane_.'
816
817
TESTS::
818
819
sage: s = oeis._imaginary_sequence()
820
sage: s.author()
821
'Anonymous.'
822
"""
823
return self._fields['A'][0]
824
825
def keywords(self):
826
r"""
827
Return the keywords associated to the sequence ``self``.
828
829
OUTPUT:
830
831
- tuple of strings.
832
833
EXAMPLES::
834
835
sage: f = oeis(45) ; f # optional -- internet
836
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
837
838
sage: f.keywords() # optional -- internet
839
('core', 'nonn', 'easy', 'nice', 'changed')
840
841
TESTS::
842
843
sage: s = oeis._imaginary_sequence()
844
sage: s.keywords()
845
('sign', 'easy')
846
847
sage: s = oeis._imaginary_sequence(keywords='nonn,hard')
848
sage: s.keywords()
849
('nonn', 'hard')
850
"""
851
return tuple(self._fields['K'][0].split(','))
852
853
def natural_object(self):
854
r"""
855
Return the natural object associated to the sequence ``self``.
856
857
OUTPUT:
858
859
- If the sequence ``self`` corresponds to the digits of a real
860
number, returns the associated real number (as an element of
861
RealLazyField()).
862
863
- If the sequence ``self`` corresponds to the convergents of a
864
continued fraction, returns the associated continued
865
fraction (as an element of ContinuedFractionField()).
866
867
.. WARNING::
868
869
This method forgets the fact that the returned sequence may not be
870
complete.
871
872
.. TODO::
873
874
- ask OEIS to add a keyword telling whether the sequence comes from
875
a power series, e.g. for http://oeis.org/A000182
876
- discover other possible conversions.
877
878
EXAMPLES::
879
880
sage: g = oeis("A002852") ; g # optional -- internet
881
A002852: Continued fraction for Euler's constant (or Euler-Mascheroni constant) gamma.
882
883
sage: x = g.natural_object() ; x.parent() # optional -- internet
884
Field of all continued fractions
885
886
sage: x[:20] == continued_fraction(euler_gamma, nterms=20) # optional -- internet
887
True
888
889
::
890
891
sage: ee = oeis('A001113') ; ee # optional -- internet
892
A001113: Decimal expansion of e.
893
894
sage: x = ee.natural_object() ; x # optional -- internet
895
2.718281828459046?
896
897
sage: x.parent() # optional -- internet
898
Real Lazy Field
899
900
sage: x == RR(e) # optional -- internet
901
True
902
903
::
904
905
sage: av = oeis('A087778') ; av # optional -- internet
906
A087778: Decimal expansion of Avogadro's constant.
907
908
sage: av.natural_object() # optional -- internet
909
6.022141000000000?e23
910
911
::
912
913
sage: fib = oeis('A000045') ; fib # optional -- internet
914
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
915
916
sage: x = fib.natural_object() ; x.parent() # optional -- internet
917
Category of sequences in Non negative integer semiring
918
919
::
920
921
sage: sfib = oeis('A039834') ; sfib # optional -- internet
922
A039834: a(n+2)=-a(n+1)+a(n) (signed Fibonacci numbers); or Fibonacci numbers (A000045) extended to negative indices.
923
924
sage: x = sfib.natural_object() ; x.parent() # optional -- internet
925
Category of sequences in Integer Ring
926
927
TESTS::
928
929
sage: s = oeis._imaginary_sequence('nonn,cofr')
930
sage: s.natural_object().parent()
931
Field of all continued fractions
932
933
sage: s = oeis._imaginary_sequence('nonn')
934
sage: s.natural_object().parent()
935
Category of sequences in Non negative integer semiring
936
937
sage: s = oeis._imaginary_sequence()
938
sage: s.natural_object().parent()
939
Category of sequences in Integer Ring
940
"""
941
if 'cofr' in self.keywords() and not 'frac' in self.keywords():
942
return ContinuedFractionField()(self.first_terms())
943
elif 'cons' in self.keywords():
944
offset = self.offsets()[0]
945
terms = self.first_terms() + tuple([0] * abs(offset))
946
return RealLazyField()('0' + ''.join(map(str, terms[:offset])) + '.' + ''.join(map(str, terms[offset:])))
947
elif 'nonn' in self.keywords():
948
return Sequence(self.first_terms(), NN)
949
else:
950
return Sequence(self.first_terms(),IntegerRing())
951
952
def is_finite(self):
953
r"""
954
Tells whether the sequence is finite.
955
956
Currently, OEIS only provides a keyword when the sequence is known to
957
be finite. So, when this keyword is not there, we do not know whether
958
it is infinite or not.
959
960
OUTPUT:
961
962
- Returns ``True`` when the sequence is known to be finite.
963
- Returns ``Unknown`` otherwise.
964
965
.. TODO::
966
967
Ask OEIS for a keyword ensuring that a sequence is infinite.
968
969
EXAMPLES::
970
971
sage: s = oeis('A114288') ; s # optional -- internet
972
A114288: Lexicographically minimal solution of any 9 X 9 sudoku, read by rows.
973
974
sage: s.is_finite() # optional -- internet
975
True
976
977
::
978
979
sage: f = oeis(45) ; f # optional -- internet
980
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
981
982
sage: f.is_finite() # optional -- internet
983
Unknown
984
985
TESTS::
986
987
sage: s = oeis._imaginary_sequence()
988
sage: s.is_finite()
989
Unknown
990
991
sage: s = oeis._imaginary_sequence('nonn,finit')
992
sage: s.is_finite()
993
True
994
995
"""
996
if 'finit' in self.keywords() or 'full' in self.keywords():
997
return True
998
else:
999
return Unknown
1000
1001
def is_full(self):
1002
r"""
1003
Tells whether the sequence ``self`` is full, that is, if all its
1004
elements are listed in ``self.first_terms()``.
1005
1006
Currently, OEIS only provides a keyword when the sequence is known to
1007
be full. So, when this keyword is not there, we do not know whether
1008
some elements are missing or not.
1009
1010
OUTPUT:
1011
1012
- Returns ``True`` when the sequence is known to be full.
1013
- Returns ``Unknown`` otherwise.
1014
1015
EXAMPLES::
1016
1017
sage: s = oeis('A114288') ; s # optional -- internet
1018
A114288: Lexicographically minimal solution of any 9 X 9 sudoku, read by rows.
1019
1020
sage: s.is_full() # optional -- internet
1021
True
1022
1023
::
1024
1025
sage: f = oeis(45) ; f # optional -- internet
1026
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
1027
1028
sage: f.is_full() # optional -- internet
1029
Unknown
1030
1031
TESTS::
1032
1033
sage: s = oeis._imaginary_sequence()
1034
sage: s.is_full()
1035
Unknown
1036
1037
sage: s = oeis._imaginary_sequence('nonn,full,finit')
1038
sage: s.is_full()
1039
True
1040
"""
1041
if 'full' in self.keywords():
1042
return True
1043
else:
1044
return Unknown
1045
1046
@cached_method
1047
def first_terms(self, number=None, absolute_value=False):
1048
r"""
1049
1050
INPUT:
1051
1052
- ``number`` - (integer or ``None``, default: ``None``) the number of
1053
terms returned (if less than the number of available terms). When set
1054
to None, returns all the known terms.
1055
1056
- ``absolute_value`` - (bool, default: ``False``) when a sequence has
1057
negative entries, OEIS also stores the absolute values of its first
1058
terms, when ``absolute_value`` is set to ``True``, you will get them.
1059
1060
OUTPUT:
1061
1062
- tuple of integers.
1063
1064
EXAMPLES::
1065
1066
sage: f = oeis(45) ; f # optional -- internet
1067
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
1068
1069
sage: f.first_terms()[:10] # optional -- internet
1070
(0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
1071
1072
TESTS::
1073
1074
sage: s = oeis._imaginary_sequence()
1075
sage: s.first_terms()
1076
(1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
1077
sage: s.first_terms(5)
1078
(1, 1, 1, 1, -1)
1079
sage: s.first_terms(5, absolute_value=True)
1080
(1, 1, 1, 1, 1)
1081
1082
sage: s = oeis._imaginary_sequence(keywords='full')
1083
sage: s(40)
1084
Traceback (most recent call last):
1085
...
1086
TypeError: You found a sign inconsistency, please contact OEIS
1087
1088
sage: s = oeis._imaginary_sequence(keywords='sign,full')
1089
sage: s(40)
1090
1
1091
1092
sage: s = oeis._imaginary_sequence(keywords='nonn,full')
1093
sage: s(42)
1094
1
1095
"""
1096
if absolute_value or ('nonn' in self.keywords()):
1097
fields = ['S','T','U']
1098
elif ('sign' in self.keywords()):
1099
fields = ['V','W','X']
1100
else:
1101
raise TypeError("You found a sign inconsistency, please contact OEIS")
1102
return to_tuple(" ".join(flatten([self._fields[a] for a in fields])))[:number]
1103
1104
def _repr_(self):
1105
r"""
1106
Prints the sequence number and a short summary of this sequence.
1107
1108
OUTPUT:
1109
1110
- string.
1111
1112
EXAMPLES::
1113
1114
sage: f = oeis(45) # optional -- internet
1115
sage: f # optional -- internet
1116
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
1117
1118
TESTS::
1119
1120
sage: s = oeis._imaginary_sequence()
1121
sage: s
1122
A999999: The opposite of twice the characteristic sequence of 42 plus one, starting from 38.
1123
"""
1124
return "%s: %s" % (self.id(), self.name())
1125
1126
def __call__(self, k):
1127
r"""
1128
Returns the element of the sequence ``self`` whith index ``k``.
1129
1130
INPUT:
1131
1132
- ``k`` - integer.
1133
1134
OUTPUT:
1135
1136
- integer.
1137
1138
.. NOTE::
1139
1140
The first index of the sequence ``self`` is not necessarily zero,
1141
it depends on the first offset of ``self``. If the sequence
1142
represents the decimal expansion of a real number, the index 0
1143
corresponds to the digit right after the decimal point.
1144
1145
EXAMPLES::
1146
1147
sage: f = oeis(45) # optional -- internet
1148
sage: f.first_terms()[:10] # optional -- internet
1149
(0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
1150
1151
sage: f(4) # optional -- internet
1152
3
1153
1154
::
1155
1156
sage: sfibo = oeis('A039834') # optional -- internet
1157
sage: sfibo.first_terms()[:10] # optional -- internet
1158
(1, 1, 0, 1, -1, 2, -3, 5, -8, 13)
1159
1160
sage: sfibo(-2) # optional -- internet
1161
1
1162
sage: sfibo(4) # optional -- internet
1163
-3
1164
sage: sfibo.offsets() # optional -- internet
1165
(-2, 6)
1166
1167
TESTS::
1168
1169
sage: s = oeis._imaginary_sequence()
1170
sage: s(38)
1171
1
1172
sage: s(42)
1173
-1
1174
sage: s(2)
1175
Traceback (most recent call last):
1176
...
1177
ValueError: Sequence A999999 is not defined (or known) for index 2
1178
"""
1179
offset = self.offsets()[0]
1180
if 'cons' in self.keywords():
1181
offset = - offset
1182
n = k - offset
1183
if not 0 <= n < len(self.first_terms()):
1184
raise ValueError("Sequence %s is not defined (or known) for index %s" % (self.id(), k))
1185
return self.first_terms()[n]
1186
1187
def __getitem__(self, i):
1188
r"""
1189
Return the ``i``th element of sequence ``self``, viewed as a tuple.
1190
1191
The first element appearing in the sequence ``self``corresponds to
1192
``self[0]``. Do not confuse with calling ``self(k)``.
1193
1194
INPUT:
1195
1196
- ``i`` - integer.
1197
1198
OUTPUT:
1199
1200
- integer.
1201
1202
EXAMPLES::
1203
1204
sage: sfibo = oeis('A039834') # optional -- internet
1205
sage: sfibo[8] # optional -- internet
1206
-8
1207
sage: sfibo(8) # optional -- internet
1208
-21
1209
1210
TESTS::
1211
1212
sage: s = oeis._imaginary_sequence()
1213
sage: s[2]
1214
1
1215
sage: s[4]
1216
-1
1217
sage: s[38]
1218
Traceback (most recent call last):
1219
...
1220
IndexError: tuple index out of range
1221
"""
1222
return self.first_terms()[i]
1223
1224
def __iter__(self):
1225
r"""
1226
Iterates over the first terms of ``self``, and raises an error if
1227
those first terms are exhausted and the real associated sequence
1228
still have terms to produce.
1229
1230
OUTPUT:
1231
1232
- integer.
1233
1234
EXAMPLES::
1235
1236
sage: p = oeis('A085823') ; p # optional -- internet
1237
A085823: Numbers in which all substrings are primes.
1238
1239
sage: for i in p: # optional -- internet
1240
....: print i
1241
2
1242
3
1243
5
1244
7
1245
23
1246
37
1247
53
1248
73
1249
373
1250
1251
::
1252
1253
sage: w = oeis(7540) ; w # optional -- internet
1254
A007540: Wilson primes: primes p such that (p-1)! == -1 (mod p^2).
1255
1256
sage: i = w.__iter__() # optional -- internet
1257
sage: i.next() # optional -- internet
1258
5
1259
sage: i.next() # optional -- internet
1260
13
1261
sage: i.next() # optional -- internet
1262
563
1263
sage: i.next() # optional -- internet
1264
Traceback (most recent call last):
1265
...
1266
LookupError: Future values not provided by OEIS.
1267
1268
::
1269
1270
sage: f = oeis(45) ; f # optional -- internet
1271
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
1272
1273
sage: for i in f: # optional -- internet
1274
....: print i
1275
Traceback (most recent call last):
1276
...
1277
LookupError: Future values not provided by OEIS.
1278
1279
TESTS::
1280
1281
sage: s = oeis._imaginary_sequence()
1282
sage: for i in s:
1283
....: pass
1284
Traceback (most recent call last):
1285
...
1286
LookupError: Future values not provided by OEIS.
1287
1288
sage: for i in s:
1289
....: if i == -1:
1290
....: print i
1291
....: break
1292
-1
1293
1294
sage: s = oeis._imaginary_sequence(keywords='sign,full')
1295
sage: for i in s: pass
1296
"""
1297
for x in self.first_terms():
1298
yield x
1299
if not self.is_full():
1300
raise LookupError("Future values not provided by OEIS.")
1301
1302
def __eq__(self,other):
1303
r"""
1304
1305
Returns ``True`` if ``self`` is equal to ``other`` and ``False``
1306
otherwise. Two integer sequences are considered equal if they have the
1307
same OEIS ID.
1308
1309
INPUT:
1310
1311
- ``other`` - an oeis sequence.
1312
1313
OUTPUT:
1314
1315
- boolean.
1316
1317
EXAMPLES::
1318
1319
sage: oeis([1,2,3,5,8,13])[0] == oeis(45) # optional -- internet
1320
True
1321
1322
TESTS::
1323
1324
sage: s = oeis._imaginary_sequence()
1325
sage: s == oeis._imaginary_sequence()
1326
True
1327
1328
"""
1329
return self.id() == other.id()
1330
1331
def __ne__(self, other):
1332
r"""
1333
1334
Returns ``True`` if ``self`` has a different OEIS ID than ``other`` and
1335
``False`` otherwise.
1336
1337
INPUT:
1338
1339
- ``other`` - an oeis sequence.
1340
1341
OUTPUT:
1342
1343
- boolean.
1344
1345
EXAMPLES::
1346
1347
sage: oeis([1,2,3,5,8,13])[0] != oeis(40) # optional -- internet
1348
True
1349
1350
TESTS::
1351
1352
sage: s = oeis._imaginary_sequence()
1353
sage: s != oeis._imaginary_sequence()
1354
False
1355
"""
1356
return not self.__eq__(other)
1357
1358
def references(self):
1359
r"""
1360
Return a tuple of references associated to the sequence ``self``.
1361
1362
OUTPUT:
1363
1364
- tuple of strings (with fancy formatting).
1365
1366
EXAMPLES::
1367
1368
sage: w = oeis(7540) ; w # optional -- internet
1369
A007540: Wilson primes: primes p such that (p-1)! == -1 (mod p^2).
1370
1371
sage: w.references() # optional -- internet
1372
0: A. H. Beiler, Recreations in the Theory of Numbers, Dover, NY, 1964, p. 52.
1373
1: C. Clawson, Mathematical Mysteries, Plenum Press, 1996, p. 180.
1374
2: Edgar Costa, Robert Gerbicz, and David Harvey, <a href="http://arxiv.org/abs/1209.3436">A search for Wilson primes</a>, 2012
1375
...
1376
1377
sage: _[0] # optional -- internet
1378
'A. H. Beiler, Recreations in the Theory of Numbers, Dover, NY, 1964, p. 52.'
1379
1380
TESTS::
1381
1382
sage: s = oeis._imaginary_sequence()
1383
sage: s.references()[1]
1384
'Lewis Carroll, The Hunting of the Snark.'
1385
"""
1386
return FancyTuple(self._fields['D'])
1387
1388
def links(self, browse=None, format='guess'):
1389
r"""
1390
Return, display or browse links associated to the sequence ``self``.
1391
1392
INPUT:
1393
1394
- ``browse`` - an integer, a list of integers, or the word 'all'
1395
(default: ``None``) : which links to open in a web browser.
1396
1397
- ``format`` - string (default: 'guess') : how to display the links.
1398
1399
OUTPUT:
1400
1401
- tuple of strings (with fancy formatting):
1402
- if ``format`` is ``url``, returns a tuple of absolute links without description.
1403
- if ``format`` is ``html``, returns nothing but prints a tuple of clickable absolute links in their context.
1404
- if ``format`` is ``guess``, adapts the output to the context (command line or notebook).
1405
- if ``format`` is ``raw``, the links as they appear in the database, relative links are not made absolute.
1406
1407
EXAMPLES::
1408
1409
sage: f = oeis(45) ; f # optional -- internet
1410
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
1411
1412
sage: f.links(format='url') # optional -- internet
1413
0: http://oeis.org/A000045/b000045.txt
1414
1: http://www.schoolnet.ca/vp-pv/amof/e_fiboI.htm
1415
...
1416
1417
sage: f.links(format='raw') # optional -- internet
1418
0: N. J. A. Sloane, <a href="/A000045/b000045.txt">The first 2000 Fibonacci numbers: Table of n, F(n) for n = 0..2000</a>
1419
1: Amazing Mathematical Object Factory, <a href="http://www.schoolnet.ca/vp-pv/amof/e_fiboI.htm">Information on the Fibonacci sequences</a>
1420
...
1421
1422
TESTS::
1423
1424
sage: s = oeis._imaginary_sequence()
1425
sage: s.links(format='raw')[2]
1426
'Do not confuse with the sequence <a href="/A000042">A000042</a> or the sequence <a href="/A000024">A000024</a>'
1427
1428
sage: s.links(format='url')[3]
1429
'http://oeis.org/A000024'
1430
1431
sage: s.links(format="html")
1432
<html><font color='black'>0: Wikipedia, <a href="http://en.wikipedia.org/wiki/42_(number)">42 (number)</a>
1433
1: See. also <a href="http://trac.sagemath.org/sage_trac/ticket/42">trac ticket #42</a>
1434
...
1435
"""
1436
url_absolute = lambda s: re.sub('\"\/', '\"' + oeis_url, s)
1437
if browse is None:
1438
if format == 'guess':
1439
if embedded():
1440
return self.links(format='html')
1441
else:
1442
return self.links(format='url')
1443
elif format == 'raw':
1444
return FancyTuple(self._fields['H'])
1445
elif format == 'html':
1446
html(FancyTuple(map(url_absolute, self._fields['H'])))
1447
elif format == 'url':
1448
url_list = flatten([_urls(url_absolute(string)) for string in self._fields['H']])
1449
return FancyTuple(url_list)
1450
else:
1451
import webbrowser
1452
url_list = flatten([_urls(url_absolute(string)) for string in self._fields['H']])
1453
if isinstance(browse, (int, Integer)):
1454
webbrowser.open(url_list[browse])
1455
elif isinstance(browse, (list, tuple)):
1456
for url_number in browse:
1457
webbrowser.open(url_list[url_number])
1458
elif browse == 'all':
1459
for url in url_list:
1460
webbrowser.open(url)
1461
1462
def formulas(self):
1463
r"""
1464
Return a tuple of formulas associated to the sequence ``self``.
1465
1466
OUTPUT:
1467
1468
- tuple of strings (with fancy formatting).
1469
1470
EXAMPLES::
1471
1472
sage: f = oeis(45) ; f # optional -- internet
1473
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
1474
1475
sage: f.formulas()[1] # optional -- internet
1476
'F(n) = ((1+sqrt(5))^n-(1-sqrt(5))^n)/(2^n*sqrt(5)).'
1477
1478
TESTS::
1479
1480
sage: s = oeis._imaginary_sequence()
1481
sage: s.formulas()
1482
0: For n big enough, s(n+1) - s(n) = 0.
1483
1484
"""
1485
return FancyTuple(self._fields['F'])
1486
1487
def cross_references(self, fetch=False):
1488
r"""
1489
Return a tuple of cross references associated to the sequence
1490
``self``.
1491
1492
INPUT:
1493
1494
- ``fetch`` - boolean (default: ``False``).
1495
1496
OUTPUT:
1497
1498
- if ``fetch`` is ``False``, return a list of OEIS IDs (strings).
1499
- if ``fetch`` if ``True``, return a tuple of OEIS sequences.
1500
1501
EXAMPLES::
1502
1503
sage: nbalanced = oeis("A005598") ; nbalanced # optional -- internet
1504
A005598: a(n)=1+sum((n-i+1)*phi(i),i=1..n).
1505
1506
sage: nbalanced.cross_references() # optional -- internet
1507
('A049703', 'A049695', 'A103116', 'A000010')
1508
1509
sage: nbalanced.cross_references(fetch=True) # optional -- internet
1510
0: A049703: a(0) = 0; for n>0, a(n) = A005598(n)/2.
1511
1: A049695: Array T read by diagonals; T(i,j)=number of nonnegative slopes of lines determined by 2 lattice points in [ 0,i ] X [ 0,j ] if i>0; T(0,j)=1 if j>0; T(0,0)=0.
1512
2: A103116: A005598(n) - 1.
1513
3: A000010: Euler totient function phi(n): count numbers <= n and prime to n.
1514
1515
sage: phi = _[3] # optional -- internet
1516
1517
TESTS::
1518
1519
sage: s = oeis._imaginary_sequence()
1520
sage: s.cross_references()
1521
('A000042', 'A000024')
1522
"""
1523
ref_list = re.findall('A[0-9]{6}', " ".join(self._fields['Y']))
1524
if fetch:
1525
return FancyTuple(map(oeis.find_by_id, ref_list))
1526
else:
1527
return tuple(ref_list)
1528
1529
def extensions_or_errors(self):
1530
r"""
1531
Return a tuple of extensions or errors associated to the
1532
sequence ``self``.
1533
1534
OUTPUT:
1535
1536
- tuple of strings (with fancy formatting).
1537
1538
EXAMPLES::
1539
1540
sage: sfibo = oeis('A039834') ; sfibo # optional -- internet
1541
A039834: a(n+2)=-a(n+1)+a(n) (signed Fibonacci numbers); or Fibonacci numbers (A000045) extended to negative indices.
1542
1543
sage: sfibo.extensions_or_errors()[0] # optional -- internet
1544
'Signs corrected by Len Smiley (smiley(AT)math.uaa.alaska.edu) and _N. J. A. Sloane_.'
1545
1546
TESTS::
1547
1548
sage: s = oeis._imaginary_sequence()
1549
sage: s.extensions_or_errors()
1550
0: This sequence does not contain errors.
1551
1552
"""
1553
return FancyTuple(self._fields['E'])
1554
1555
def examples(self):
1556
r"""
1557
Return a tuple of examples associated to the sequence ``self``.
1558
1559
OUTPUT:
1560
1561
- tuple of strings (with fancy formatting).
1562
1563
EXAMPLES::
1564
1565
sage: c = oeis(1203) ; c # optional -- internet
1566
A001203: Continued fraction expansion of Pi.
1567
1568
sage: c.examples() # optional -- internet
1569
0: Pi = 3.1415926535897932384...
1570
1: = 3 + 1/(7 + 1/(15 + 1/(1 + 1/(292 + ...))))
1571
2: = [a_0; a_1, a_2, a_3, ...] = [3; 7, 15, 292, ...]
1572
1573
TESTS::
1574
1575
sage: s = oeis._imaginary_sequence()
1576
sage: s.examples()
1577
0: s(42) + s(43) = 0.
1578
"""
1579
return FancyTuple(self._fields['e'])
1580
1581
def comments(self):
1582
r"""
1583
Return a tuple of comments associated to the sequence ``self``.
1584
1585
OUTPUT:
1586
1587
- tuple of strings (with fancy formatting).
1588
1589
EXAMPLES::
1590
1591
sage: f = oeis(45) ; f # optional -- internet
1592
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
1593
1594
sage: f.comments()[:3] # optional -- internet
1595
("Also called Lam{\\'e}'s sequence.",
1596
"F(n+2) = number of binary sequences of length n that have no consecutive 0's.",
1597
'F(n+2) = number of subsets of {1,2,...,n} that contain no consecutive integers.')
1598
1599
TESTS::
1600
1601
sage: s = oeis._imaginary_sequence()
1602
sage: s.comments()
1603
0: 42 is the product of the first 4 prime numbers, except 5 and perhaps 1.
1604
1: Apart from that, i have no comment.
1605
"""
1606
return FancyTuple(self._fields['C'])
1607
1608
def url(self):
1609
r"""
1610
Return the URL of the page associated to the sequence ``self``.
1611
1612
OUTPUT:
1613
1614
- string.
1615
1616
EXAMPLES::
1617
1618
sage: f = oeis(45) ; f # optional -- internet
1619
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
1620
1621
sage: f.url() # optional -- internet
1622
'http://oeis.org/A000045'
1623
1624
TESTS::
1625
1626
sage: s = oeis._imaginary_sequence()
1627
sage: s.url()
1628
'http://oeis.org/A999999'
1629
"""
1630
return oeis_url + self.id()
1631
1632
def browse(self):
1633
r"""
1634
Open the OEIS web page associated to the sequence ``self`` in a browser.
1635
1636
EXAMPLES::
1637
1638
sage: f = oeis(45) ; f # optional -- internet, webbrowser
1639
A000045: Fibonacci numbers: F(n) = F(n-1) + F(n-2) with F(0) = 0 and F(1) = 1.
1640
1641
sage: f.browse() # optional -- internet, webbrowser
1642
1643
TESTS::
1644
1645
sage: s = oeis._imaginary_sequence() # optional -- webbrowser
1646
sage: s.browse() # optional -- webbrowser
1647
"""
1648
import webbrowser
1649
webbrowser.open(self.url())
1650
1651
def show(self):
1652
r"""
1653
Display most available informations about the sequence ``self``.
1654
1655
EXAMPLES::
1656
1657
sage: s = oeis(12345) # optional -- internet
1658
sage: s.show() # optional -- internet
1659
ID
1660
A012345
1661
<BLANKLINE>
1662
NAME
1663
sinh(arcsin(x)*arcsin(x))=2/2!*x^2+8/4!*x^4+248/6!*x^6+11328/8!*x^8...
1664
<BLANKLINE>
1665
FIRST TERMS
1666
(2, 8, 248, 11328, 849312, 94857600, 14819214720, 3091936512000, ...
1667
<BLANKLINE>
1668
KEYWORDS
1669
('nonn',)
1670
<BLANKLINE>
1671
OFFSETS
1672
(0, 1)
1673
URL
1674
http://oeis.org/A012345
1675
<BLANKLINE>
1676
AUTHOR
1677
Patrick Demichel (patrick.demichel(AT)hp.com)
1678
<BLANKLINE>
1679
1680
TESTS::
1681
1682
sage: s = oeis._imaginary_sequence()
1683
sage: s.show()
1684
ID
1685
A999999
1686
<BLANKLINE>
1687
NAME
1688
The opposite of twice the characteristic sequence of 42 plus ...
1689
FIRST TERMS
1690
(1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
1691
<BLANKLINE>
1692
COMMENTS
1693
0: 42 is the product of the first 4 prime numbers, except ...
1694
1: Apart from that, i have no comment.
1695
...
1696
"""
1697
for s in ['id', 'name', 'first_terms', 'comments', 'references',
1698
'links', 'formulas', 'examples', 'cross_references',
1699
'programs', 'keywords', 'offsets', 'url', 'old_IDs',
1700
'author', 'extensions_or_errors']:
1701
if embedded() and s == 'links':
1702
print re.sub('_',' ',s).upper()
1703
getattr(self, s)()
1704
print '\n'
1705
else:
1706
result = getattr(self, s)()
1707
if result != '' and result != ('',) and result != ():
1708
print re.sub('_',' ',s).upper()
1709
print str(result) + '\n'
1710
1711
def programs(self, language='other'):
1712
r"""
1713
Returns programs implementing the sequence ``self`` in the given ``language``.
1714
1715
INPUT:
1716
1717
- ``language`` - string (default: 'other') - the language of the
1718
program. Current values are: 'maple', 'mathematica' and 'other'.
1719
1720
OUTPUT:
1721
1722
- tuple of strings (with fancy formatting).
1723
1724
.. TODO:: ask OEIS to add a "Sage program" field in the database ;)
1725
1726
EXAMPLES::
1727
1728
sage: ee = oeis('A001113') ; ee # optional -- internet
1729
A001113: Decimal expansion of e.
1730
1731
sage: ee.programs()[0] # optional -- internet
1732
'(PARI) { default(realprecision, 50080); x=exp(1); for (n=1, 50000, d=floor(x); x=(x-d)*10; write("b001113.txt", n, " ", d)); } [From Harry J. Smith, Apr 15 2009]'
1733
1734
TESTS::
1735
1736
sage: s = oeis._imaginary_sequence()
1737
sage: s.programs()
1738
0: (Python)
1739
1: def A999999(n):
1740
2: assert(isinstance(n, (int, Integer))), "n must be an integer."
1741
3: if n < 38:
1742
4: raise ValueError("The value %s is not accepted." %str(n)))
1743
5: elif n == 42:
1744
6: return -1
1745
7: else:
1746
8: return 1
1747
1748
sage: s.programs('maple')
1749
0: Do not even try, Maple is not able to produce such a sequence.
1750
1751
sage: s.programs('mathematica')
1752
0: Mathematica neither.
1753
"""
1754
if language == "maple":
1755
return FancyTuple(self._fields['p'])
1756
elif language == "mathematica":
1757
return FancyTuple(self._fields['t'])
1758
else:
1759
return FancyTuple(self._fields['o'])
1760
1761
class FancyTuple(tuple):
1762
r"""
1763
This class inherits from ``tuple``, it allows to nicely print tuples whose
1764
elements have a one line representation.
1765
1766
EXAMPLES::
1767
1768
sage: from sage.databases.oeis import FancyTuple
1769
sage: t = FancyTuple(['zero', 'one', 'two', 'three', 4]) ; t
1770
0: zero
1771
1: one
1772
2: two
1773
3: three
1774
4: 4
1775
1776
sage: t[2]
1777
'two'
1778
"""
1779
def __repr__(self):
1780
r"""
1781
Prints the tuple with one value per line, each line begins with the
1782
index of the value in ``self``.
1783
1784
EXAMPLES::
1785
sage: from sage.databases.oeis import FancyTuple
1786
sage: t = FancyTuple(['zero', 'one', 'two', 'three', 4]) ; t
1787
0: zero
1788
1: one
1789
2: two
1790
3: three
1791
4: 4
1792
"""
1793
length = len(str(len(self)-1))
1794
return '\n'.join(map(lambda i: ('{0:>%d}' % length).format(str(i)) + ': ' + str(self[i]),
1795
range(len(self))))
1796
1797
oeis = OEIS()
1798
1799
1800