""" Contains the base class for series Made using sequences in mind """ from sympy.core.expr import Expr from sympy.core.singleton import S from sympy.core.cache import cacheit class SeriesBase(Expr): """Base Class for series""" @property def interval(self): """The interval on which the series is defined""" raise NotImplementedError("(%s).interval" % self) @property def start(self): """The starting point of the series. This point is included""" raise NotImplementedError("(%s).start" % self) @property def stop(self): """The ending point of the series. This point is included""" raise NotImplementedError("(%s).stop" % self) @property def length(self): """Length of the series expansion""" raise NotImplementedError("(%s).length" % self) @property def variables(self): """Returns a tuple of variables that are bounded""" return () @property def free_symbols(self): """ This method returns the symbols in the object, excluding those that take on a specific value (i.e. the dummy symbols). """ return ({j for i in self.args for j in i.free_symbols} .difference(self.variables)) @cacheit def term(self, pt): """Term at point pt of a series""" if pt < self.start or pt > self.stop: raise IndexError("Index %s out of bounds %s" % (pt, self.interval)) return self._eval_term(pt) def _eval_term(self, pt): raise NotImplementedError("The _eval_term method should be added to" "%s to return series term so it is available" "when 'term' calls it." % self.func) def _ith_point(self, i): """ Returns the i'th point of a series If start point is negative infinity, point is returned from the end. Assumes the first point to be indexed zero. Examples ======== TODO """ if self.start is S.NegativeInfinity: initial = self.stop step = -1 else: initial = self.start step = 1 return initial + i*step def __iter__(self): i = 0 while i < self.length: pt = self._ith_point(i) yield self.term(pt) i += 1 def __getitem__(self, index): if isinstance(index, int): index = self._ith_point(index) return self.term(index) elif isinstance(index, slice): start, stop = index.start, index.stop if start is None: start = 0 if stop is None: stop = self.length return [self.term(self._ith_point(i)) for i in range(start, stop, index.step or 1)]