def _divider(p1, p2, op="truediv"):
        p1 = Polynomial.polify(p1).simplify()
        p2 = Polynomial.polify(p2).simplify()

        if p1.isZero():
            return 0
        if p1.degree < p2.degree:
            if op == "truediv":
                return Fraction(p1, p2)
            if op == "floordiv":
                return 0
            if op == "modulo":
                return p1
        divisorTerms = []

        p1Term1 = p1.terms[0]
        p1Term1_coeff = p1Term1 if utils.isnumeric(p1Term1) else p1Term1.c
        p2Term2 = p2.terms[0]
        p2Term1_coeff = p2Term2 if utils.isnumeric(p2Term2) else p2Term2.c

        divisorVal = PowerTerm(p1Term1_coeff / p2Term1_coeff, x,
                               p1.degree - p2.degree)

        divisorTerms.append(divisorVal)
        newP1 = Polynomial.polify(p1 - (p2 * divisorVal)).simplify()
        divisorTerms.append(newP1._divider(p2, op))
        if op == "modulo":
            return divisorTerms.pop()
        return sum(divisorTerms)
    def _divider(p1, p2, op = "truediv"):
        p1 = Polynomial.polify(p1).simplify()
        p2 = Polynomial.polify(p2).simplify()

        if p1.isZero():
            return 0
        if p1.degree < p2.degree:
            if op == "truediv":
                return Fraction(p1 , p2)
            if op == "floordiv":
                return 0
            if op == "modulo":
                return p1
        divisorTerms = []

        p1Term1 = p1.terms[0]
        p1Term1_coeff = p1Term1 if utils.isnumeric(p1Term1) else p1Term1.c
        p2Term2 = p2.terms[0]
        p2Term1_coeff = p2Term2 if utils.isnumeric(p2Term2) else p2Term2.c

        divisorVal = PowerTerm(p1Term1_coeff / p2Term1_coeff, x, p1.degree - p2.degree)

        divisorTerms.append(divisorVal)
        newP1 = Polynomial.polify(p1 - (p2 * divisorVal)).simplify()
        divisorTerms.append(newP1._divider(p2, op))
        if op == "modulo":
            return divisorTerms.pop()
        return sum(divisorTerms)
 def __mul__(e1, e2):
     assert map(Expression.isExpression,
                (e1, e2)), "Arguements must be of Class Term"
     multiplied = 0
     for term1 in [e1] if utils.isnumeric(e1) else e1.terms:
         for term2 in [e2] if utils.isnumeric(e2) else e2.terms:
             multiplied += (term1 * term2)
     return multiplied
 def __mul__(e1, e2):
     assert map(Expression.isExpression, (e1, e2)
                ), "Arguements must be of Class Term"
     multiplied = 0
     for term1 in [e1] if utils.isnumeric(e1) else e1.terms:
         for term2 in [e2] if utils.isnumeric(e2) else e2.terms:
             multiplied += (term1 * term2)
     return multiplied
 def __init__(self, terms):
     assert isinstance(terms, list), "Terms must be a list "
     for term in terms:
         assert PowerTerm.isPwrTerm(term) or utils.isnumeric(term), "Every Term must be a PowerTerm" + " " + str(term)
         assert utils.isnumeric(term) or utils.isnumeric(term.exp), "Every Term must be a PowerTerm"
     super(Polynomial, self).__init__(terms)
     self.set_terms(terms)
     self.maxDegree = None
 def __init__(self, terms):
     assert isinstance(terms, list), "Terms must be a list "
     for term in terms:
         assert PowerTerm.isPwrTerm(term) or utils.isnumeric(
             term), "Every Term must be a PowerTerm" + " " + str(term)
         assert utils.isnumeric(term) or utils.isnumeric(
             term.exp), "Every Term must be a PowerTerm"
     super(Polynomial, self).__init__(terms)
     self.set_terms(terms)
     self.maxDegree = None
 def __add__(x1, x2):
     assert map(Expression.isExpression,
                (x1, x2)), "Arguements must be an Expression"
     if x1.__class__ == x2.__class__:
         return PowerTerm(2, x1, 1)
     if utils.isnumeric(x2):
         return Expression(x1.terms + [x2])
     return Expression(x1.terms + x2.terms)
 def __init__(self, coefficient=1, main=X(), exp=1):
     super(PowerTerm, self).__init__()
     assert utils.isnumeric(coefficient), "Coefficient must be a number"
     assert Expression.isExpression(main)
     assert Expression.isExpression(exp)
     self.c = coefficient
     self.main = main
     self.exp = exp
 def __init__(self, coefficient=1, main = X(), exp=1):
     super(PowerTerm, self).__init__()
     assert utils.isnumeric(coefficient), "Coefficient must be a number"
     assert Expression.isExpression(main)
     assert Expression.isExpression(exp)
     self.c = coefficient
     self.main = main
     self.exp = exp
Example #10
0
 def __add__(x1, x2):
     assert map(Expression.isExpression, (x1, x2)
                ), "Arguements must be an Expression"
     if x1.__class__ == x2.__class__:
         return PowerTerm(2, x1, 1)
     if utils.isnumeric(x2):
         return Expression(x1.terms + [x2])
     return Expression(x1.terms + x2.terms)
Example #11
0
 def simplify(self):
     for term in self.terms:
         lst = []
         if utils.isnumeric(term):
             lst.append(term)
         else:
             lst.append(term.simplify())
     self.set_terms(list(filter(lambda x: x, self.terms))) ## NEED TO FIX
     return self
Example #12
0
    def evaluate(self, *args):
        evaluated = []
        for term in self.termsList:
            if utils.isnumeric(term):
                evaluated.append(term)
            else:
                evaluated.append(term(*args))

        return sum(evaluated)
    def evaluate(self, *args):
        evaluated = []
        for term in self.termsList:
            if utils.isnumeric(term):
                evaluated.append(term)
            else:
                evaluated.append(term(*args))

        return sum(evaluated)
 def simplify(self):
     for term in self.terms:
         lst = []
         if utils.isnumeric(term):
             lst.append(term)
         else:
             lst.append(term.simplify())
     self.set_terms(list(filter(lambda x: x, self.terms)))  ## NEED TO FIX
     return self
Example #15
0
 def simplify(self):
     newTerms = []
     for term in self.terms:
         if utils.isnumeric(term):
             if term != 0:
                 newTerms.append(term)
         elif term.c != 0:
             newTerms.append(term)
     self.set_terms(newTerms)
     return self._combine_terms()._sort()
 def simplify(self):
     newTerms = []
     for term in self.terms:
         if utils.isnumeric(term):
             if term != 0:
                 newTerms.append(term)
         elif term.c != 0:
             newTerms.append(term)
     self.set_terms(newTerms)
     return self._combine_terms()._sort()
Example #17
0
 def __mul__(x1, x2):
     assert map(Expression.isExpression, (x1, x2)
                ), "Arguements must be an Expression"
     if x2.__class__ == Expression:
         return x2.__mul__(x1)
     if x1.__class__ == x2.__class__:
         return PowerTerm(1, x1, 2) if x1.var == x2.var else MultTerm((x1, x2))
     if utils.isnumeric(x2):
         return PowerTerm(x2, x1, 1)
     return x2.__mul__(x1)
 def __mul__(x1, x2):
     assert map(Expression.isExpression,
                (x1, x2)), "Arguements must be an Expression"
     if x2.__class__ == Expression:
         return x2.__mul__(x1)
     if x1.__class__ == x2.__class__:
         return PowerTerm(1, x1, 2) if x1.var == x2.var else MultTerm(
             (x1, x2))
     if utils.isnumeric(x2):
         return PowerTerm(x2, x1, 1)
     return x2.__mul__(x1)
Example #19
0
    def reduceCoefficients(self):
        allTerms = self.num.terms + self.den.terms
        coefficients = list(
            term if utils.isnumeric(term) else term.coefficient
                for term in allTerms)

        def gcd_help(x, y):
            x, y = map(abs, (x, y))
            if y > x:
                return gcd_help(y, x)
            if y == 0:
                return x
            return gcd_help(y, x % y)
        gcd = reduce(gcd_help, coefficients)
        for term in allTerms:
            if utils.isnumeric(term):
                term /= gcd
            else:
                term.set_coefficient(term.coefficient / gcd)
        return self
Example #20
0
 def __add__(p1, p2):
     assert map(Expression.isExpression, (p1, p2)
                ), "Arguements must be of type ExponentialTerm"
     if p2 == 0:
         return p1
     if p1.exp == 0 and utils.isnumeric(p2):
         return p2 + p1.c
     if PowerTerm.isPwrTerm(p2) and p1.exp == p2.exp and p1.main == p2.main: # ERROR HERE WITH VAR
         return PowerTerm(p1.c + p2.c, p1.main, p1.exp)
     else:
         return Expression([p1, p2])
    def reduceCoefficients(self):
        allTerms = self.num.terms + self.den.terms
        coefficients = list(term if utils.isnumeric(term) else term.coefficient
                            for term in allTerms)

        def gcd_help(x, y):
            x, y = map(abs, (x, y))
            if y > x:
                return gcd_help(y, x)
            if y == 0:
                return x
            return gcd_help(y, x % y)

        gcd = reduce(gcd_help, coefficients)
        for term in allTerms:
            if utils.isnumeric(term):
                term /= gcd
            else:
                term.set_coefficient(term.coefficient / gcd)
        return self
 def __add__(p1, p2):
     assert map(Expression.isExpression,
                (p1, p2)), "Arguements must be of type ExponentialTerm"
     if p2 == 0:
         return p1
     if p1.exp == 0 and utils.isnumeric(p2):
         return p2 + p1.c
     if PowerTerm.isPwrTerm(
             p2
     ) and p1.exp == p2.exp and p1.main == p2.main:  # ERROR HERE WITH VAR
         return PowerTerm(p1.c + p2.c, p1.main, p1.exp)
     else:
         return Expression([p1, p2])
    def __mul__(p1, p2):
        assert map(Expression.isExpression,
                   (p1, p2)), "Arguements must be of type ExponentialTerm"
        if p2.__class__ == Expression:
            return p2.__mul__(p1)
        if p1.__class__ == p2.__class__ and p1.main == p2.main:
            return PowerTerm(p1.c * p2.c, p1.main, p1.exp + p2.exp)
        if p2 == p1.main:
            copy = p1.copy()
            return copy.set_exp(copy.exp + 1)
        if utils.isnumeric(p2):
            return PowerTerm(p1.c * p2, p1.main, p1.exp)
        if p2.__class__ == Fraction:
            return p2.__mul__(p1)

        return MultTerm([p1, p2])
Example #24
0
    def __mul__(p1, p2):
        assert map(Expression.isExpression, (p1, p2)
                   ), "Arguements must be of type ExponentialTerm"
        if p2.__class__ == Expression:
            return p2.__mul__(p1)
        if p1.__class__ == p2.__class__ and p1.main == p2.main:
            return PowerTerm(p1.c * p2.c, p1.main, p1.exp + p2.exp)
        if p2 == p1.main:
            copy = p1.copy()
            return copy.set_exp(copy.exp + 1)
        if utils.isnumeric(p2):
            return PowerTerm(p1.c * p2, p1.main, p1.exp)
        if p2.__class__ == Fraction:
            return p2.__mul__(p1)

        return MultTerm([p1, p2])
Example #25
0
    def __init__(self, terms):
        super(MultTerm, self).__init__()
        self.termsMultiplied = list(terms)
        self.c = 1
        for term in self.termsMultiplied:
            if MultTerm.isMultTerm(term):
                self.termsMultiplied.extend(term.termsMultiplied)
                self.c *= term.c
                self.termsMultiplied.remove(term)

        for term in self.termsMultiplied:
            if utils.isnumeric(term):
                self.c *= term
                self.termsMultiplied.remove(term)
            else:
                self.c *= term.c
                term.set_coefficient(1)
    def __init__(self, terms):
        super(MultTerm, self).__init__()
        self.termsMultiplied = list(terms)
        self.c = 1
        for term in self.termsMultiplied:
            if MultTerm.isMultTerm(term):
                self.termsMultiplied.extend(term.termsMultiplied)
                self.c *= term.c
                self.termsMultiplied.remove(term)

        for term in self.termsMultiplied:
            if utils.isnumeric(term):
                self.c *= term
                self.termsMultiplied.remove(term)
            else:
                self.c *= term.c
                term.set_coefficient(1)
 def __str__(self):
     output = ""
     for term in self.terms:
         c = exp = 0
         if utils.isnumeric(term):
             c = term
         else:
             c, exp = term.c, term.exp
         if c == 0:
             continue
         elif exp == 0:
             output += str(c) + " + "
         elif c == 1:
             output += "x^" + str(exp) + " + "
         else:
             output += str(c) + "x^" + str(exp) + " + "
     output = output[:len(output) - 3]
     if output == "":
         return "0"
     return output
Example #28
0
 def __str__(self):
     output = ""
     for term in self.terms:
         c = exp = 0
         if utils.isnumeric(term):
             c = term
         else:
             c, exp = term.c, term.exp
         if c == 0:
             continue
         elif exp == 0:
             output += str(c) + " + "
         elif c == 1:
             output += "x^" + str(exp) + " + "
         else:
             output += str(c) +  "x^" + str(exp) + " + "
     output = output[: len(output) - 3]
     if output == "":
         return "0"
     return output
 def polify(p):
     if Polynomial.isPolynomial(p):
         return p
     return Polynomial([p]) if utils.isnumeric(p) else Polynomial(p.terms)
 def degree(self):
     degree_fn = lambda x: 0 if utils.isnumeric(x) else x.exp
     return max(list(map(degree_fn, self.terms)))
Example #31
0
 def evaluate(self, *args):
     i, b = self.insideTerm, self.base
     insideVal = i if utils.isnumeric(i) else i(*args)
     baseVal = b if utils.isnumeric(b) else b(*args)
     return self.c * math.log(insideVal, baseVal)
Example #32
0
 def __call__(self, *args):
     assert all(map(lambda x: utils.isnumeric(x[1]), args))
     return self.evaluate(*args)
Example #33
0
 def _combine_terms(self):
     degree_fn = lambda x: 0 if utils.isnumeric(x) else x.exp
     sep_degrees = utils.list_to_listOfTypes(self.terms, degree_fn)
     self.set_terms(list(map(sum, sep_degrees)))
     return self
 def __call__(self, *args):
     assert all(map(lambda x: utils.isnumeric(x[1]), args))
     return self.evaluate(*args)
Example #35
0
 def _sort(self):
     degree_fn = lambda x: 0 if utils.isnumeric(x) else x.exp
     self.set_terms(sorted(self.terms, key = degree_fn, reverse = True))
     return self
 def evaluate(self, *args):
     m, e = self.main, self.exp
     mainVal = m if utils.isnumeric(m) else m(*args)
     expVal = e if utils.isnumeric(e) else e(*args)
     return self.c * pow(mainVal, expVal)
 def evaluate(self, *args):
     expVal = self.exp if utils.isnumeric(self.exp) else self.exp(*args)
     return self.c * math.exp(expVal)
 def evaluate(self, *args):
     i, b = self.insideTerm, self.base
     insideVal = i if utils.isnumeric(i) else i(*args)
     baseVal = b if utils.isnumeric(b) else b(*args)
     return self.c * math.log(insideVal, baseVal)
 def _combine_terms(self):
     degree_fn = lambda x: 0 if utils.isnumeric(x) else x.exp
     sep_degrees = utils.list_to_listOfTypes(self.terms, degree_fn)
     self.set_terms(list(map(sum, sep_degrees)))
     return self
Example #40
0
 def polify(p):
     if Polynomial.isPolynomial(p):
         return p
     return Polynomial([p]) if utils.isnumeric(p) else Polynomial(p.terms)
 def _sort(self):
     degree_fn = lambda x: 0 if utils.isnumeric(x) else x.exp
     self.set_terms(sorted(self.terms, key=degree_fn, reverse=True))
     return self
Example #42
0
 def degree(self):
     degree_fn = lambda x: 0 if utils.isnumeric(x) else x.exp
     return max(list(map(degree_fn, self.terms)))
Example #43
0
 def __div__(e1, e2):
     """ p1  divided by p2 -> p1/p2 """
     # Error Handling done in Mul
     if utils.isnumeric(e2):
         return e1 * (1.0/e2)
     return e1 * e2.reciprocal()
Example #44
0
 def evaluate(self, *args):
     m, e = self.main, self.exp
     mainVal = m if utils.isnumeric(m) else m(*args)
     expVal = e if utils.isnumeric(e) else e(*args)
     return self.c * pow(mainVal, expVal)
Example #45
0
 def evaluate(self, *args):
     expVal = self.exp if utils.isnumeric(self.exp) else self.exp(*args)
     return self.c * math.exp(expVal)
 def isExpression(e):
     return isinstance(e, Expression) or utils.isnumeric(e)
 def __div__(e1, e2):
     """ p1  divided by p2 -> p1/p2 """
     # Error Handling done in Mul
     if utils.isnumeric(e2):
         return e1 * (1.0 / e2)
     return e1 * e2.reciprocal()
Example #48
0
 def isExpression(e):
     return isinstance(e, Expression) or utils.isnumeric(e)
Example #49
0
def encode_single(typ, arg):
    base, sub, _ = typ
    # Unsigned integers: uint<sz>
    if base == 'uint':
        sub = int(sub)
        i = decint(arg, False)

        if not 0 <= i < 2 ** sub:
            raise ValueOutOfBounds(repr(arg))
        return zpad(encode_int(i), 32)
    # bool: int<sz>
    elif base == 'bool':
        assert isinstance(arg, bool)
        return zpad(encode_int(int(arg)), 32)
    # Signed integers: int<sz>
    elif base == 'int':
        sub = int(sub)
        i = decint(arg, True)
        if not -2 ** (sub - 1) <= i < 2 ** (sub - 1):
            raise ValueOutOfBounds(repr(arg))
        return zpad(encode_int(i % 2 ** sub), 32)
    # Unsigned reals: ureal<high>x<low>
    elif base == 'ureal':
        high, low = [int(x) for x in sub.split('x')]
        if not 0 <= arg < 2 ** high:
            raise ValueOutOfBounds(repr(arg))
        return zpad(encode_int(int(arg * 2 ** low)), 32)
    # Signed reals: real<high>x<low>
    elif base == 'real':
        high, low = [int(x) for x in sub.split('x')]
        if not -2 ** (high - 1) <= arg < 2 ** (high - 1):
            raise ValueOutOfBounds(repr(arg))
        i = int(arg * 2 ** low)
        return zpad(encode_int(i % 2 ** (high + low)), 32)
    # Strings
    elif base == 'string' or base == 'bytes':
        if not is_string(arg):
            raise EncodingError("Expecting string: %r" % arg)
        # Fixed length: string<sz>
        if len(sub):
            assert int(sub) <= 32
            assert len(arg) <= int(sub)
            return arg + b'\x00' * (32 - len(arg))
        # Variable length: string
        else:
            return zpad(encode_int(len(arg)), 32) + \
                arg + \
                b'\x00' * (utils.ceil32(len(arg)) - len(arg))
    # Hashes: hash<sz>
    elif base == 'hash':
        if not (int(sub) and int(sub) <= 32):
            raise EncodingError("too long: %r" % arg)
        if isnumeric(arg):
            return zpad(encode_int(arg), 32)
        elif len(arg) == int(sub):
            return zpad(arg, 32)
        elif len(arg) == int(sub) * 2:
            return zpad(decode_hex(arg), 32)
        else:
            raise EncodingError("Could not parse hash: %r" % arg)
    # Addresses: address (== hash160)
    elif base == 'address':
        assert sub == ''
        if isnumeric(arg):
            return zpad(encode_int(arg), 32)
        elif len(arg) == 20:
            return zpad(arg, 32)
        elif len(arg) == 40:
            return zpad(decode_hex(arg), 32)
        elif len(arg) == 42 and arg[:2] in {'0x', b'0x'}:
            return zpad(decode_hex(arg[2:]), 32)
        else:
            raise EncodingError("Could not parse address: %r" % arg)
    raise EncodingError("Unhandled type: %r %r" % (base, sub))
Example #50
0
def encode_single(typ, arg):
    base, sub, _ = typ
    # Unsigned integers: uint<sz>
    if base == 'uint':
        sub = int(sub)
        i = decint(arg, False)

        if not 0 <= i < 2**sub:
            raise ValueOutOfBounds(repr(arg))
        return zpad(encode_int(i), 32)
    # bool: int<sz>
    elif base == 'bool':
        assert isinstance(arg, bool)
        return zpad(encode_int(int(arg)), 32)
    # Signed integers: int<sz>
    elif base == 'int':
        sub = int(sub)
        i = decint(arg, True)
        if not -2**(sub - 1) <= i < 2**(sub - 1):
            raise ValueOutOfBounds(repr(arg))
        return zpad(encode_int(i % 2**sub), 32)
    # Unsigned reals: ureal<high>x<low>
    elif base == 'ureal':
        high, low = [int(x) for x in sub.split('x')]
        if not 0 <= arg < 2**high:
            raise ValueOutOfBounds(repr(arg))
        return zpad(encode_int(int(arg * 2**low)), 32)
    # Signed reals: real<high>x<low>
    elif base == 'real':
        high, low = [int(x) for x in sub.split('x')]
        if not -2**(high - 1) <= arg < 2**(high - 1):
            raise ValueOutOfBounds(repr(arg))
        i = int(arg * 2**low)
        return zpad(encode_int(i % 2**(high + low)), 32)
    # Strings
    elif base == 'string' or base == 'bytes':
        if not is_string(arg):
            raise EncodingError("Expecting string: %r" % arg)
        # Fixed length: string<sz>
        if len(sub):
            assert int(sub) <= 32
            assert len(arg) <= int(sub)
            return arg + b'\x00' * (32 - len(arg))
        # Variable length: string
        else:
            return zpad(encode_int(len(arg)), 32) + \
                arg + \
                b'\x00' * (utils.ceil32(len(arg)) - len(arg))
    # Hashes: hash<sz>
    elif base == 'hash':
        if not (int(sub) and int(sub) <= 32):
            raise EncodingError("too long: %r" % arg)
        if isnumeric(arg):
            return zpad(encode_int(arg), 32)
        elif len(arg) == int(sub):
            return zpad(arg, 32)
        elif len(arg) == int(sub) * 2:
            return zpad(decode_hex(arg), 32)
        else:
            raise EncodingError("Could not parse hash: %r" % arg)
    # Addresses: address (== hash160)
    elif base == 'address':
        assert sub == ''
        if isnumeric(arg):
            return zpad(encode_int(arg), 32)
        elif len(arg) == 20:
            return zpad(arg, 32)
        elif len(arg) == 40:
            return zpad(decode_hex(arg), 32)
        elif len(arg) == 42 and arg[:2] == '0x':
            return zpad(decode_hex(arg[2:]), 32)
        else:
            raise EncodingError("Could not parse address: %r" % arg)
    raise EncodingError("Unhandled type: %r %r" % (base, sub))