C2FiniteSequence
and C2FiniteSequenceRing
Ring of \(C^2\)-finite sequences
Sublasses rec_sequences.DifferenceDefinableSequenceRing
and
defines sequences satisfying a linear
recurrence equation with coefficients which are C-finite sequence.
Such a \(C^2\)-finite sequence \(a(n)\) is defined by a recurrence
with \(c_r(n) \neq 0\) for all \(n\) and initial values \(a(0),...,a(r-1)\). This is based on the theory and algorithms developed in [JPNP21a] and [JPNP21b].
EXAMPLES:
sage: from rec_sequences.C2FiniteSequenceRing import *
sage: from rec_sequences.CFiniteSequenceRing import *
sage: C = CFiniteSequenceRing(QQ)
sage: C2 = C2FiniteSequenceRing(QQ)
sage: n = var("n")
sage: c = C(2^n+1)
sage: a = C2([c, -1], [3])
sage: a[:10]
[3, 6, 18, 90, 810, 13770, 454410, 29536650, 3810227850, 979228557450]
sage: f = C([1,1, -1], [0,1]) # define fibonacci numbers
sage: l = C([1,1,-1], [2,1]) # define lucas numbers
sage: f_fac = f.factorial(C2) # define fibonorials
sage: f_fac
C^2-finite sequence of order 1 and degree 2 with coefficients:
> c0 (n) : C-finite sequence c0(n): (1)*c0(n) + (1)*c0(n+1) + (-1)*c0(n+2) = 0 and c0(0)=1 , c0(1)=1
> c1 (n) : C-finite sequence c1(n)=-1
and initial values a(0)=1
sage: f_fac[:10]
[1, 1, 1, 2, 6, 30, 240, 3120, 65520, 2227680]
sage: a_plus_f = a+f_fac
sage: a_plus_f.order(), a_plus_f.degree()
(2, 25)
sage: a_plus_f[:10]
[4, 7, 19, 92, 816, 13800, 454650, 29539770, 3810293370, 979230785130]
sage: l_sparse = l.sparse_subsequence(C2) # define l(n^2)
sage: l_sparse[:8]
[2, 1, 7, 76, 2207, 167761, 33385282, 17393796001]
sage: f_times_l = f_fac * l_sparse # long time
sage: f_times_l.order(), f_times_l.degree() # long time
(2, 15)
sage: f_times_l[:5] # long time
[2, 1, 7, 152, 13242]
- class rec_sequences.C2FiniteSequenceRing.C2FiniteSequence(parent, coefficients, initial_values, name='a', is_gen=False, construct=False, cache=True, *args, **kwds)
Bases:
rec_sequences.DifferenceDefinableSequenceRing.DifferenceDefinableSequence
A C^2-finite sequence, i.e. a sequence where every term can be determined by a linear recurrence with coefficients coming from a C-finite sequence ring and finitely many initial values. We assume that this recurrence holds for all values and that the leading coefficient is non-zero for all n (this is not checked).
- __init__(parent, coefficients, initial_values, name='a', is_gen=False, construct=False, cache=True, *args, **kwds)
Construct a \(C^2\)-finite sequence \(a(n)\) with recurrence
\[c_0(n) a(n) + \dots + c_r(n) a(n+r) = 0 \text{ for all } n \geq 0\]from given list of coefficients \(c_0, ... , c_r\) and given list of initial values \(a(0), ..., a(r-1)\).
Note
We assume that the leading coefficient \(c_r\) does not contain any zero terms. If it does, this might yield problems in later computations.
INPUT:
parent
– aC2FiniteSequenceRing
coefficients
– the coefficients of the recurrenceinitial_values
– a list of initial values, determining the sequence with at least order of the recurrence many valuesname
(default “a”) – a name for the sequence
OUTPUT:
A sequence determined by the given recurrence and initial values.
EXAMPLES:
sage: from rec_sequences.C2FiniteSequenceRing import * sage: from rec_sequences.CFiniteSequenceRing import * sage: C = CFiniteSequenceRing(QQ) sage: C2 = C2FiniteSequenceRing(QQ) sage: n = var("n") sage: c = C(2^n+1) sage: a = C2([c, -1], [3]) sage: a C^2-finite sequence of order 1 and degree 2 with coefficients: > c0 (n) : C-finite sequence c0(n): (2)*c0(n) + (-3)*c0(n+1) + (1)*c0(n+2) = 0 and c0(0)=2 , c0(1)=3 > c1 (n) : C-finite sequence c1(n)=-1 and initial values a(0)=3
- _latex_(name=None)
Creates a latex representation of the sequence. This is done by creating the latex representation of the closed forms of the coefficients and showing the recurrence and the initial values.
OUTPUT:
A latex representation showing the closed form of the sequence.
EXAMPLES:
sage: from rec_sequences.C2FiniteSequenceRing import * sage: from rec_sequences.CFiniteSequenceRing import * sage: C = CFiniteSequenceRing(QQ) sage: C2 = C2FiniteSequenceRing(QQ) sage: n = var("n") sage: c = C(2^n+1) sage: d = C(3^n) sage: a = C2([c, d], [1]) sage: print(latex(a)) \left(2^{n} + 1\right)\cdot a(n) + \left(3^{n}\right) \cdot a(n+1) = 0 \quad a(0)=1
- _repr_(name=None)
Produces a string representation of the sequence.
INPUT:
name
(optional) – a string used as the name of the sequence; if not given,self.name()
is used.
OUTPUT:
A string representation of the sequence consisting of the recurrence and enough initial values to uniquely define the sequence.
EXAMPLES:
sage: from rec_sequences.C2FiniteSequenceRing import * sage: from rec_sequences.CFiniteSequenceRing import * sage: C = CFiniteSequenceRing(QQ) sage: C2 = C2FiniteSequenceRing(QQ) sage: n = var("n") sage: c = C(2^n) sage: a = C2([c, -1], [1]) sage: a C^2-finite sequence of order 1 and degree 1 with coefficients: > c0 (n) : C-finite sequence c0(n): (2)*c0(n) + (-1)*c0(n+1) = 0 and c0(0)=1 > c1 (n) : C-finite sequence c1(n)=-1 and initial values a(0)=1
- functional_equation()
Computes the functional equation corresponding to the sequence. This functional equation is given as object of type
rec_sequences.FunctionalEquation
and represents a functional equation of the form\[\sum_{k=1}^m \alpha_k x^{j_k} g^{(d_k)} (\lambda_k x) = p(x)\]for constants \(\alpha_k, \lambda_k\), natural numbers \(j_k, d_k\) and a polynomial \(p(x)\) where \(g\) denotes the generating function of the sequence.
OUTPUT:
A functional equation for the generating function of the sequence.
EXAMPLES:
sage: from rec_sequences.C2FiniteSequenceRing import * sage: from rec_sequences.CFiniteSequenceRing import * sage: C = CFiniteSequenceRing(QQ) sage: C2 = C2FiniteSequenceRing(QQ) sage: n = var("n") sage: c = C(2^n+1) sage: d = C(3^n) sage: a = C2([c, d], [1]) sage: print(a.functional_equation()) (x)g(2x) + (x)g(x) + (1/3)g(3x) = 1/3
- log = <Logger C2Fin (WARNING)>
- class rec_sequences.C2FiniteSequenceRing.C2FiniteSequenceRing(base_ring, name=None, element_class=None, category=None, *args, **kwds)
Bases:
rec_sequences.DifferenceDefinableSequenceRing.DifferenceDefinableSequenceRing
A Ring of C^2-finite sequences.
- Element
alias of
rec_sequences.C2FiniteSequenceRing.C2FiniteSequence
- __init__(base_ring, name=None, element_class=None, category=None, *args, **kwds)
Constructor for a \(C^2\)-finite sequence ring.
INPUT:
field
(default:QQ
) – a field of characteristic zero over which the \(C^2\)-finite sequence ring is defined.
OUTPUT:
A ring of \(C^2\)-finite sequences
EXAMPLES:
sage: from rec_sequences.C2FiniteSequenceRing import * sage: C2FiniteSequenceRing(QQ) Ring of C^2-finite sequences with base field Rational Field
- _element_constructor_(x, y=None, name='a', check=True, is_gen=False, construct=False, *args, **kwds)
Tries to construct a sequence \(a(n)\).
This is possible if:
x
is already a \(C^2\)-finite sequence.x
is a list of C-finite sequences andy
is a list of field elements. Thenx
is interpreted as the coefficients of the recurrence andy
as the initial values of the sequence, i.e. \(a(0), ..., a(r-1)\).x
is a C-finite sequence.x
can be converted into a field element. Then it is interpreted as the constant sequence \((x)_{n \in \mathbb{N}}\)
EXAMPLES:
sage: from rec_sequences.C2FiniteSequenceRing import * sage: from rec_sequences.CFiniteSequenceRing import * sage: C = CFiniteSequenceRing(QQ) sage: C2 = C2FiniteSequenceRing(QQ) sage: n = var("n") sage: c = C(2^n+(-1)^n) sage: d = C(2^n+1) sage: a = C2([c,-d], [1], name="a") sage: print(latex(a)) \left(2^{n} + \left(-1\right)^{n}\right)\cdot a(n) + \left(-2^{n} - 1\right) \cdot a(n+1) = 0 \quad a(0)=1 sage: a2 = C2(a) sage: b = C2(c) sage: print(b) C^2-finite sequence of order 2 and degree 1 with coefficients: > c0 (n) : C-finite sequence c0(n)=2 > c1 (n) : C-finite sequence c1(n)=1 > c2 (n) : C-finite sequence c2(n)=-1 and initial values a(0)=2 , a(1)=1
- _latex_()
OUTPUT:
A latex representation of the sequence ring.
EXAMPLES:
sage: from rec_sequences.C2FiniteSequenceRing import * sage: print(latex(C2FiniteSequenceRing(QQ))) \mathcal{C^2}(\Bold{Q})
- _repr_()
OUTPUT:
A string representation of the sequence ring.
EXAMPLES:
sage: from rec_sequences.C2FiniteSequenceRing import * sage: C2FiniteSequenceRing(QQ) Ring of C^2-finite sequences with base field Rational Field
- guess(data, zeros, order_bound=2, degree_bound=0, ensure=1, simple=False)
Given a list of terms \(a(0), a(1), a(2), \dots\), try to guess a \(C^2\)-finite recurrence
\[c_0(n) a(n) + \dots + c_r(n) a(n+r) = 0 \text{ for all } n \geq 0\]satisfied by these terms. The eigenvalues of the coefficient sequences \(c_i\) are chosen among the given values
zeros
.Note
We assume that the base field is big enough to also contain the zeros of the characteristic polynomials of the coefficient sequences.
INPUT:
data
– a list of elements in the base field of the ring used for guessingzeros
– a list of elements in the base field of the ring used for the roots of the coefficient sequencesorder_bound
(default:2
) – a natural number, the bound on the order \(r\) of the recurrencedegree_bound
(default:0
) – a natural number, the maximal multiplicity of the given roots in the coefficient polynomials.ensure
(default:1
) – a natural number, the number of excess equations used for the linear system; the larger this value the more confident one can be about the result.simple
(default:False
) – a boolean; ifTrue
a simple \(C^2\)-finite recurrence (i.e., a recurrence with leading coefficient1
) is guessed.
OUTPUT:
A \(C^2\)-finite sequence with the given initial values \(a(0),a(1), \dots\). If no \(C^2\)-finite recurrence could be found, a
ValueError
is raised.EXAMPLES:
sage: from rec_sequences.C2FiniteSequenceRing import * sage: C2 = C2FiniteSequenceRing(QQ) sage: zeros = [1,2,4] sage: data = [2^(n^2) for n in range(100)] sage: a = C2.guess(data, zeros) sage: a[:100] == data True sage: data2 = [n^2*2^(n^2) for n in range(100)] sage: C2.guess(data2, zeros) Traceback (most recent call last): ... ValueError: No recurrence found. sage: a2 = C2.guess(data2, zeros, degree_bound=2) sage: a2.degree() 3 sage: # guess recurrence for f(n^2) sage: from itertools import * sage: K.<a> = NumberField(x^2-5) sage: CK = CFiniteSequenceRing(K) sage: CCK = C2FiniteSequenceRing(K) sage: zeros = set([1,(1+a)/2,(1-a)/2]) sage: all_zeros = zeros sage: for comb in combinations_with_replacement(zeros, 4) : ....: all_zeros.add(mul(comb)) sage: f = CK([1,1,-1],[0,1]) sage: data = [f[n^2] for n in range(100)] sage: f2 = CCK.guess(data, all_zeros) # long time sage: f2[:100] == data # long time True sage: f2_simple = CCK.guess(data, all_zeros, 3, 0, True) # long time sage: f2_simple[:100] == data # long time True