class RationalFunction: """Rational Function Instances of this class represent rational functions in a single variable. They can be evaluated like functions. Rational functions support addition, subtraction, multiplication, and division. """ def __init__(self, numerator, denominator=[1.]): """ @param numerator: polynomial in one variable, or a list of polynomial coefficients @type numerator: L{Scientific.Functions.Polynomial.Polynomial} or C{list} of numbers @param denominator: polynomial in one variable, or a list of polynomial coefficients @type denominator: L{Scientific.Functions.Polynomial.Polynomial} or C{list} of numbers """ if hasattr(numerator, 'is_polynomial'): self.numerator = numerator else: self.numerator = Polynomial(numerator) if hasattr(denominator, 'is_polynomial'): self.denominator = denominator else: self.denominator = Polynomial(denominator) self._normalize() is_rational_function = 1 def __call__(self, value): return self.numerator(value) / self.denominator(value) def __repr__(self): return "RationalFunction(%s,%s)" % (repr(list( self.numerator.coeff)), repr(list(self.denominator.coeff))) def _normalize(self): self.numerator = self._truncate(self.numerator) self.denominator = self._truncate(self.denominator) n = 0 while 1: if self.numerator.coeff[n] != 0: break if self.denominator.coeff[n] != 0: break n = n + 1 if n == len(self.numerator.coeff): break if n > 0: self.numerator = Polynomial(self.numerator.coeff[n:]) self.denominator = Polynomial(self.denominator.coeff[n:]) factor = self.denominator.coeff[-1] if factor != 1.: self.numerator = self.numerator / factor self.denominator = self.denominator / factor def _truncate(self, poly): if poly.coeff[-1] != 0.: return poly coeff = poly.coeff while len(coeff) > 1 and coeff[-1] == 0.: coeff = coeff[:-1] return Polynomial(coeff) def __coerce__(self, other): if hasattr(other, 'is_rational_function'): return (self, other) elif hasattr(other, 'is_polynomial'): return (self, RationalFunction(other, [1.])) else: return (self, RationalFunction([other], [1.])) def __mul__(self, other): return RationalFunction(self.numerator * other.numerator, self.denominator * other.denominator) __rmul__ = __mul__ def __div__(self, other): return RationalFunction(self.numerator * other.denominator, self.denominator * other.numerator) __truediv__ = __div__ def __rdiv__(self, other): return RationalFunction(other.numerator * self.denominator, other.denominator * self.numerator) def __add__(self, other): return RationalFunction( self.numerator * other.denominator + self.denominator * other.numerator, self.denominator * other.denominator) __radd__ = __add__ def __sub__(self, other): return RationalFunction( self.numerator * other.denominator - self.denominator * other.numerator, self.denominator * other.denominator) def __rsub__(self, other): return RationalFunction( other.numerator * self.denominator - other.denominator * self.numerator, self.denominator * other.denominator) def divide(self, shift=0): """ @param shift: the power of the independent variable by which the numerator is multiplied prior to division @type shift: C{int} (non-negative) @return: a polynomial and a rational function such that the sum of the two is equal to the original rational function. The returned rational function's numerator is of lower order than its denominator. @rtype: (L{Scientific.Functions.Polynomial.Polynomial}, L{RationalFunction}) """ num = Numeric.array(self.numerator.coeff, copy=1) if shift > 0: num = Numeric.concatenate((shift * [0.], num)) den = self.denominator.coeff den_order = len(den) coeff = [] while len(num) >= den_order: q = num[-1] / den[-1] coeff.append(q) num[-den_order:] = num[-den_order:] - q * den num = num[:-1] if not coeff: coeff = [0] coeff.reverse() if len(num) == 0: num = [0] return Polynomial(coeff), RationalFunction(num, den) def zeros(self): """ Find the X{zeros} (X{roots}) of the numerator by diagonalization of the associated Frobenius matrix. @returns: an array containing the zeros @rtype: C{Numeric.array} """ return self.numerator.zeros() def poles(self): """ Find the X{poles} (zeros of the denominator) by diagonalization of the associated Frobenius matrix. @returns: an array containing the poles @rtype: C{Numeric.array} """ return self.denominator.zeros()
class RationalFunction: """Rational Function Instances of this class represent rational functions in a single variable. They can be evaluated like functions. Rational functions support addition, subtraction, multiplication, and division. """ def __init__(self, numerator, denominator=[1.]): """ @param numerator: polynomial in one variable, or a list of polynomial coefficients @type numerator: L{Scientific.Functions.Polynomial.Polynomial} or C{list} of numbers @param denominator: polynomial in one variable, or a list of polynomial coefficients @type denominator: L{Scientific.Functions.Polynomial.Polynomial} or C{list} of numbers """ if hasattr(numerator, 'is_polynomial'): self.numerator = numerator else: self.numerator = Polynomial(numerator) if hasattr(denominator, 'is_polynomial'): self.denominator = denominator else: self.denominator = Polynomial(denominator) self._normalize() is_rational_function = 1 def __call__(self, value): return self.numerator(value)/self.denominator(value) def __repr__(self): return "RationalFunction(%s,%s)" % (repr(list(self.numerator.coeff)), repr(list(self.denominator.coeff))) def _normalize(self): self.numerator = self._truncate(self.numerator) self.denominator = self._truncate(self.denominator) n = 0 while 1: if self.numerator.coeff[n] != 0: break if self.denominator.coeff[n] != 0: break n = n + 1 if n == len(self.numerator.coeff): break if n > 0: self.numerator = Polynomial(self.numerator.coeff[n:]) self.denominator = Polynomial(self.denominator.coeff[n:]) factor = self.denominator.coeff[-1] if factor != 1.: self.numerator = self.numerator/factor self.denominator = self.denominator/factor def _truncate(self, poly): if poly.coeff[-1] != 0.: return poly coeff = poly.coeff while len(coeff) > 1 and coeff[-1] == 0.: coeff = coeff[:-1] return Polynomial(coeff) def __coerce__(self, other): if hasattr(other, 'is_rational_function'): return (self, other) elif hasattr(other, 'is_polynomial'): return (self, RationalFunction(other, [1.])) else: return (self, RationalFunction([other], [1.])) def __mul__(self, other): return RationalFunction(self.numerator*other.numerator, self.denominator*other.denominator) __rmul__ = __mul__ def __div__(self, other): return RationalFunction(self.numerator*other.denominator, self.denominator*other.numerator) def __rdiv__(self, other): return RationalFunction(other.numerator*self.denominator, other.denominator*self.numerator) def __add__(self, other): return RationalFunction(self.numerator*other.denominator+ self.denominator*other.numerator, self.denominator*other.denominator) __radd__ = __add__ def __sub__(self, other): return RationalFunction(self.numerator*other.denominator- self.denominator*other.numerator, self.denominator*other.denominator) def __rsub__(self, other): return RationalFunction(other.numerator*self.denominator- other.denominator*self.numerator, self.denominator*other.denominator) def divide(self, shift=0): """ @param shift: the power of the independent variable by which the numerator is multiplied prior to division @type shift: C{int} (non-negative) @return: a polynomial and a rational function such that the sum of the two is equal to the original rational function. The returned rational function's numerator is of lower order than its denominator. @rtype: (L{Scientific.Functions.Polynomial.Polynomial}, L{RationalFunction}) """ num = Numeric.array(self.numerator.coeff, copy=1) if shift > 0: num = Numeric.concatenate((shift*[0.], num)) den = self.denominator.coeff den_order = len(den) coeff = [] while len(num) >= den_order: q = num[-1]/den[-1] coeff.append(q) num[-den_order:] = num[-den_order:]-q*den num = num[:-1] if not coeff: coeff = [0] coeff.reverse() if len(num) == 0: num = [0] return Polynomial(coeff), RationalFunction(num, den) def zeros(self): """ Find the X{zeros} (X{roots}) of the numerator by diagonalization of the associated Frobenius matrix. @returns: an array containing the zeros @rtype: C{Numeric.array} """ return self.numerator.zeros() def poles(self): """ Find the X{poles} (zeros of the denominator) by diagonalization of the associated Frobenius matrix. @returns: an array containing the poles @rtype: C{Numeric.array} """ return self.denominator.zeros()
class RationalFunction: """Rational Function Instances of this class represent rational functions in a single variable. They can be evaluated like functions. Constructor: RationalFunction(|numerator|, |denominator|) Arguments: |numerator|, |denominator| -- polynomials or sequences of numbers that represent the polynomial coefficients Rational functions support addition, subtraction, multiplication, and division. """ def __init__(self, numerator, denominator=[1.]): if hasattr(numerator, 'is_polynomial'): self.numerator = numerator else: self.numerator = Polynomial(numerator) if hasattr(denominator, 'is_polynomial'): self.denominator = denominator else: self.denominator = Polynomial(denominator) self._normalize() is_rational_function = 1 def __call__(self, value): return self.numerator(value)/self.denominator(value) def __repr__(self): return "RationalFunction(%s,%s)" % (repr(list(self.numerator.coeff)), repr(list(self.denominator.coeff))) def _normalize(self): self.numerator = self._truncate(self.numerator) self.denominator = self._truncate(self.denominator) n = 0 while 1: if self.numerator.coeff[n] != 0: break if self.denominator.coeff[n] != 0: break n = n + 1 if n == len(self.numerator.coeff): break if n > 0: self.numerator = Polynomial(self.numerator.coeff[n:]) self.denominator = Polynomial(self.denominator.coeff[n:]) factor = self.denominator.coeff[-1] if factor != 1.: self.numerator = self.numerator/factor self.denominator = self.denominator/factor def _truncate(self, poly): if poly.coeff[-1] != 0.: return poly coeff = poly.coeff while len(coeff) > 1 and coeff[-1] == 0.: coeff = coeff[:-1] return Polynomial(coeff) def __coerce__(self, other): if hasattr(other, 'is_rational_function'): return (self, other) elif hasattr(other, 'is_polynomial'): return (self, RationalFunction(other, [1.])) else: return (self, RationalFunction([other], [1.])) def __mul__(self, other): return RationalFunction(self.numerator*other.numerator, self.denominator*other.denominator) __rmul__ = __mul__ def __div__(self, other): return RationalFunction(self.numerator*other.denominator, self.denominator*other.numerator) def __rdiv__(self, other): return RationalFunction(other.numerator*self.denominator, other.denominator*self.numerator) def __add__(self, other): return RationalFunction(self.numerator*other.denominator+ self.denominator*other.numerator, self.denominator*other.denominator) __radd__ = __add__ def __sub__(self, other): return RationalFunction(self.numerator*other.denominator- self.denominator*other.numerator, self.denominator*other.denominator) def __rsub__(self, other): return RationalFunction(other.numerator*self.denominator- other.denominator*self.numerator, self.denominator*other.denominator) def divide(self, shift=0): """Returns a polynomial and a rational function such that the sum of the two is equal to the original rational function. The returned rational function's numerator is of lower order than its denominator. The argument |shift| (default: 0) specifies a positive integer power of the independent variable by which the numerator is multiplied prior to division. """ num = Numeric.array(self.numerator.coeff, copy=1) if shift > 0: num = Numeric.concatenate((shift*[0.], num)) den = self.denominator.coeff den_order = len(den) coeff = [] while len(num) >= den_order: q = num[-1]/den[-1] coeff.append(q) num[-den_order:] = num[-den_order:]-q*den num = num[:-1] if not coeff: coeff = [0] coeff.reverse() if len(num) == 0: num = [0] return Polynomial(coeff), RationalFunction(num, den) def zeros(self): "Returns an array containing the zeros." return self.numerator.zeros() def poles(self): "Returns an array containing the poles." return self.denominator.zeros()
class RationalFunction: """Rational Function Instances of this class represent rational functions in a single variable. They can be evaluated like functions. Constructor: RationalFunction(|numerator|, |denominator|) Arguments: |numerator|, |denominator| -- polynomials or sequences of numbers that represent the polynomial coefficients Rational functions support addition, subtraction, multiplication, and division. """ def __init__(self, numerator, denominator=[1.]): if hasattr(numerator, 'is_polynomial'): self.numerator = numerator else: self.numerator = Polynomial(numerator) if hasattr(denominator, 'is_polynomial'): self.denominator = denominator else: self.denominator = Polynomial(denominator) self._normalize() is_rational_function = 1 def __call__(self, value): return self.numerator(value) / self.denominator(value) def __repr__(self): return "RationalFunction(%s,%s)" % (repr(list( self.numerator.coeff)), repr(list(self.denominator.coeff))) def _normalize(self): self.numerator = self._truncate(self.numerator) self.denominator = self._truncate(self.denominator) n = 0 while 1: if self.numerator.coeff[n] != 0: break if self.denominator.coeff[n] != 0: break n = n + 1 if n == len(self.numerator.coeff): break if n > 0: self.numerator = Polynomial(self.numerator.coeff[n:]) self.denominator = Polynomial(self.denominator.coeff[n:]) factor = self.denominator.coeff[-1] if factor != 1.: self.numerator = self.numerator / factor self.denominator = self.denominator / factor def _truncate(self, poly): if poly.coeff[-1] != 0.: return poly coeff = poly.coeff while len(coeff) > 1 and coeff[-1] == 0.: coeff = coeff[:-1] return Polynomial(coeff) def __coerce__(self, other): if hasattr(other, 'is_rational_function'): return (self, other) elif hasattr(other, 'is_polynomial'): return (self, RationalFunction(other, [1.])) else: return (self, RationalFunction([other], [1.])) def __mul__(self, other): return RationalFunction(self.numerator * other.numerator, self.denominator * other.denominator) __rmul__ = __mul__ def __div__(self, other): return RationalFunction(self.numerator * other.denominator, self.denominator * other.numerator) def __rdiv__(self, other): return RationalFunction(other.numerator * self.denominator, other.denominator * self.numerator) def __add__(self, other): return RationalFunction( self.numerator * other.denominator + self.denominator * other.numerator, self.denominator * other.denominator) __radd__ = __add__ def __sub__(self, other): return RationalFunction( self.numerator * other.denominator - self.denominator * other.numerator, self.denominator * other.denominator) def __rsub__(self, other): return RationalFunction( other.numerator * self.denominator - other.denominator * self.numerator, self.denominator * other.denominator) def divide(self, shift=0): """Returns a polynomial and a rational function such that the sum of the two is equal to the original rational function. The returned rational function's numerator is of lower order than its denominator. The argument |shift| (default: 0) specifies a positive integer power of the independent variable by which the numerator is multiplied prior to division. """ num = Numeric.array(self.numerator.coeff, copy=1) if shift > 0: num = Numeric.concatenate((shift * [0.], num)) den = self.denominator.coeff den_order = len(den) coeff = [] while len(num) >= den_order: q = num[-1] / den[-1] coeff.append(q) num[-den_order:] = num[-den_order:] - q * den num = num[:-1] if not coeff: coeff = [0] coeff.reverse() if len(num) == 0: num = [0] return Polynomial(coeff), RationalFunction(num, den) def zeros(self): "Returns an array containing the zeros." return self.numerator.zeros() def poles(self): "Returns an array containing the poles." return self.denominator.zeros()