Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/matrix/berlekamp_massey.py
4097 views
1
"""
2
Minimal Polynomials of Linear Recurrence Sequences
3
4
AUTHORS:
5
6
- William Stein
7
"""
8
9
10
#*****************************************************************************
11
# Copyright (C) 2005 William Stein <[email protected]>
12
#
13
# Distributed under the terms of the GNU General Public License (GPL)
14
#
15
# This code is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
# General Public License for more details.
19
#
20
# The full text of the GPL is available at:
21
#
22
# http://www.gnu.org/licenses/
23
#*****************************************************************************
24
25
import sage.rings.rational_field
26
27
def berlekamp_massey(a):
28
"""
29
Use the Berlekamp-Massey algorithm to find the minimal polynomial
30
of a linearly recurrence sequence a.
31
32
The minimal polynomial of a linear recurrence `\{a_r\}` is
33
by definition the unique monic polynomial `g`, such that if
34
`\{a_r\}` satisfies a linear recurrence
35
`a_{j+k} + b_{j-1} a_{j-1+k} + \cdots + b_0 a_k=0`
36
(for all `k\geq 0`), then `g` divides the
37
polynomial `x^j + \sum_{i=0}^{j-1} b_i x^i`.
38
39
INPUT:
40
41
42
- ``a`` - a list of even length of elements of a field
43
(or domain)
44
45
46
OUTPUT:
47
48
49
- ``Polynomial`` - the minimal polynomial of the
50
sequence (as a polynomial over the field in which the entries of a
51
live)
52
53
54
EXAMPLES::
55
56
sage: berlekamp_massey([1,2,1,2,1,2])
57
x^2 - 1
58
sage: berlekamp_massey([GF(7)(1),19,1,19])
59
x^2 + 6
60
sage: berlekamp_massey([2,2,1,2,1,191,393,132])
61
x^4 - 36727/11711*x^3 + 34213/5019*x^2 + 7024942/35133*x - 335813/1673
62
sage: berlekamp_massey(prime_range(2,38))
63
x^6 - 14/9*x^5 - 7/9*x^4 + 157/54*x^3 - 25/27*x^2 - 73/18*x + 37/9
64
"""
65
66
if not isinstance(a, list):
67
raise TypeError, "Argument 1 must be a list."
68
if len(a)%2 != 0:
69
raise ValueError, "Argument 1 must have an even number of terms."
70
71
M = len(a)//2
72
73
try:
74
K = a[0].parent().fraction_field()
75
except AttributeError:
76
K = sage.rings.rational_field.RationalField()
77
R = K['x']
78
x = R.gen()
79
80
f = {}
81
q = {}
82
s = {}
83
t = {}
84
f[-1] = R(a)
85
f[0] = x**(2*M)
86
s[-1] = 1
87
t[0] = 1
88
s[0] = 0
89
t[-1] = 0
90
j = 0
91
while f[j].degree() >= M:
92
j += 1
93
q[j], f[j] = f[j-2].quo_rem(f[j-1])
94
# assert q[j]*f[j-1] + f[j] == f[j-2], "poly divide failed."
95
s[j] = s[j-2] - q[j]*s[j-1]
96
t[j] = t[j-2] - q[j]*t[j-1]
97
t = s[j].reverse()
98
f = ~(t[t.degree()]) * t # make monic (~ is inverse in python)
99
return f
100
101
102