Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
add, sub functions
Browse files Browse the repository at this point in the history
  • Loading branch information
rwst committed Apr 15, 2014
1 parent b39485b commit cc2b400
Showing 1 changed file with 80 additions and 43 deletions.
123 changes: 80 additions & 43 deletions src/sage/rings/cfinite_sequence.py
Expand Up @@ -58,12 +58,6 @@
sage: s = CFiniteSequence.from_recurrence([1,1],[0,0,0,1,1])
sage: r == s
True
sage: r = CFiniteSequence(1/(1-2*x))
sage: r[0:5]
[1, 2, 4, 8, 16]
sage: s = CFiniteSequence.from_recurrence([1],[1])
sage: (r + s)[0:5] # not tested
[2, 3, 5, 9, 17] # a(n) = 2^n + 1
SEEALSO:
:func:`fibonacci`, :class:`BinaryRecurrenceSequence`
Expand Down Expand Up @@ -104,7 +98,6 @@
from sage.rings.power_series_ring import PowerSeriesRing

from sage.matrix.berlekamp_massey import berlekamp_massey
from sage.misc.prandom import randint

class CFiniteSequence(FractionFieldElement):

Expand Down Expand Up @@ -251,6 +244,42 @@ def __repr__(self):
else:
return 'C-finite sequence, generated by ' + str(self.ogf())

def _add_(self, other):
"""
Addition of C-finite sequences.
EXAMPLES::
sage: R.<x> = ZZ[]
sage: r = CFiniteSequence(1/(1-2*x))
sage: r[0:5] # a(n) = 2^n
[1, 2, 4, 8, 16]
sage: s = CFiniteSequence.from_recurrence([1],[1])
sage: (r + s)[0:5] # a(n) = 2^n + 1
[2, 3, 5, 9, 17]
sage: r + 0 == r
True
sage: (r + x^2)[0:5]
[1, 2, 5, 8, 16]
sage: (r + 3/x)[-1]
3
"""

return CFiniteSequence(self.ogf() + other.numerator()/other.denominator())

def _sub_(self, other):
"""
Subtraction of C-finite sequences.
EXAMPLES::
sage: R.<x> = ZZ[]
sage: r = CFiniteSequence(1/(1-2*x))
sage: r[0:5] # a(n) = 2^n
[1, 2, 4, 8, 16]
"""
return CFiniteSequence(self.ogf() - other.numerator()/other.denominator())

def coefficients(self):
"""
Return the coefficients of the recurrence representation of the C-finite sequence.
Expand All @@ -269,39 +298,6 @@ def coefficients(self):

return self._c

def recurrence_repr(self):
"""
Return a string with the recurrence representation of the C-finite sequence.
OUTPUT:
- A CFiniteSequence object
EXAMPLES::
sage: R.<x> = ZZ[]
sage: CFiniteSequence((2-x)/(1-x-x^2)).recurrence_repr()
'Homogenous linear recurrence with constant coefficients of degree 2: a(n+2) = 1*a(n) + 1*a(n+1), starting a(0...) = [2, 1]'
sage: CFiniteSequence(x/(1-x)^3).recurrence_repr()
'Homogenous linear recurrence with constant coefficients of degree 3: a(n+3) = 3*a(n) - 3*a(n+1) + 1*a(n+2), starting a(1...) = [1, 3, 6]'
sage: CFiniteSequence(R(1)).recurrence_repr()
'Finite sequence [1], offset 0'
"""

if self._deg == 0:
return 'Finite sequence ' + str(self._a) + ', offset ' + str(self._off)
else:
cstr = 'a(n+' + str(self._deg) + ') = ' + str(self._c[0]) + '*a(n)'
for i in range(1, self._deg):
if self._c[i] < 0:
cstr = cstr + ' - ' + str(-(self._c[i])) + '*a(n+' + str(i) + ')'
elif self._c[i] > 0:
cstr = cstr + ' + ' + str(self._c[i]) + '*a(n+' + str(i) + ')'
else:
cstr = cstr + ' + ' + str(self._c[i]) + '*a(n+' + str(i) + ')'
astr = ', starting a(' + str(self._off) + '...) = ' + str(self._a)
return 'Homogenous linear recurrence with constant coefficients of degree ' + str(self._deg) + ': ' + cstr + astr

def __eq__(self, other):
"""
Compare two CFiniteSequences.
Expand Down Expand Up @@ -355,6 +351,11 @@ def __getitem__(self, key) :
[1, 0, -2, 0]
sage: r[-1:4] # not tested, python will not allow this!
[0, 1, 0 -2, 0]
sage: r = CFiniteSequence((-2*x^3 + x^2 + 1)/(-2*x + 1))
sage: r[0:5] # handle ogf > 1
[1, 2, 5, 8, 16]
sage: r[-2]
0
"""

if isinstance(key, slice):
Expand All @@ -369,29 +370,65 @@ def __getitem__(self, key) :
return self._a[key - self._off]
else:
return 0
quo = self.numerator().quo_rem(self.denominator())[0]
wp = quo[key - self._off]

A = Matrix(QQ, 1, d, self._c)
B = Matrix.identity(QQ, d - 1)
C = Matrix(QQ, d - 1, 1, 0)
V = Matrix(QQ, d, 1, self._a[:d][::-1])
M = Matrix.block([[A], [B, C]], subdivide=False)
return list(M ** (key - self._off) * V)[d-1][0]
return wp + list(M ** (key - self._off) * V)[d-1][0]
else:
raise TypeError, "Invalid argument type."

def ogf(self):
"""
Return the ordinary generating function associated with the CFiniteSequence.
This is always a polynomial fraction.
This is always a fraction of polynomials in the base ring.
EXAMPLES::
sage: R = CFiniteSequence.from_recurrence([2],[1]) # powers of 2
sage: R = CFiniteSequence.from_recurrence([2],[1])
sage: R.ogf()
1/(-2*x + 1)
"""

return (self.numerator().parent().gen())**self._off * self.numerator() / self.denominator()

def recurrence_repr(self):
"""
Return a string with the recurrence representation of the C-finite sequence.
OUTPUT:
- A CFiniteSequence object
EXAMPLES::
sage: R.<x> = ZZ[]
sage: CFiniteSequence((2-x)/(1-x-x^2)).recurrence_repr()
'Homogenous linear recurrence with constant coefficients of degree 2: a(n+2) = 1*a(n) + 1*a(n+1), starting a(0...) = [2, 1]'
sage: CFiniteSequence(x/(1-x)^3).recurrence_repr()
'Homogenous linear recurrence with constant coefficients of degree 3: a(n+3) = 3*a(n) - 3*a(n+1) + 1*a(n+2), starting a(1...) = [1, 3, 6]'
sage: CFiniteSequence(R(1)).recurrence_repr()
'Finite sequence [1], offset 0'
"""

if self._deg == 0:
return 'Finite sequence ' + str(self._a) + ', offset ' + str(self._off)
else:
cstr = 'a(n+' + str(self._deg) + ') = ' + str(self._c[0]) + '*a(n)'
for i in range(1, self._deg):
if self._c[i] < 0:
cstr = cstr + ' - ' + str(-(self._c[i])) + '*a(n+' + str(i) + ')'
elif self._c[i] > 0:
cstr = cstr + ' + ' + str(self._c[i]) + '*a(n+' + str(i) + ')'
else:
cstr = cstr + ' + ' + str(self._c[i]) + '*a(n+' + str(i) + ')'
astr = ', starting a(' + str(self._off) + '...) = ' + str(self._a)
return 'Homogenous linear recurrence with constant coefficients of degree ' + str(self._deg) + ': ' + cstr + astr

def series(self, n):
"""
Return the Laurent power series associated with the CFiniteSequence, with precision n.
Expand Down

0 comments on commit cc2b400

Please sign in to comment.