"""
def __new__(cls, coefficients=None, constant=0):
+ """
+ Create a new expression.
+ """
if isinstance(coefficients, str):
if constant != 0:
raise TypeError('too many arguments')
return self
def coefficient(self, symbol):
+ """
+ Return the coefficient value of the given symbol.
+ """
if not isinstance(symbol, Symbol):
raise TypeError('symbol must be a Symbol instance')
return Rational(self._coefficients.get(symbol, 0))
__getitem__ = coefficient
def coefficients(self):
+ """
+ Return a list of the coefficients of an expression
+ """
for symbol, coefficient in self._coefficients.items():
yield symbol, Rational(coefficient)
@property
def constant(self):
+ """
+ Return the constant value of an expression.
+ """
return Rational(self._constant)
@property
def symbols(self):
+ """
+ Return a list of symbols in an expression.
+ """
return self._symbols
@property
def dimension(self):
+ """
+ Create and return a new linear expression from a string or a list of coefficients and a constant.
+ """
return self._dimension
def __hash__(self):
return hash((tuple(self._coefficients.items()), self._constant))
def isconstant(self):
+ """
+ Return true if an expression is a constant.
+ """
return False
def issymbol(self):
+ """
+ Return true if an expression is a symbol.
+ """
return False
def values(self):
+ """
+ Return the coefficient and constant values of an expression.
+ """
for coefficient in self._coefficients.values():
yield Rational(coefficient)
yield Rational(self._constant)
@_polymorphic
def __add__(self, other):
+ """
+ Return the sum of two expressions.
+ """
coefficients = defaultdict(Fraction, self._coefficients)
for symbol, coefficient in other._coefficients.items():
coefficients[symbol] += coefficient
@_polymorphic
def __sub__(self, other):
+ """
+ Return the difference between two expressions.
+ """
coefficients = defaultdict(Fraction, self._coefficients)
for symbol, coefficient in other._coefficients.items():
coefficients[symbol] -= coefficient
return other - self
def __mul__(self, other):
+ """
+ Return the product of two expressions if other is a rational number.
+ """
if isinstance(other, numbers.Rational):
coefficients = ((symbol, coefficient * other)
for symbol, coefficient in self._coefficients.items())
@_polymorphic
def __eq__(self, other):
- # returns a boolean, not a constraint
- # see http://docs.sympy.org/dev/tutorial/gotchas.html#equals-signs
+ """
+ Test whether two expressions are equal
+ """
return isinstance(other, Expression) and \
self._coefficients == other._coefficients and \
self._constant == other._constant
return Gt(self, other)
def scaleint(self):
+ """
+ Multiply an expression by a scalar to make all coefficients integer values.
+ """
lcm = functools.reduce(lambda a, b: a*b // gcd(a, b),
[value.denominator for value in self.values()])
return self * lcm
def subs(self, symbol, expression=None):
+ """
+ Subsitute symbol by expression in equations and return the resulting
+ expression.
+ """
if expression is None:
if isinstance(symbol, Mapping):
symbol = symbol.items()
@classmethod
def fromstring(cls, string):
+ """
+ Create an expression from a string.
+ """
# add implicit multiplication operators, e.g. '5x' -> '5*x'
string = Expression._RE_NUM_VAR.sub(r'\1*\2', string)
tree = ast.parse(string, 'eval')
@classmethod
def fromsympy(cls, expr):
+ """
+ Convert sympy object to an expression.
+ """
import sympy
coefficients = []
constant = 0
return Expression(coefficients, constant)
def tosympy(self):
+ """
+ Return an expression as a sympy object.
+ """
import sympy
expr = 0
for symbol, coefficient in self.coefficients():
class Symbol(Expression):
def __new__(cls, name):
+ """
+ Create and return a symbol from a string.
+ """
if not isinstance(name, str):
raise TypeError('name must be a string')
self = object().__new__(cls)
return self.sortkey() == other.sortkey()
def asdummy(self):
+ """
+ Return a symbol as a Dummy Symbol.
+ """
return Dummy(self.name)
@classmethod
class Dummy(Symbol):
-
+ """
+ This class returns a dummy symbol to ensure that no variables are repeated in an expression
+ """
_count = 0
def __new__(cls, name=None):
+ """
+ Create and return a new dummy symbol.
+ """
if name is None:
name = 'Dummy_{}'.format(Dummy._count)
elif not isinstance(name, str):
def symbols(names):
+ """
+ Transform strings into instances of the Symbol class
+ """
if isinstance(names, str):
names = names.replace(',', ' ').split()
return tuple(Symbol(name) for name in names)
class Rational(Expression, Fraction):
+ """
+ This class represents integers and rational numbers of any size.
+ """
def __new__(cls, numerator=0, denominator=None):
self = object().__new__(cls)
@property
def constant(self):
+ """
+ Return rational as a constant.
+ """
return self
def isconstant(self):
+ """
+ Test whether a value is a constant.
+ """
return True
def __bool__(self):
@classmethod
def fromsympy(cls, expr):
+ """
+ Create a rational object from a sympy expression
+ """
import sympy
if isinstance(expr, sympy.Rational):
return Rational(expr.p, expr.q)