コード例 #1
0
ファイル: algebra.py プロジェクト: Alexey95/physpy
 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
コード例 #2
0
ファイル: algebra.py プロジェクト: Alexey95/physpy
 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)
コード例 #3
0
ファイル: algebra.py プロジェクト: Alexey95/physpy
    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)])
コード例 #4
0
ファイル: algebra.py プロジェクト: Alexey95/physpy
    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
コード例 #5
0
ファイル: algebra.py プロジェクト: Alexey95/physpy
    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)
コード例 #6
0
ファイル: algebra.py プロジェクト: Alexey95/physpy
 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
コード例 #7
0
ファイル: algebra.py プロジェクト: Alexey95/physpy
    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)
コード例 #8
0
ファイル: algebra.py プロジェクト: Alexey95/physpy
 def sqrt(m):
     c = m[0] ** 0.5
     l = {v: d / 2 for v, d in iteritems(m[1])}
     return [c, l]
コード例 #9
0
ファイル: algebra.py プロジェクト: Alexey95/physpy
 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]])