コード例 #1
0
    def __new__(cls, *var, **options):
        if not options:
            self = super().__new__(ZZ)
        else:
            if "complex" in options:
                if options["complex"]:
                    self = super().__new__(CC)
            elif "rational" in options:
                if options["rational"]:
                    self = super().__new__(QQ)
            elif "mod" in options:
                validate_type(options["mod"], int)
                if options["mod"] < 0:
                    raise ValueError(
                        "modulus option must be 0 or positive integer")
                elif options["mod"] > 0:
                    """ positive characteristic """
                    """ 
						* Require Updates !! 
						Given variables without relation, must return infinite objects.

					"""
                    if is_prime(options["mod"]):
                        self = super().__new__(FiniteField)
                    else:
                        self = super().__new__(FiniteRing)
                else:
                    self = super().__new__(ZZ)
            else:
                self = super().__new__(ZZ)
        return self
コード例 #2
0
def factor(f, deg=0):
    validate_type(f, Poly)
    validate_type(deg, int)
    if deg == 0:
        """
			calculate with Cantor-Zassenhaus algorithm
		"""
        pass
    else:
        if not f.is_univariate():
            raise ValueError("f must be a univatiate polynomial")
        var = f.get_univariate()
        r, q = f.degree(var) // deg, f.coeff_dom.number()
        dom_ = f.dom.add_quotient(f.rep)
        F = [f]
        while len(F) < r:
            g = poly(f.dom.random(deg=r * deg - 1, monic=True), dom=dom_)
            g = g**((q**deg - 1) // 2) - 1
            g = poly(g.rep, *f.indet_vars, dom=f.dom)
            if g == 0:
                continue
            F_1 = list()
            while len(F) > 0:
                h = F.pop()
                if h.degree(var) <= deg:
                    continue
                z = gcd(h, g)
                if z == 1 or z == h:
                    F_1.append(h)
                else:
                    F_1.append(z)
                    F_1.append(h // z)
            F = F_1
        return F
コード例 #3
0
def dp_from_int(n, var):
    validate_type(n, int)
    validate_type(var, (tuple, list))
    coeffs_ = [n]
    for v in var[1:][::-1]:
        coeffs_ = [dp(v, coeffs_)]
    return dp(var[0], coeffs_)
コード例 #4
0
def symbols(c):
    validate_type(c, str)
    symbols_ = c.replace(" ", "").split(",")
    if len(symbols_) == 1:
        return symbol(symbols_[0])
    else:
        return tuple([symbol(s) for s in symbols_])
コード例 #5
0
def as_dp(f, *symbol):
    validate_type(f, int, Symbol, DP)
    if isinstance(f, int):
        if len(symbol) == 0:
            raise ValueError("needs one symbol when f is int")
        else:
            return dp(symbol[0], [f])
    elif isinstance(f, Symbol):
        return f.as_dp()
    else:
        return f
コード例 #6
0
def gcd(f, g):
    validate_type(f, Poly)
    validate_type(g, Poly)
    if not f.is_univariate() or not g.is_univariate():
        raise TypeError("arguments must be univariate polynomials")
    if f.degree() < g.degree():
        f, g = g, f
    q = f % g
    if q == 0:
        return g
    else:
        return gcd(g, q).get_monic()
コード例 #7
0
 def __pow__(f, e):
     validate_type(e, int)
     if e < 0:
         raise ValueError("exponent must be positive")
     if e == 0:
         return poly(1, *f.indet_vars, dom=f.dom)
     num_ = bin(e).replace('0b', '')
     pow_ = 1
     for i in num_:
         pow_ = pow_ * pow_
         if i == '1':
             pow_ = f * pow_
     return pow_
コード例 #8
0
 def extend(self, var, rel=0):
     validate_type(var, Symbol)
     if var in self.const_vars:
         raise ValueError("it already has the variable '%s'" % str(var))
     validate_type(rel, int, DP)
     const_vars_ = self.const_vars + (var, )
     if rel == 0:
         return ring(*const_vars_, mod=self.mod, rel=self.rel)
     else:
         if self.rel == 0:
             return ring(*const_vars_, mod=self.mod, rel=rel)
         else:
             dps_ = self.rel.as_tuple() + (rel, )
             return ring(*const_vars_, mod=self.mod, rel=dps_)
コード例 #9
0
def diff(f, *var):
    validate_type(f, Poly)
    if len(var) > 1:
        raise ValueError(
            "the number of variable argument must be 0 or 1, not %s" %
            str(len(var)))
    elif len(var) == 1:
        var_ = var[0]
        sorted_vars = tuple_union(var, tuple_minus(f.inner_vars, var))
        rep_ = f.rep.sort_vars(sorted_vars)
    else:
        var_ = f.indet_vars[0]
        rep_ = f.rep

    return poly(rep_.diff(var_), *f.indet_vars, dom=f.dom)
コード例 #10
0
 def reduce(self, rep):
     validate_type(rep, DP, int)
     if isinstance(rep, int):
         if self.reduction_step["mod"]:
             rep = rep % self.mod
         return rep
     else:
         reduce_ = rep
         if self.reduction_step["quo"]:
             reduce_ = _reduce(reduce_, self.quo)
         if self.reduction_step["rel"]:
             reduce_ = _reduce(reduce_, self.rel)
         if self.reduction_step["mod"]:
             reduce_ = reduce_ % self.mod
     return reduce_
コード例 #11
0
 def diff(self, var):
     validate_type(var, Symbol)
     if not var in self.inner_vars:
         return dp(self.var, (0, ))
     else:
         coeffs_ = list()
         if var == self.var:
             for i in range(len(self) - 1):
                 coeffs_.append(self[i + 1] * (i + 1))
         else:
             for c in self:
                 if isinstance(c, int):
                     coeffs_.append(0)
                 else:
                     coeffs_.append(c.diff(var))
         return dp(self.var, coeffs_)
コード例 #12
0
 def as_dist_tuple(self, termorder="lex", with_index=False):
     validate_type(termorder, str)
     if termorder == "lex":
         iters, list_ = list(), list()
         for v in self.inner_vars[::-1]:
             iters.append(range(self.degree(v) + 1)[::-1])
         for p in itertools.product(*iters):
             if with_index:
                 list_.append((p[::-1], self[p[::-1]]))
             else:
                 list_.append(self[p[::-1]])
     elif termorder == "grevlex":
         raise NotImplementedError()
     else:
         raise TypeError("given unsupported termorder '%s'" % termorder)
     return tuple(list_)
コード例 #13
0
def dp_from_dict(var, coeffs):
    validate_type(coeffs, dict)
    if len(var) == 0:
        raise ValueError("needs one variable at least")
    if len(var) == 1:
        coeffs_, i, j = [], 0, 0
        while i < len(coeffs):
            try:
                coeffs_.append(coeffs[j])
                i += 1
            except KeyError:
                coeffs_.append(0)
            finally:
                j += 1
        return dp(var[0], coeffs_)
    else:
        pass
コード例 #14
0
def dp_from_list(var, coeffs):
    validate_type(coeffs, tuple, list)
    if len(var) == 0:
        raise ValueError("needs one variable at least")
    if len(var) == 1:
        return dp(var[0], coeffs)
    else:
        coeffs_ = []
        for r in coeffs:
            if isinstance(r, list):
                coeffs_.append(dp_from_list(var[1:], r))
            elif isinstance(r, int):
                coeffs_.append(r)
            else:
                raise ValueError(
                    "elements of coeffs list must be int or dp, not %s" %
                    r.__class__.__name__)
        return dp(var[0], coeffs_)
コード例 #15
0
 def it_dist(self, termorder="lex", with_index=False):
     validate_type(termorder, str)
     if termorder == "lex":
         iters = [
             range(self.degree(v, non_negative=True), -1, -1)
             for v in self.inner_vars
         ]
         for p in itertools.product(*iters):
             c = self[p]
             if c == 0:
                 continue
             if with_index:
                 yield (p, c)
             else:
                 yield c
     elif termorder == "grevlex":
         raise NotImplementedError()
     else:
         raise TypeError("given unsupported termorder '%s'" % termorder)
コード例 #16
0
 def subs(self, subsdict):
     validate_type(subsdict, dict)
     f_ = self
     for k, v in subsdict.items():
         if isinstance(k, Symbol):
             k = as_dp(k).sort_vars(self.inner_vars)
         elif isinstance(k, DP):
             if k.is_monomial():
                 if k.is_monic():
                     k = k.sort_vars(self.inner_vars)
                 else:
                     raise ValueError("keys of subsdict must be monic")
             else:
                 raise ValueError("keys of subsdict must be monomial")
         else:
             raise TypeError(
                 "keys of subsdict must be Symbol or DP, not '%s'" %
                 k.__class__.__name__)
         f_ = f_._subs(k, v)
     return f_
コード例 #17
0
    def __init__(self, value, *var, **options):
        validate_type(value, dict, tuple, list)
        if isinstance(value, dict):
            self.value_dict = value
        else:
            self.value_dict = dict()
            if not var:
                raise ValueError("require variable with value tuple")
            i = 0
            for v in var:
                self.value_dict[v] = valur[0]
                i += 1

        if "coeff_dom" in options:
            self.coeff_dom = options["coeff_dom"]
        else:
            self.coeff_dom = ring()

        if "proj" in options and options["proj"]:
            self.affine = False
        else:
            self.affine = True
コード例 #18
0
    def __init__(self, *var, **options):
        """
		Arugments:
		* var: indeterminate variables
		* options: allowed keys are "quo" and them of Rings'
		"""

        self.indet_vars = var

        if "coeff_dom" in options:
            validate_type(options["coeff_dom"], Ring)
            self.coeff_dom = options["coeff_dom"]
        else:
            self.coeff_dom = ring(**options)

        self.reduction_step = dict()

        if not self.coeff_dom.mod == 0:
            self.mod = self.coeff_dom.mod
            self.reduction_step["mod"] = True
        else:
            self.mod = 0
            self.reduction_step["mod"] = False

        if not self.coeff_dom.rel == 0:
            self.rel = relation(self.coeff_dom.rel)
            self.reduction_step["rel"] = True
        else:
            self.rel = 0
            self.reduction_step["rel"] = False

        self.const_vars = self.coeff_dom.const_vars

        if "quo" in options and not isinstance(options["quo"], int):
            self.quo = relation(options["quo"])
            self.reduction_step["quo"] = True
        else:
            self.quo = 0
            self.reduction_step["quo"] = False
コード例 #19
0
    def it_dist(self, termorder="lex", with_index=False, zero_skip=True):
        """
		generate coefficients of each index of exponents,
		return int or DP object with index tuple if with_index is True.
		"""

        validate_type(termorder, str)
        if termorder == "lex":
            iters = [
                range(self.degree(v, non_negative=True), -1, -1)
                for v in self.indet_vars
            ]
            for p in itertools.product(*iters):
                c = self.rep[p]
                if zero_skip and c == 0:
                    continue
                if with_index:
                    yield (p, c)
                else:
                    yield c
        elif termorder == "grevlex":
            raise NotImplementedError()
        else:
            raise TypeError("given unsupported termorder '%s'" % termorder)
コード例 #20
0
    def __init__(self, rep, *var, **options):
        if isinstance(rep, Poly):
            self.rep = rep.rep
            self.indet_vars = rep.indet_vars
            self.const_vars = rep.const_vars
            self.inner_vars = rep.inner_vars
            self.coeff_dom = rep.coeff_dom
            self.dom = rep.dom
        else:
            if isinstance(rep, DP):
                pass
            elif isinstance(rep, int):
                rep = dp_from_int(rep, var)
            elif isinstance(rep, Symbol):
                rep = rep.as_dp()
            else:
                raise TypeError("rep must be Poly or DP, not %s" %
                                rep.__class__.__name__)
            """

			* Set domain options

			Given "dom" option, initialize with it.
			Not given, construct PolynomialRing object and set to "dom" option

			"""

            if "dom" in options:
                validate_type(options["dom"], PolynomialRing)
                dom = options["dom"]
                self.indet_vars, self.const_vars = self._set_var(
                    rep, tuple_union(dom.indet_vars, var))
                self.inner_vars = tuple_union(self.indet_vars, self.const_vars)
                self.coeff_dom = ring(*self.const_vars,
                                      mod=dom.coeff_dom.mod,
                                      rel=dom.coeff_dom.rel)
                self.dom = polynomialring(*self.indet_vars,
                                          coeff_dom=self.coeff_dom,
                                          quo=dom.quo)
            else:
                self.indet_vars, self.const_vars = self._set_var(rep, var)
                self.inner_vars = tuple_union(self.indet_vars, self.const_vars)

                if "coeff_dom" in options:
                    validate_type(options["coeff_dom"], Ring)
                    self.coeff_dom = options["coeff_dom"]
                else:
                    if "mod" in options:
                        validate_type(options["mod"], int)
                        mod = options["mod"]
                    else:
                        mod = 0

                    if "rel" in options:
                        validate_type(options["rel"], int, tuple, DP, Relation)
                        rel = options["rel"]
                    else:
                        rel = 0

                    self.coeff_dom = ring(*self.const_vars, mod=mod, rel=rel)
                    if len(self.coeff_dom.const_vars) == 0:
                        pass
                    else:
                        self.rep = self.rep.sort_vars(
                            tuple_union(self.inner_vars,
                                        self.coeff_dom.const_vars))

                if "quo" in options:
                    validate_type(options["rel"], int, tuple, DP, Relation)
                    quo = options["rel"]
                else:
                    quo = 0

                self.dom = polynomialring(*self.indet_vars,
                                          coeff_dom=self.coeff_dom,
                                          quo=quo)
            self.rep = self.reduce()
コード例 #21
0
def LC(f, termorder="lex"):
    validate_type(f, Poly)
    lc_ = next(f.it_dist(zero_skip=False))
    return poly(lc_, *f.indet_vars, dom=f.dom)
コード例 #22
0
 def __init__(self, char):
     validate_type(char, str)
     self.char = char
コード例 #23
0
 def __mul__(p, n):
     validate_type(n, int, DP)
     for v in self:
         self[v] *= n
コード例 #24
0
def symbol(c):
    validate_type(c, str)
    return Symbol(c)