Exemplo n.º 1
0
    def __call__(self, *args, **kwds):
        if args and kwds:
            raise TypeError("You can pass either positional or keyword "
                            "arguments, but not both.")
        elif len(args or kwds) != self.dimension:
            raise TypeError("You must pass exactly {} "
                            "value(s) ({} given).".format(self.dimension,
                                                          len(args or kwds)))
        elif not args and tuple(sorted(iterkeys(kwds))) != self.letters:
            diff_set = set(iterkeys(kwds)) - set(self.letters)
            diff_joint = "', '".join(diff_set)
            raise TypeError("Invalid letter(s): '{}'".format(diff_joint))

        if args:
            for i, l in enumerate(self.letters):
                kwds[l] = args[i]

        if any(not isinstance(v, numbers.Number) for v in itervalues(kwds)):
            sorted_list = sorted(v for v in itervalues(kwds)\
                                 if not isinstance(v, numbers.Number))
            inv_joint = "', '".join(sorted_list)
            raise TypeError("Invalid value for letter(s): "
                            "'{}'".format(inv_joint))

        if not self:
            return 0
        elif self.is_constant():
            return sum(m[0] for m in self._monomials)

        return sum(c * functools.reduce(operator.mul,
                                        (kwds[x] ** l[x] for x in l), 1)\
                   for c, l in self._monomials)
Exemplo n.º 2
0
    def letters(self):
        if not self:
            return ()

        letters = []
        for c, ls in self._monomials:
            for l in iterkeys(ls):
                if l not in letters:
                    letters.append(l)

        return tuple(sorted(letters))
Exemplo n.º 3
0
def gcd(x, y, *args):
    if args:
        return gcd(gcd(x, y), args[0], *args[1:])
    if not x and not y:
        return 1

    if isinstance(x, float):
        x = fractions.Fraction(x).limit_denominator()

    if isinstance(y, float):
        y = fractions.Fraction(y).limit_denominator()

    x = abs(x) if isinstance(x, numbers.Real) else x
    y = abs(y) if isinstance(y, numbers.Real) else y

    if x == 0:
        return y
    elif y == 0:
        return x
    elif isinstance(x, complex) and not x.real and not isinstance(y, complex) or\
              isinstance(y, complex) and not y.real and not isinstance(x, complex):
        return 1

    try:
        if x.is_monomial() and y.is_monomial() or x.is_constant() or y.is_constant():
            coeff = gcd(x.monomials[0][0], y.monomials[0][0])
            letters = {}
            for l in iterkeys(x.monomials[0][1]):
                d_x = x.monomials[0][1][l]
                d_y = y.monomials[0][1].get(l, 0)
                letters[l] = min((d_x, d_y))
            return x.from_iterable([[coeff, letters]])
    except AttributeError:
        pass

    if (not isinstance(x, numbers.Number)) ^\
       (not isinstance(y, numbers.Number)):
        try:
            integer, poly = (x, y) if isinstance(x, numbers.Number) else (y, x)
            return gcd(functools.reduce(gcd, poly.coefficients), integer)
        except AttributeError:
            pass

    while True:
        r = x % y
        degree = y.degree if hasattr(y, "degree") else 1
        if not r and degree == 1:
            return y
        elif not degree:
            return 1
        x, y = y, r
Exemplo n.º 4
0
    def sort(self, letter=None, reverse=False):
        if letter is not None and (not is_letter_valid(letter) or\
                                   letter not in self.letters):
            raise ValueError("The letter must be a single letter from the "
                             "alphabet contained in the Polynomial.")
        elif len(self) in (0, 1):
            return
        elif self.is_constant():
            return

        def _sort(monomials, letter=None):
            if letter is None:
                return sorted((m for m in monomials if not m[1]),
                              key=lambda m: m[0], reverse=True)
            return sorted((m for m in monomials if letter in m[1]),
                          key=lambda m: m[1][letter], reverse=True)

        degrees = self.all_max_letter_degrees
        letters = sorted(iterkeys(degrees),
                         key=lambda l: (degrees[l], 255 - ord(l)),
                         reverse=True)

        preferenced_letters = sorted(l for l in letters\
                                     if l in self.preferenced_letters)

        if preferenced_letters and letter is None:
            letter = preferenced_letters.pop(0)
        elif letter is None:
            letter = letters[0]

        letters.remove(letter)

        lower_letters = [l for l in letters\
                         if l.islower() and l not in preferenced_letters]
        upper_letters = [l for l in letters\
                         if l.isupper() and l not in preferenced_letters]

        letters = [letter] + preferenced_letters +\
                  lower_letters + upper_letters

        monomials = []
        for l in letters:
            for m in _sort(self._monomials, l):
                if m not in monomials:
                    monomials.append(m)
        for m in _sort(self._monomials):
            if m not in monomials:
                monomials.append(m)
        if reverse:
            monomials.reverse()
        self._monomials = monomials
Exemplo n.º 5
0
    def __repr__(self):
        if not self:
            return "0"

        poly_str = ""
        for m in self._monomials:
            mono_str = ("+ " if m[0] >= 0 and poly_str else "") +\
                       str(m[0]).replace("-", "- ")
            if m[1] and m[0] in (1, -1):
                mono_str = mono_str.replace("1", "")
            for l in sorted(iterkeys(m[1])):
                mono_str += l
                if m[1][l] == 1:
                    continue
                mono_str += "^" + str(m[1][l])
            poly_str += " " + mono_str

        return poly_str[1:]