def div_monomials(m1, m2): letters = m1[1].copy() for l, d in iteritems(m2[1]): letters[l] -= d m = [[fractions.Fraction(m1[0], m2[0]), letters]] p = Polynomial.from_iterable(m) return p
def max_degree_of_letter(self, letter): if not is_letter_valid(letter): raise ValueError("The letter must be a single letter from the " "alphabet.") elif letter not in self.letters: return 0 all_vars = (l for c, l in self._monomials) return max(d for v in all_vars for l, d in iteritems(v) if l == letter)
def _simplify(self): if self._monomials == [[0, {}]]: self._monomials = [] return elif not self: return monos = collections.OrderedDict() for c, l in self._monomials: l = tuple(l for l in iteritems(l) if l[1]) if l in monos: monos[l].append(c) else: monos[l] = [c] self._monomials = [] for l, c in iteritems(monos): c = sum(c) if not c: continue self._monomials.append([c, dict(l)])
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(): s1 = sum(m[0] for m in self._numerator._monomials) s2 = sum(m[0] for m in self._denominator._monomials) return fractions.Fraction(s1) / s2 kwds1 = {} kwds2 = {} for l, v in iteritems(kwds): if l in self.numerator.letters: kwds1[l] = v if l in self.denominator.letters: kwds2[l] = v s1 = sum(c * functools.reduce(operator.mul, (kwds1[x] ** l[x] for x in l), 1)\ for c, l in self._numerator._monomials) s2 = sum(c * functools.reduce(operator.mul, (kwds2[x] ** l[x] for x in l), 1)\ for c, l in self._denominator._monomials) return fractions.Fraction(s1) / s2
def __mul__(self, other): if not isinstance(other, Polynomial): raise TypeError("Only multiplication between Polynomial instances " "is allowed.") monos = [] for c1, l1 in self._monomials: for c2, l2 in other._monomials: l = l1.copy() for letter, degree in iteritems(l2): if letter in l: l[letter] += degree else: l[letter] = degree monos.append([c1 * c2, l]) return Polynomial.from_iterable(monos)
def check_and_convert_iterable(iterable): monos = [] for c, letters in iterable: if not isinstance(c, numbers.Number): raise ValueError("The coefficient must be a number.") vars_ = {} it = iteritems(letters) if isinstance(letters, dict)\ else letters for letter, degree in it: if not is_letter_valid(letter): raise ValueError("All letters must be a single letter " "from the alphabet.") elif not is_degree_valid(degree): raise ValueError("The degree of each variable must be " "a positive integer.") vars_[letter] = degree monos.append([fractions.Fraction(str(c)), vars_]) return monos
def __pow__(self, exp): if not isinstance(exp, int): raise TypeError("Exponent must be an integer.") elif exp < 0: return 1 / (self ** (-exp)) elif exp == 0: return Polynomial("1") elif not self: return Polynomial() elif self.is_monomial(): m = list(self.monomials[0]) m[0] = m[0] ** exp m[1] = {l: e * exp for l, e in iteritems(m[1])} return Polynomial.from_iterable([m]) elif self.is_binomial(): a = Polynomial.from_iterable([self._monomials[0]]) b = Polynomial.from_iterable([self._monomials[1]]) return sum(coeff * a ** (exp - k) * b ** k for k, coeff in enumerate(bin_coeffs(exp))) return functools.reduce(operator.mul, [self] * exp)
def sqrt(m): c = m[0] ** 0.5 l = {v: d / 2 for v, d in iteritems(m[1])} return [c, l]
def sqrt_m(m): c = abs(m[0]) ** 0.5 l = {l: d / 2 for l, d in iteritems(m[1])} return Polynomial.from_iterable([[c, l]])