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

Commit

Permalink
handle ogf > 1
Browse files Browse the repository at this point in the history
  • Loading branch information
rwst committed Apr 15, 2014
1 parent ba8a5a6 commit be9bb7f
Showing 1 changed file with 42 additions and 24 deletions.
66 changes: 42 additions & 24 deletions src/sage/combinat/cfinite_sequence.py
Expand Up @@ -43,8 +43,28 @@
sage: CFiniteSequence.guess([0,1,1,2,3,5,8])
C-finite sequence, generated by x/(-x^2 - x + 1)
TESTS::
sage: CFiniteSequence(x/(1-x))
C-finite sequence, generated by x/(-x + 1)
sage: CFiniteSequence(x^3/(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) = 0, a(1) = 0, a(2) = 0, a(3) = 1'
sage: r=CFiniteSequence.from_recurrence([1,1],[0,0,0,1])
sage: r.seq(5)
[0, 0, 0, 1, 1]
sage: r.ogf()
x^3/(-x^2 - x + 1)
sage: r = CFiniteSequence.from_recurrence([-1],[1])
sage: s = CFiniteSequence.from_recurrence([-1],[1,-1])
sage: r == s
True
sage: CFiniteSequence(1/x)
Traceback (most recent call last):
...
ValueError: Denominator divisible by x not allowed.
SEEALSO:
:func:`fibonacci`, :class:`sage.combinat.binary_recurrence_sequences.BinaryRecurrenceSequence`
:func:`fibonacci`, :class:`BinaryRecurrenceSequence`
AUTHORS:
Expand Down Expand Up @@ -123,14 +143,17 @@ def __init__(self, ogf):
num = ogf.numerator()
den = ogf.denominator()
f = den.constant_coefficient()
if f == 0:
raise ValueError("Denominator divisible by x not allowed.")
num = num/f
den = den/f
if den == 1:
self._deg = 0
else:
self._deg = den.degree()
R = PowerSeriesRing(Rationals(), 'x')
self._a = (R(num, prec=self._deg) / R(den, prec=self._deg)).padded_list()
alen = max(self._deg, num.degree() + 1)
self._a = (R(num, prec=alen) / R(den, prec=alen)).padded_list()
self._c = [-den.list()[i] for i in range(1,self._deg+1)]
self._ogf = num/den
else: raise ValueError("Cannot convert to CFiniteSequence.")
Expand Down Expand Up @@ -168,14 +191,13 @@ def from_recurrence(cls, coefficients, values):
if not isinstance(values, list):
raise ValueError("Wrong type for recurrence start value list.")
deg = len(coefficients)
if len(values) > deg:
raise ValueError("More than deg start values not implemented.")

co = coefficients[::-1]
co.extend([0] * (len(values)-deg))
R = PolynomialRing(Rationals(), 'x')
x = R.gen()
den = -1 + sum([x**(n+1)*co[n] for n in range(deg)])
num = -values[0] + sum([x**n * (-values[n] + sum([values[k]*co[n-1-k] for k in range(n)])) for n in range(1,deg)])
num = -values[0] + sum([x**n * (-values[n] + sum([values[k]*co[n-1-k] for k in range(n)])) for n in range(1,len(values))])
return cls(num/den)

def __repr__(self):
Expand Down Expand Up @@ -237,7 +259,7 @@ def recurrence_repr(self):
else:
cstr = cstr + ' + ' + str(self._c[i]) + '*a(n+' + str(i) + ')'
astr = ', starting a(0) = ' + str(self._a[0])
for i in range(1, self._deg):
for i in range(1, len(self._a)):
astr = astr + ', a(' + str(i) + ')' + ' = ' + str(self._a[i])
return 'Homogenous linear recurrence with constant coefficients of degree ' + str(self._deg) + ': ' + cstr + astr

Expand Down Expand Up @@ -292,15 +314,16 @@ def __getitem__( self, key ) :
m = max(key.start, key.stop)
return [self[ii] for ii in xrange(*key.indices(m+1))]
elif isinstance( key, (Integer, int) ) :
d = self._deg
if key < 0 : #Handle negative indices
raise IndexError, "The index (%d) is out of range."%key
if self._deg == 0:
if d == 0:
if len(self._a) > key: return self._a[key]
else: return 0
A = Matrix(Rationals(), 1, self._deg, self._c)
B = Matrix.identity(Rationals(), self._deg-1)
C = Matrix(Rationals(), self._deg-1, 1, 0)
V = Matrix(Rationals(), self._deg, 1, self._a[::-1])
A = Matrix(Rationals(), 1, d, self._c)
B = Matrix.identity(Rationals(), d-1)
C = Matrix(Rationals(), d-1, 1, 0)
V = Matrix(Rationals(), d, 1, self._a[:d][::-1])
M = Matrix.block([[A],[B,C]],subdivide=False)
return list(M**(key-1)*V)[0][0]
else:
Expand Down Expand Up @@ -357,8 +380,14 @@ def seq(self, n):
[0, 1, 2, 3, 4]
"""

R = PowerSeriesRing(Rationals(), 'x')
return (R(self._ogf.numerator(), prec=n) / R(self._ogf.denominator(), prec=n)).padded_list(n)
if n <= len(self._a):
outlist = self._a[:n]
else:
outlist = self._a
R = PowerSeriesRing(Rationals(), 'x')
fullseq = (R(self._ogf.numerator(), prec=n) / R(self._ogf.denominator(), prec=n)).padded_list(n)
outlist.extend(fullseq[len(self._a):])
return outlist

@staticmethod
def guess(sequence):
Expand Down Expand Up @@ -404,19 +433,8 @@ def random_object():
"""
.. TODO::
sage: CFiniteSequence(x/(1-x)) # specific output not implemented
Constant sequence a(n) = 1, starting a(0) = 0
sage: CFiniteSequence(x^3/(1-x-x^2)) # gf>1 output not implemented
Homogenous linear recurrence with constant coefficients of degree 2: a(n+2) = 1*a(n) + 1*a(n+1), starting a(0) = 0, a(1) = 0, a(2) = 0, a(3) = 1
sage: r=CFiniteSequence.from_recurrence([1,1],[0,0,0,1]) # gf>1 from attr not implemented
sage: r.ogf() # not implemented
x^3/(-x^2 - x + 1)
sage: r.egf() # not implemented
exp(2*x)
sage: latex(r) # not implemented
\big\{a_{n\ge0}\big|a_{n+2}=\sum_{i=0}^{1}c_ia_{n+i}, c=\{1,1\}, a_{n<2}=\{0,0,0,1\}\big\}
sage: r = CFiniteSequence.from_recurrence([-1],[1]) # not implemented
sage: s = CFiniteSequence.from_recurrence([-1],[1,-1]) # not implemented
sage: r == s # not implemented
True
"""

0 comments on commit be9bb7f

Please sign in to comment.