def test_pickling_polys_errors(): # TODO: TypeError: __init__() takes at least 3 arguments (1 given) # for c in (ExactQuotientFailed, ExactQuotientFailed(x, 3*x, ZZ)): # check(c) # TODO: TypeError: can't pickle instancemethod objects # for c in (OperationNotSupported, OperationNotSupported(Poly(x), Poly.gcd)): # check(c) for c in (HeuristicGCDFailed, HeuristicGCDFailed(), HomomorphismFailed, HomomorphismFailed(), IsomorphismFailed, IsomorphismFailed(), ExtraneousFactors, ExtraneousFactors(), EvaluationFailed, EvaluationFailed(), RefinementFailed, RefinementFailed(), CoercionFailed, CoercionFailed(), NotInvertible, NotInvertible(), NotReversible, NotReversible(), NotAlgebraic, NotAlgebraic(), DomainError, DomainError(), PolynomialError, PolynomialError(), UnificationFailed, UnificationFailed(), GeneratorsError, GeneratorsError(), GeneratorsNeeded, GeneratorsNeeded()): check(c) # TODO: PicklingError: Can't pickle <function <lambda> at 0x38578c0>: it's not found as __main__.<lambda> # for c in (ComputationFailed, ComputationFailed(lambda t: t, 3, None)): # check(c) for c in (UnivariatePolynomialError, UnivariatePolynomialError(), MultivariatePolynomialError, MultivariatePolynomialError()): check(c) # TODO: TypeError: __init__() takes at least 3 arguments (1 given) # for c in (PolificationFailed, PolificationFailed({}, x, x, False)): # check(c) for c in (OptionError, OptionError(), FlagError, FlagError()): check(c)
def dup_half_gcdex(f, g, K): """ Half extended Euclidean algorithm in `F[x]`. Returns ``(s, h)`` such that ``h = gcd(f, g)`` and ``s*f = h (mod g)``. Examples ======== >>> from diofant.polys import ring, QQ >>> R, x = ring("x", QQ) >>> f = x**4 - 2*x**3 - 6*x**2 + 12*x + 15 >>> g = x**3 + x**2 - 4*x - 4 >>> R.dup_half_gcdex(f, g) (-1/5*x + 3/5, x + 1) """ if not K.has_Field: raise DomainError("can't compute half extended GCD over %s" % K) a, b = [K.one], [] while g: q, r = dup_div(f, g, K) f, g = g, r a, b = b, dup_sub_mul(a, q, b, K) a = dup_quo_ground(a, dup_LC(f, K), K) f = dup_monic(f, K) return a, f
def dup_factor_list(f, K0): """Factor polynomials into irreducibles in `K[x]`. """ j, f = dup_terms_gcd(f, K0) cont, f = dup_primitive(f, K0) if K0.is_FiniteField: coeff, factors = dup_gf_factor(f, K0) elif K0.is_Algebraic: coeff, factors = dup_ext_factor(f, K0) else: if not K0.is_Exact: K0_inexact, K0 = K0, K0.get_exact() f = dup_convert(f, K0_inexact, K0) else: K0_inexact = None if K0.has_Field: K = K0.get_ring() denom, f = dup_clear_denoms(f, K0, K) f = dup_convert(f, K0, K) else: K = K0 if K.is_ZZ: coeff, factors = dup_zz_factor(f, K) elif K.is_Poly: f, u = dmp_inject(f, 0, K) coeff, factors = dmp_factor_list(f, u, K.domain) for i, (f, k) in enumerate(factors): factors[i] = (dmp_eject(f, u, K), k) coeff = K.convert(coeff, K.domain) else: # pragma: no cover raise DomainError('factorization not supported over %s' % K0) if K0.has_Field: for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K, K0), k) coeff = K0.convert(coeff, K) if K0_inexact is None: coeff = coeff / denom else: for i, (f, k) in enumerate(factors): f = dup_quo_ground(f, denom, K0) f = dup_convert(f, K0, K0_inexact) factors[i] = (f, k) coeff = K0_inexact.convert(coeff * denom**i, K0) K0 = K0_inexact if j: factors.insert(0, ([K0.one, K0.zero], j)) return coeff * cont, _sort_factors(factors)
def dmp_sqf_norm(f, u, K): """ Square-free norm of ``f`` in ``K[X]``, useful over algebraic domains. Returns ``s``, ``f``, ``r``, such that ``g(x) = f(x-sa)`` and ``r(x) = Norm(g(x))`` is a square-free polynomial over K, where ``a`` is the algebraic extension of ``K``. Examples ======== >>> from diofant.polys import ring, QQ >>> from diofant import I >>> K = QQ.algebraic_field(I) >>> R, x, y = ring("x,y", K) >>> _, X, Y = ring("x,y", QQ) >>> s, f, r = R.dmp_sqf_norm(x*y + y**2) >>> s == 1 True >>> f == x*y + y**2 + K([QQ(-1), QQ(0)])*y True >>> r == X**2*Y**2 + 2*X*Y**3 + Y**4 + Y**2 True """ if not u: return dup_sqf_norm(f, K) if not K.is_Algebraic: raise DomainError("ground domain must be algebraic") g = dmp_raise(K.mod.rep, u + 1, 0, K.domain) F = dmp_raise([K.one, -K.unit], u, 0, K) s = 0 while True: h, _ = dmp_inject(f, u, K, front=True) r = dmp_resultant(g, h, u + 1, K.domain) if dmp_sqf_p(r, u, K.domain): break else: f, s = dmp_compose(f, F, u, K), s + 1 return s, f, r
def __init__(self, dom, *ext): if not dom.is_QQ: raise DomainError("ground domain must be a rational field") from diofant.polys.numberfields import to_number_field self.orig_ext = ext self.ext = to_number_field(ext) self.mod = self.ext.minpoly.rep self.domain = dom self.ngens = 1 self.symbols = self.gens = (self.ext, ) self.unit = self([dom(1), dom(0)]) self.zero = self.dtype.zero(self.mod.rep, dom) self.one = self.dtype.one(self.mod.rep, dom)
def dup_real_imag(f, K): """ Return bivariate polynomials ``f1`` and ``f2``, such that ``f = f1 + f2*I``. Examples ======== >>> from diofant.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> R.dup_real_imag(x**3 + x**2 + x + 1) (x**3 + x**2 - 3*x*y**2 + x - y**2 + 1, 3*x**2*y + 2*x*y - y**3 + y) """ if not K.is_ZZ and not K.is_QQ: raise DomainError( "computing real and imaginary parts is not supported over %s" % K) f1 = dmp_zero(1) f2 = dmp_zero(1) if not f: return f1, f2 g = [[[K.one, K.zero]], [[K.one], []]] h = dmp_ground(f[0], 2) for c in f[1:]: h = dmp_mul(h, g, 2, K) h = dmp_add_term(h, dmp_ground(c, 1), 0, 2, K) H = dup_to_raw_dict(h) for k, h in H.items(): m = k % 4 if not m: f1 = dmp_add(f1, h, 1, K) elif m == 1: f2 = dmp_add(f2, h, 1, K) elif m == 2: f1 = dmp_sub(f1, h, 1, K) else: f2 = dmp_sub(f2, h, 1, K) return f1, f2
def dup_sqf_norm(f, K): """ Square-free norm of ``f`` in ``K[x]``, useful over algebraic domains. Returns ``s``, ``f``, ``r``, such that ``g(x) = f(x-sa)`` and ``r(x) = Norm(g(x))`` is a square-free polynomial over K, where ``a`` is the algebraic extension of ``K``. Examples ======== >>> from diofant.polys import ring, QQ >>> from diofant import sqrt >>> K = QQ.algebraic_field(sqrt(3)) >>> R, x = ring("x", K) >>> _, X = ring("x", QQ) >>> s, f, r = R.dup_sqf_norm(x**2 - 2) >>> s == 1 True >>> f == x**2 + K([QQ(-2), QQ(0)])*x + 1 True >>> r == X**4 - 10*X**2 + 1 True """ if not K.is_Algebraic: raise DomainError("ground domain must be algebraic") s, g = 0, dmp_raise(K.mod.rep, 1, 0, K.domain) while True: h, _ = dmp_inject(f, 0, K, front=True) r = dmp_resultant(g, h, 1, K.domain) if dup_sqf_p(r, K.domain): break else: f, s = dup_shift(f, -K.unit, K), s + 1 return s, f, r
def dmp_lift(f, u, K): """ Convert algebraic coefficients to integers in ``K[X]``. Examples ======== >>> from diofant.polys import ring, QQ >>> from diofant import I >>> K = QQ.algebraic_field(I) >>> R, x = ring("x", K) >>> f = x**2 + K([QQ(1), QQ(0)])*x + K([QQ(2), QQ(0)]) >>> R.dmp_lift(f) x**8 + 2*x**6 + 9*x**4 - 8*x**2 + 16 """ if not K.is_Algebraic: raise DomainError( 'computation can be done only in an algebraic domain') F, monoms, polys = dmp_to_dict(f, u), [], [] for monom, coeff in F.items(): if not coeff.is_ground: monoms.append(monom) perms = variations([-1, 1], len(monoms), repetition=True) for perm in perms: G = dict(F) for sign, monom in zip(perm, monoms): if sign == -1: G[monom] = -G[monom] polys.append(dmp_from_dict(G, u, K)) return dmp_convert(dmp_expand(polys, u, K), u, K, K.domain)
def get_ring(self): """Returns a ring associated with ``self``. """ raise DomainError('there is no ring associated with %s' % self)
def algebraic_field(self, *extension): """Returns an algebraic field, i.e. `K(\\alpha, \ldots)`. """ raise DomainError("can't create algebraic field over %s" % self)
def get_field(self): """Returns a field associated with ``self``. """ raise DomainError('there is no field associated with %s' % self)
def get_exact(self): """Returns an exact domain associated with ``self``. """ raise DomainError("there is no exact domain associated with %s" % self)
def dmp_factor_list(f, u, K0): """Factor polynomials into irreducibles in `K[X]`. """ if not u: return dup_factor_list(f, K0) J, f = dmp_terms_gcd(f, u, K0) cont, f = dmp_ground_primitive(f, u, K0) if K0.is_FiniteField: # pragma: no cover coeff, factors = dmp_gf_factor(f, u, K0) elif K0.is_Algebraic: coeff, factors = dmp_ext_factor(f, u, K0) else: if not K0.is_Exact: K0_inexact, K0 = K0, K0.get_exact() f = dmp_convert(f, u, K0_inexact, K0) else: K0_inexact = None if K0.has_Field: K = K0.get_ring() denom, f = dmp_clear_denoms(f, u, K0, K) f = dmp_convert(f, u, K0, K) else: K = K0 if K.is_ZZ: levels, f, v = dmp_exclude(f, u, K) coeff, factors = dmp_zz_factor(f, v, K) for i, (f, k) in enumerate(factors): factors[i] = (dmp_include(f, levels, v, K), k) elif K.is_Poly: f, v = dmp_inject(f, u, K) coeff, factors = dmp_factor_list(f, v, K.domain) for i, (f, k) in enumerate(factors): factors[i] = (dmp_eject(f, v, K), k) coeff = K.convert(coeff, K.domain) else: # pragma: no cover raise DomainError('factorization not supported over %s' % K0) if K0.has_Field: for i, (f, k) in enumerate(factors): factors[i] = (dmp_convert(f, u, K, K0), k) coeff = K0.convert(coeff, K) if K0_inexact is None: coeff = coeff / denom else: for i, (f, k) in enumerate(factors): f = dmp_quo_ground(f, denom, u, K0) f = dmp_convert(f, u, K0, K0_inexact) factors[i] = (f, k) coeff = K0_inexact.convert(coeff * denom**i, K0) K0 = K0_inexact for i, j in enumerate(reversed(J)): if not j: continue term = {(0, ) * (u - i) + (1, ) + (0, ) * i: K0.one} factors.insert(0, (dmp_from_dict(term, u, K0), j)) return coeff * cont, _sort_factors(factors)