Skip to content

Commit

Permalink
BUG: The polynomial convenience classes let different types interact.
Browse files Browse the repository at this point in the history
In particular for arithmetic where one could end up with a Polynomial
type with Chebyshev coefficients after an addition. It is unlikely that
that would be done on purpose.

The PolyDomain error message was also replaced by a TypeError with
an appropriate message. That seems like a better choice.
  • Loading branch information
charris committed Apr 30, 2012
1 parent b4a3beb commit 75519d5
Showing 1 changed file with 60 additions and 38 deletions.
98 changes: 60 additions & 38 deletions numpy/polynomial/polytemplate.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@

polytemplate = string.Template('''
from __future__ import division
REL_IMPORT polyutils as pu
import numpy as np
import warnings
REL_IMPORT polyutils as pu
class $name(pu.PolyBase) :
"""A $name series class.
Expand Down Expand Up @@ -147,21 +148,25 @@ def has_samewindow(self, other):
"""
return np.all(self.window == other.window)
def has_samewindow(self, other):
"""Check if windows match.
def has_sametype(self, other):
"""Check if types match.
Parameters
----------
other : class instance
The other class must have the ``window`` attribute.
other : object
Class instance.
Returns
-------
bool : boolean
True if the windows are the same, False otherwise.
True if other is same class as self
Notes
-----
.. versionadded:: 1.7.0
"""
return np.all(self.window == other.window)
return isinstance(other, self.__class__)
def __init__(self, coef, domain=$domain, window=$domain) :
[coef, dom, win] = pu.as_series([coef, domain, window], trim=False)
Expand Down Expand Up @@ -220,11 +225,15 @@ def __pos__(self) :
def __add__(self, other) :
"""Returns sum"""
if isinstance(other, self.__class__) :
if self.has_samedomain(other) and self.has_samewindow(other):
if isinstance(other, pu.PolyBase):
if not self.has_sametype(other):
raise TypeError("Polynomial types differ")
elif not self.has_samedomain(other):
raise TypeError("Domains differ")
elif not self.has_samewindow(other):
raise TypeError("Windows differ")
else:
coef = ${nick}add(self.coef, other.coef)
else :
raise PolyDomainError()
else :
try :
coef = ${nick}add(self.coef, other)
Expand All @@ -234,11 +243,15 @@ def __add__(self, other) :
def __sub__(self, other) :
"""Returns difference"""
if isinstance(other, self.__class__) :
if self.has_samedomain(other) and self.has_samewindow(other):
if isinstance(other, pu.PolyBase):
if not self.has_sametype(other):
raise TypeError("Polynomial types differ")
elif not self.has_samedomain(other):
raise TypeError("Domains differ")
elif not self.has_samewindow(other):
raise TypeError("Windows differ")
else:
coef = ${nick}sub(self.coef, other.coef)
else :
raise PolyDomainError()
else :
try :
coef = ${nick}sub(self.coef, other)
Expand All @@ -248,11 +261,15 @@ def __sub__(self, other) :
def __mul__(self, other) :
"""Returns product"""
if isinstance(other, self.__class__) :
if self.has_samedomain(other) and self.has_samewindow(other):
if isinstance(other, pu.PolyBase):
if not self.has_sametype(other):
raise TypeError("Polynomial types differ")
elif not self.has_samedomain(other):
raise TypeError("Domains differ")
elif not self.has_samewindow(other):
raise TypeError("Windows differ")
else:
coef = ${nick}mul(self.coef, other.coef)
else :
raise PolyDomainError()
else :
try :
coef = ${nick}mul(self.coef, other)
Expand All @@ -261,32 +278,31 @@ def __mul__(self, other) :
return self.__class__(coef, self.domain, self.window)
def __div__(self, other):
# set to __floordiv__ /.
# set to __floordiv__, /, for now.
return self.__floordiv__(other)
def __truediv__(self, other) :
# there is no true divide if the rhs is not a scalar, although it
# could return the first n elements of an infinite series.
# It is hard to see where n would come from, though.
if isinstance(other, self.__class__) :
if len(other.coef) == 1 :
coef = div(self.coef, other.coef)
else :
return NotImplemented
elif np.isscalar(other) :
if np.isscalar(other) :
# this might be overly restrictive
coef = self.coef/other
return self.__class__(coef, self.domain, self.window)
else :
return NotImplemented
return self.__class__(coef, self.domain, self.window)
def __floordiv__(self, other) :
"""Returns the quotient."""
if isinstance(other, self.__class__) :
if np.all(self.domain == other.domain) :
if isinstance(other, pu.PolyBase):
if not self.has_sametype(other):
raise TypeError("Polynomial types differ")
elif not self.has_samedomain(other):
raise TypeError("Domains differ")
elif not self.has_samewindow(other):
raise TypeError("Windows differ")
else:
quo, rem = ${nick}div(self.coef, other.coef)
else :
raise PolyDomainError()
else :
try :
quo, rem = ${nick}div(self.coef, other)
Expand All @@ -296,11 +312,15 @@ def __floordiv__(self, other) :
def __mod__(self, other) :
"""Returns the remainder."""
if isinstance(other, self.__class__) :
if self.has_samedomain(other) and self.has_samewindow(other):
if isinstance(other, pu.PolyBase):
if not self.has_sametype(other):
raise TypeError("Polynomial types differ")
elif not self.has_samedomain(other):
raise TypeError("Domains differ")
elif not self.has_samewindow(other):
raise TypeError("Windows differ")
else:
quo, rem = ${nick}div(self.coef, other.coef)
else :
raise PolyDomainError()
else :
try :
quo, rem = ${nick}div(self.coef, other)
Expand All @@ -311,10 +331,12 @@ def __mod__(self, other) :
def __divmod__(self, other) :
"""Returns quo, remainder"""
if isinstance(other, self.__class__) :
if self.has_samedomain(other) and self.has_samewindow(other):
if not self.has_samedomain(other):
raise TypeError("Domains are not equal")
elif not self.has_samewindow(other):
raise TypeError("Windows are not equal")
else:
quo, rem = ${nick}div(self.coef, other.coef)
else :
raise PolyDomainError()
else :
try :
quo, rem = ${nick}div(self.coef, other)
Expand Down

0 comments on commit 75519d5

Please sign in to comment.