Formal power series: Difference between revisions

another python
(jq)
(another python)
Line 1,759:
[1, Fraction(0, 1), Fraction(-1, 2), Fraction(0, 1), Fraction(1, 24), Fraction(0, 1), Fraction(-1, 720), Fraction(0, 1), Fraction(1, 40320), Fraction(0, 1)]
</pre>
 
===Operator overloading===
Define an iterator class as a polynomial to provide overloaded operators and automatic tee-ing. It is kind of overkill.
<lang python>from itertools import count, chain, tee, islice, cycle
from fractions import Fraction
 
# infinite polynomial class
class Poly:
def __init__(self, gen = None):
self.gen, self.source = (None, gen) if type(gen) is Poly \
else (gen, None)
 
def __iter__(self):
# We're essentially tee'ing it everytime the iterator
# is, well, iterated. This may be excessive.
return Poly(self)
 
def getsource(self):
if self.gen == None:
s = self.source
s.getsource()
(a,b) = tee(s.gen, 2)
s.gen = a
self.gen = b
 
def next(self):
self.getsource()
return next(self.gen)
 
__next__ = next
 
# Overload "<<" as stream input operator. Hey, C++ does it.
def __lshift__(self, a): self.gen = a
 
# The other operators are pretty much what one would expect
def __neg__(self): return Poly(-x for x in self)
 
def __sub__(a, b): return a + (-b)
 
def __rsub__(a, n):
def gen():
yield(n - next(a))
for x in a: yield(-x)
return Poly(gen())
 
def __add__(a, b):
if type(b) is Poly:
return Poly(x + y for (x,y) in zip(a,b))
 
def gen():
yield(next(a) + b)
for x in a: yield(x)
return Poly(gen())
 
def __radd__(a,b):
return a + b
 
def __mul__(a,b):
if not type(b) is Poly:
return Poly(x*b for x in a)
 
def gen():
s = Poly(cycle([0]))
for y in b:
s += y*a
yield(next(s))
 
return Poly(gen())
 
def __rmul__(a,b): return a*b
 
def __truediv__(a,b):
if not type(b) is Poly:
return Poly(Fraction(x, b) for x in a)
 
a, b = Poly(a), Poly(b)
def gen():
r, bb = a,next(b)
while True:
aa = next(r)
q = Fraction(aa, bb)
yield(q)
r -= q*b
 
return Poly(gen())
 
# these two would probably be better as class methods
def inte(a):
def gen():
yield(0)
for (x,n) in zip(a, count(1)):
yield(Fraction(x,n))
return Poly(gen())
 
def diff(a):
def gen():
for (x, n) in zip(a, count(0)):
if n: yield(x*n)
return Poly(gen())
 
 
# all that for the syntactic sugar
sinx, cosx, tanx, expx = Poly(), Poly(), Poly(), Poly()
 
sinx << inte(cosx)
cosx << 1 - inte(sinx)
tanx << sinx / cosx # "=" would also work here
expx << 1 + inte(expx)
 
for n,x in zip(("sin", "cos", "tan", "exp"), (sinx, cosx, tanx, expx)):
print(n, ', '.join(map(str, list(islice(x, 10)))))</lang>
 
=={{header|Racket}}==
Anonymous user