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.DifferenceDefinableSequenceA 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– aC2FiniteSequenceRingcoefficients– 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.FunctionalEquationand 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.DifferenceDefinableSequenceRingA 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:
xis already a \(C^2\)-finite sequence.xis a list of C-finite sequences andyis a list of field elements. Thenxis interpreted as the coefficients of the recurrence andyas the initial values of the sequence, i.e. \(a(0), ..., a(r-1)\).xis a C-finite sequence.xcan 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; ifTruea 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
ValueErroris 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