def test_dup_strip(): assert dup_strip([]) == [] assert dup_strip([0]) == [] assert dup_strip([0,0,0]) == [] assert dup_strip([1]) == [1] assert dup_strip([0,1]) == [1] assert dup_strip([0,0,0,1]) == [1] assert dup_strip([1,2,0]) == [1,2,0] assert dup_strip([0,1,2,0]) == [1,2,0] assert dup_strip([0,0,0,1,2,0]) == [1,2,0]
def dup_trunc(f, p, K): """ Reduce a ``K[x]`` polynomial modulo a constant ``p`` in ``K``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_trunc(2*x**3 + 3*x**2 + 5*x + 7, ZZ(3)) -x**3 - x + 1 """ if K.is_ZZ: g = [] for c in f: c = c % p if c > p // 2: g.append(c - p) else: g.append(c) else: g = [ c % p for c in f ] return dup_strip(g)
def dup_compose(f, g, K): """ Evaluate functional composition ``f(g)`` in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_compose(x**2 + x, x - 1) x**2 - x """ if len(g) <= 1: return dup_strip([dup_eval(f, dup_LC(g, K), K)]) if not f: return [] h = [f[0]] for c in f[1:]: h = dup_mul(h, g, K) h = dup_add_term(h, c, 0, K) return h
def dup_add_term(f, c, i, K): """ Add ``c*x**i`` to ``f`` in ``K[x]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dup_add_term >>> f = ZZ.map([1, 0, -1]) >>> dup_add_term(f, ZZ(2), 4, ZZ) [2, 0, 1, 0, -1] """ if not c: return f n = len(f) m = n-i-1 if i == n-1: return dup_strip([f[0]+c] + f[1:]) else: if i >= n: return [c] + [K.zero]*(i-n) + f else: return f[:m] + [f[m]+c] + f[m+1:]
def dup_add(f, g, K): """ Add dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_add(x**2 - 1, x - 2) x**2 + x - 3 """ if not f: return g if not g: return f df = dup_degree(f) dg = dup_degree(g) if df == dg: return dup_strip([ a + b for a, b in zip(f, g) ]) else: k = abs(df - dg) if df > dg: h, f = f[:k], f[k:] else: h, g = g[:k], g[k:] return h + [ a + b for a, b in zip(f, g) ]
def dup_mul(f, g, K): """ Multiply dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_mul(x - 2, x + 2) x**2 - 4 """ if f == g: return dup_sqr(f, K) if not (f and g): return [] df = dup_degree(f) dg = dup_degree(g) h = [] for i in xrange(0, df + dg + 1): coeff = K.zero for j in xrange(max(0, i - dg), min(df, i) + 1): coeff += f[j] * g[i - j] h.append(coeff) return dup_strip(h)
def dup_add_term(f, c, i, K): """ Add ``c*x**i`` to ``f`` in ``K[x]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dup_add_term >>> f = ZZ.map([1, 0, -1]) >>> dup_add_term(f, ZZ(2), 4, ZZ) [2, 0, 1, 0, -1] """ if not c: return f n = len(f) m = n - i - 1 if i == n - 1: return dup_strip([f[0] + c] + f[1:]) else: if i >= n: return [c] + [K.zero] * (i - n) + f else: return f[:m] + [f[m] + c] + f[m + 1:]
def dup_sub(f, g, K): """ Subtract dense polynomials in ``K[x]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dup_sub >>> f = ZZ.map([1, 0, -1]) >>> g = ZZ.map([1, -2]) >>> dup_sub(f, g, ZZ) [1, -1, 1] """ if not f: return dup_neg(g, K) if not g: return f df = dup_degree(f) dg = dup_degree(g) if df == dg: return dup_strip([a - b for a, b in zip(f, g)]) else: k = abs(df - dg) if df > dg: h, f = f[:k], f[k:] else: h, g = dup_neg(g[:k], K), g[k:] return h + [a - b for a, b in zip(f, g)]
def dup_sub(f, g, K): """ Subtract dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_sub(x**2 - 1, x - 2) x**2 - x + 1 """ if not f: return dup_neg(g, K) if not g: return f df = dup_degree(f) dg = dup_degree(g) if df == dg: return dup_strip([ a - b for a, b in zip(f, g) ]) else: k = abs(df - dg) if df > dg: h, f = f[:k], f[k:] else: h, g = dup_neg(g[:k], K), g[k:] return h + [ a - b for a, b in zip(f, g) ]
def dup_mul(f, g, K): """ Multiply dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_mul(x - 2, x + 2) x**2 - 4 """ if f == g: return dup_sqr(f, K) if not (f and g): return [] df = dup_degree(f) dg = dup_degree(g) h = [] for i in xrange(0, df + dg + 1): coeff = K.zero for j in xrange(max(0, i - dg), min(df, i) + 1): coeff += f[j]*g[i - j] h.append(coeff) return dup_strip(h)
def dup_sub_term(f, c, i, K): """ Subtract ``c*x**i`` from ``f`` in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_sub_term(2*x**4 + x**2 - 1, ZZ(2), 4) x**2 - 1 """ if not c: return f n = len(f) m = n - i - 1 if i == n - 1: return dup_strip([f[0] - c] + f[1:]) else: if i >= n: return [-c] + [K.zero]*(i - n) + f else: return f[:m] + [f[m] - c] + f[m + 1:]
def dup_sqf_list_include(f, K, all=False): """ Return square-free decomposition of a polynomial in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> f = 2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16 >>> R.dup_sqf_list_include(f) [(2, 1), (x + 1, 2), (x + 2, 3)] >>> R.dup_sqf_list_include(f, all=True) [(2, 1), (x + 1, 2), (x + 2, 3)] """ coeff, factors = dup_sqf_list(f, K, all=all) if factors and factors[0][1] == 1: g = dup_mul_ground(factors[0][0], coeff, K) return [(g, 1)] + factors[1:] else: g = dup_strip([coeff]) return [(g, 1)] + factors
def dup_add_term(f, c, i, K): """ Add ``c*x**i`` to ``f`` in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_add_term(x**2 - 1, ZZ(2), 4) 2*x**4 + x**2 - 1 """ if not c: return f n = len(f) m = n - i - 1 if i == n - 1: return dup_strip([f[0] + c] + f[1:]) else: if i >= n: return [c] + [K.zero] * (i - n) + f else: return f[:m] + [f[m] + c] + f[m + 1:]
def dup_compose(f, g, K): """ Evaluate functional composition ``f(g)`` in ``K[x]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densetools import dup_compose >>> f = ZZ.map([1, 1, 0]) >>> g = ZZ.map([1, -1]) >>> dup_compose(f, g, ZZ) [1, -1, 0] """ if len(g) <= 1: return dup_strip([dup_eval(f, dup_LC(g, K), K)]) if not f: return [] h = [f[0]] for c in f[1:]: h = dup_mul(h, g, K) h = dup_add_term(h, c, 0, K) return h
def dup_sub(f, g, K): """ Subtract dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_sub(x**2 - 1, x - 2) x**2 - x + 1 """ if not f: return dup_neg(g, K) if not g: return f df = dup_degree(f) dg = dup_degree(g) if df == dg: return dup_strip([a - b for a, b in zip(f, g)]) else: k = abs(df - dg) if df > dg: h, f = f[:k], f[k:] else: h, g = dup_neg(g[:k], K), g[k:] return h + [a - b for a, b in zip(f, g)]
def dup_trunc(f, p, K): """ Reduce ``K[x]`` polynomial modulo a constant ``p`` in ``K``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densetools import dup_trunc >>> f = ZZ.map([2, 3, 5, 7]) >>> dup_trunc(f, ZZ(3), ZZ) [-1, 0, -1, 1] """ if K.is_ZZ: g = [] for c in f: c = c % p if c > p // 2: g.append(c - p) else: g.append(c) else: g = [c % p for c in f] return dup_strip(g)
def dup_add(f, g, K): """ Add dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_add(x**2 - 1, x - 2) x**2 + x - 3 """ if not f: return g if not g: return f df = dup_degree(f) dg = dup_degree(g) if df == dg: return dup_strip([a + b for a, b in zip(f, g)]) else: k = abs(df - dg) if df > dg: h, f = f[:k], f[k:] else: h, g = g[:k], g[k:] return h + [a + b for a, b in zip(f, g)]
def dup_sub_term(f, c, i, K): """ Subtract ``c*x**i`` from ``f`` in ``K[x]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dup_sub_term >>> f = ZZ.map([2, 0, 1, 0, -1]) >>> dup_sub_term(f, ZZ(2), 4, ZZ) [1, 0, -1] """ if not c: return f n = len(f) m = n-i-1 if i == n-1: return dup_strip([f[0]-c] + f[1:]) else: if i >= n: return [-c] + [K.zero]*(i-n) + f else: return f[:m] + [f[m]-c] + f[m+1:]
def dup_trunc(f, p, K): """ Reduce a ``K[x]`` polynomial modulo a constant ``p`` in ``K``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_trunc(2*x**3 + 3*x**2 + 5*x + 7, ZZ(3)) -x**3 - x + 1 """ if K.is_ZZ: g = [] for c in f: c = c % p if c > p // 2: g.append(c - p) else: g.append(c) else: g = [c % p for c in f] return dup_strip(g)
def dup_sqf_list_include(f, K, all=False): """ Return square-free decomposition of a polynomial in ``K[x]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.sqfreetools import dup_sqf_list_include >>> f = ZZ.map([2, 16, 50, 76, 56, 16]) >>> dup_sqf_list_include(f, ZZ) [([2], 1), ([1, 1], 2), ([1, 2], 3)] >>> dup_sqf_list_include(f, ZZ, all=True) [([2], 1), ([1, 1], 2), ([1, 2], 3)] """ coeff, factors = dup_sqf_list(f, K, all=all) if factors and factors[0][1] == 1: g = dup_mul_ground(factors[0][0], coeff, K) return [(g, 1)] + factors[1:] else: g = dup_strip([coeff]) return [(g, 1)] + factors
def dup_sub(f, g, K): """ Subtract dense polynomials in ``K[x]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dup_sub >>> f = ZZ.map([1, 0, -1]) >>> g = ZZ.map([1, -2]) >>> dup_sub(f, g, ZZ) [1, -1, 1] """ if not f: return dup_neg(g, K) if not g: return f df = dup_degree(f) dg = dup_degree(g) if df == dg: return dup_strip([ a - b for a, b in zip(f, g) ]) else: k = abs(df - dg) if df > dg: h, f = f[:k], f[k:] else: h, g = dup_neg(g[:k], K), g[k:] return h + [ a - b for a, b in zip(f, g) ]
def dup_trunc(f, p, K): """ Reduce ``K[x]`` polynomial modulo a constant ``p`` in ``K``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densetools import dup_trunc >>> f = ZZ.map([2, 3, 5, 7]) >>> dup_trunc(f, ZZ(3), ZZ) [-1, 0, -1, 1] """ if K.is_ZZ: g = [] for c in f: c = c % p if c > p // 2: g.append(c - p) else: g.append(c) else: g = [ c % p for c in f ] return dup_strip(g)
def dup_sub_term(f, c, i, K): """ Subtract ``c*x**i`` from ``f`` in ``K[x]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dup_sub_term >>> f = ZZ.map([2, 0, 1, 0, -1]) >>> dup_sub_term(f, ZZ(2), 4, ZZ) [1, 0, -1] """ if not c: return f n = len(f) m = n - i - 1 if i == n - 1: return dup_strip([f[0] - c] + f[1:]) else: if i >= n: return [-c] + [K.zero] * (i - n) + f else: return f[:m] + [f[m] - c] + f[m + 1:]
def dup_sqf_list_include(f, K, all=False): """ Return square-free decomposition of a polynomial in ``K[x]``. **Examples** >>> from sympy.polys.domains import ZZ >>> from sympy.polys.sqfreetools import dup_sqf_list_include >>> f = ZZ.map([2, 16, 50, 76, 56, 16]) >>> dup_sqf_list_include(f, ZZ) [([2], 1), ([1, 1], 2), ([1, 2], 3)] >>> dup_sqf_list_include(f, ZZ, all=True) [([2], 1), ([1, 1], 2), ([1, 2], 3)] """ coeff, factors = dup_sqf_list(f, K, all=all) if factors and factors[0][1] == 1: g = dup_mul_ground(factors[0][0], coeff, K) return [(g, 1)] + factors[1:] else: g = dup_strip([coeff]) return [(g, 1)] + factors
def dup_factor_list(f, K0, **args): """Factor polynomials into irreducibles in `K[x]`. """ if not K0.has_CharacteristicZero: # pragma: no cover raise DomainError('only characteristic zero allowed') if 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_ground_to_ring(f, K0, K) f = dup_convert(f, K0, K) else: K = K0 if K.is_ZZ: coeff, factors = dup_zz_factor(f, K, **args) elif K.is_Poly: f, u = dmp_inject(f, 0, K) coeff, factors = dmp_factor_list(f, u, K.dom, **args) for i, (f, k) in enumerate(factors): factors[i] = (dmp_eject(f, u, K), k) coeff = K.convert(coeff, K.dom) 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) denom = K0.convert(denom, K) coeff = K0.quo(coeff, denom) if K0_inexact is not None: for i, (f, k) in enumerate(factors): factors[i] = (dup_convert(f, K0, K0_inexact), k) coeff = K0_inexact.convert(coeff, K0) if not args.get('include', False): return coeff, factors else: if not factors: return [(dup_strip([coeff]), 1)] else: g = dup_mul_ground(factors[0][0], coeff, K) return [(g, factors[0][1])] + factors[1:]
def __init__(self, rep, mod, dom): if type(rep) is dict: self.rep = dup_from_dict(rep, dom) else: if type(rep) is not list: rep = [dom.convert(rep)] self.rep = dup_strip(rep) if isinstance(mod, DMP): self.mod = mod.rep else: if type(mod) is dict: self.mod = dup_from_dict(mod, dom) else: self.mod = dup_strip(mod) self.dom = dom
def dup_factor_list_include(f, K): """Factor polynomials into irreducibles in `K[x]`. """ coeff, factors = dup_factor_list(f, K) if not factors: return [(dup_strip([coeff]), 1)] else: g = dup_mul_ground(factors[0][0], coeff, K) return [(g, factors[0][1])] + factors[1:]
def dup_mul(f, g, K): """ Multiply dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_mul(x - 2, x + 2) x**2 - 4 """ if f == g: return dup_sqr(f, K) if not (f and g): return [] df = dup_degree(f) dg = dup_degree(g) n = max(df, dg) + 1 if n < 100: h = [] for i in range(0, df + dg + 1): coeff = K.zero for j in range(max(0, i - dg), min(df, i) + 1): coeff += f[j] * g[i - j] h.append(coeff) return dup_strip(h) else: # Use Karatsuba's algorithm (divide and conquer), see e.g.: # Joris van der Hoeven, Relax But Don't Be Too Lazy, # J. Symbolic Computation, 11 (2002), section 3.1.1. n2 = n // 2 fl, gl = dup_slice(f, 0, n2, K), dup_slice(g, 0, n2, K) fh = dup_rshift(dup_slice(f, n2, n, K), n2, K) gh = dup_rshift(dup_slice(g, n2, n, K), n2, K) lo, hi = dup_mul(fl, gl, K), dup_mul(fh, gh, K) mid = dup_mul(dup_add(fl, fh, K), dup_add(gl, gh, K), K) mid = dup_sub(mid, dup_add(lo, hi, K), K) return dup_add(dup_add(lo, dup_lshift(mid, n2, K), K), dup_lshift(hi, 2 * n2, K), K)
def dup_mul(f, g, K): """ Multiply dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_mul(x - 2, x + 2) x**2 - 4 """ if f == g: return dup_sqr(f, K) if not (f and g): return [] df = dup_degree(f) dg = dup_degree(g) n = max(df, dg) + 1 if n < 100: h = [] for i in xrange(0, df + dg + 1): coeff = K.zero for j in xrange(max(0, i - dg), min(df, i) + 1): coeff += f[j]*g[i - j] h.append(coeff) return dup_strip(h) else: # Use Karatsuba's algorithm (divide and conquer), see e.g.: # Joris van der Hoeven, Relax But Don't Be Too Lazy, # J. Symbolic Computation, 11 (2002), section 3.1.1. n2 = n//2 fl, gl = dup_slice(f, 0, n2, K), dup_slice(g, 0, n2, K) fh = dup_rshift(dup_slice(f, n2, n, K), n2, K) gh = dup_rshift(dup_slice(g, n2, n, K), n2, K) lo, hi = dup_mul(fl, gl, K), dup_mul(fh, gh, K) mid = dup_mul(dup_add(fl, fh, K), dup_add(gl, gh, K), K) mid = dup_sub(mid, dup_add(lo, hi, K), K) return dup_add(dup_add(lo, dup_lshift(mid, n2, K), K), dup_lshift(hi, 2*n2, K), K)
def dup_ff_div(f, g, K): """ Polynomial division with remainder over a field. Examples ======== >>> from sympy.polys import ring, QQ >>> R, x = ring("x", QQ) >>> R.dup_ff_div(x**2 + 1, 2*x - 4) (1/2*x + 1, 5) """ df = dup_degree(f) dg = dup_degree(g) q, r, dr = [], f, df if not g: raise ZeroDivisionError("polynomial division") elif df < dg: return q, r lc_g = dup_LC(g, K) while True: lc_r = dup_LC(r, K) c = K.exquo(lc_r, lc_g) j = dr - dg q = dup_add_term(q, c, j, K) h = dup_mul_term(g, c, j, K) r = dup_sub(r, h, K) _dr, dr = dr, dup_degree(r) if dr < dg: break elif dr == _dr and not K.is_Exact: # remove leading term created by rounding error r = dup_strip(r[1:]) dr = dup_degree(r) if dr < dg: break elif not (dr < _dr): raise PolynomialDivisionFailed(f, g, K) return q, r
def dup_add_term(f, c, i, K): """Add `c*x**i` to `f` in `K[x]`. """ if not c: return f n = len(f) m = n-i-1 if i == n-1: return dup_strip([f[0]+c] + f[1:]) else: if i >= n: return [c] + [K.zero]*(i-n) + f else: return f[:m] + [f[m]+c] + f[m+1:]
def dup_sub_term(f, c, i, K): """Subtract `c*x**i` from `f` in `K[x]`. """ if not c: return f n = len(f) m = n - i - 1 if i == n - 1: return dup_strip([f[0] - c] + f[1:]) else: if i >= n: return [-c] + [K.zero] * (i - n) + f else: return f[:m] + [f[m] - c] + f[m + 1:]
def dup_sub_term(f, c, i, K): """Subtract `c*x**i` from `f` in `K[x]`. """ if not c: return f n = len(f) m = n-i-1 if i == n-1: return dup_strip([f[0]-c] + f[1:]) else: if i >= n: return [-c] + [K.zero]*(i-n) + f else: return f[:m] + [f[m]-c] + f[m+1:]
def dup_add_term(f, c, i, K): """Add `c*x**i` to `f` in `K[x]`. """ if not c: return f n = len(f) m = n - i - 1 if i == n - 1: return dup_strip([f[0] + c] + f[1:]) else: if i >= n: return [c] + [K.zero] * (i - n) + f else: return f[:m] + [f[m] + c] + f[m + 1:]
def dup_diff(f, m, K): """ ``m``-th order derivative of a polynomial in ``K[x]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densetools import dup_diff >>> dup_diff([ZZ(1), ZZ(2), ZZ(3), ZZ(4)], 1, ZZ) [3, 4, 3] >>> dup_diff([ZZ(1), ZZ(2), ZZ(3), ZZ(4)], 2, ZZ) [6, 4] """ if m <= 0: return f n = dup_degree(f) if n < m: return [] deriv = [] if m == 1: for coeff in f[:-m]: deriv.append(K(n) * coeff) n -= 1 else: for coeff in f[:-m]: k = n for i in xrange(n - 1, n - m, -1): k *= i deriv.append(K(k) * coeff) n -= 1 return dup_strip(deriv)
def dup_diff(f, m, K): """ ``m``-th order derivative of a polynomial in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_diff(x**3 + 2*x**2 + 3*x + 4, 1) 3*x**2 + 4*x + 3 >>> R.dup_diff(x**3 + 2*x**2 + 3*x + 4, 2) 6*x + 4 """ if m <= 0: return f n = dup_degree(f) if n < m: return [] deriv = [] if m == 1: for coeff in f[:-m]: deriv.append(K(n)*coeff) n -= 1 else: for coeff in f[:-m]: k = n for i in range(n - 1, n - m, -1): k *= i deriv.append(K(k)*coeff) n -= 1 return dup_strip(deriv)
def dup_diff(f, m, K): """ ``m``-th order derivative of a polynomial in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_diff(x**3 + 2*x**2 + 3*x + 4, 1) 3*x**2 + 4*x + 3 >>> R.dup_diff(x**3 + 2*x**2 + 3*x + 4, 2) 6*x + 4 """ if m <= 0: return f n = dup_degree(f) if n < m: return [] deriv = [] if m == 1: for coeff in f[:-m]: deriv.append(K(n) * coeff) n -= 1 else: for coeff in f[:-m]: k = n for i in range(n - 1, n - m, -1): k *= i deriv.append(K(k) * coeff) n -= 1 return dup_strip(deriv)
def dup_diff(f, m, K): """ ``m``-th order derivative of a polynomial in ``K[x]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densetools import dup_diff >>> dup_diff([ZZ(1), ZZ(2), ZZ(3), ZZ(4)], 1, ZZ) [3, 4, 3] >>> dup_diff([ZZ(1), ZZ(2), ZZ(3), ZZ(4)], 2, ZZ) [6, 4] """ if m <= 0: return f n = dup_degree(f) if n < m: return [] deriv = [] if m == 1: for coeff in f[:-m]: deriv.append(K(n)*coeff) n -= 1 else: for coeff in f[:-m]: k = n for i in xrange(n - 1, n - m, -1): k *= i deriv.append(K(k)*coeff) n -= 1 return dup_strip(deriv)
def dup_add(f, g, K): """Add dense polynomials in `K[x]`. """ if not f: return g if not g: return f df = dup_degree(f) dg = dup_degree(g) if df == dg: return dup_strip([ a + b for a, b in zip(f, g) ]) else: k = abs(df - dg) if df > dg: h, f = f[:k], f[k:] else: h, g = g[:k], g[k:] return h + [ a + b for a, b in zip(f, g) ]
def dup_sub(f, g, K): """Subtract dense polynomials in `K[x]`. """ if not f: return dup_neg(g, K) if not g: return f df = dup_degree(f) dg = dup_degree(g) if df == dg: return dup_strip([ a - b for a, b in zip(f, g) ]) else: k = abs(df - dg) if df > dg: h, f = f[:k], f[k:] else: h, g = dup_neg(g[:k], K), g[k:] return h + [ a - b for a, b in zip(f, g) ]
def dup_add(f, g, K): """Add dense polynomials in `K[x]`. """ if not f: return g if not g: return f df = dup_degree(f) dg = dup_degree(g) if df == dg: return dup_strip([a + b for a, b in zip(f, g)]) else: k = abs(df - dg) if df > dg: h, f = f[:k], f[k:] else: h, g = g[:k], g[k:] return h + [a + b for a, b in zip(f, g)]
def dup_sub(f, g, K): """Subtract dense polynomials in `K[x]`. """ if not f: return dup_neg(g, K) if not g: return f df = dup_degree(f) dg = dup_degree(g) if df == dg: return dup_strip([a - b for a, b in zip(f, g)]) else: k = abs(df - dg) if df > dg: h, f = f[:k], f[k:] else: h, g = dup_neg(g[:k], K), g[k:] return h + [a - b for a, b in zip(f, g)]
def dup_sqr(f, K): """ Square dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dup_sqr >>> f = ZZ.map([1, 0, 1]) >>> dup_sqr(f, ZZ) [1, 0, 2, 0, 1] """ df, h = dup_degree(f), [] for i in xrange(0, 2 * df + 1): c = K.zero jmin = max(0, i - df) jmax = min(i, df) n = jmax - jmin + 1 jmax = jmin + n // 2 - 1 for j in xrange(jmin, jmax + 1): c += f[j] * f[i - j] c += c if n & 1: elem = f[jmax + 1] c += elem**2 h.append(c) return dup_strip(h)
def dup_sqr(f, K): """ Square dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dup_sqr >>> f = ZZ.map([1, 0, 1]) >>> dup_sqr(f, ZZ) [1, 0, 2, 0, 1] """ df, h = dup_degree(f), [] for i in xrange(0, 2*df+1): c = K.zero jmin = max(0, i-df) jmax = min(i, df) n = jmax - jmin + 1 jmax = jmin + n // 2 - 1 for j in xrange(jmin, jmax+1): c += f[j]*f[i-j] c += c if n & 1: elem = f[jmax+1] c += elem**2 h.append(c) return dup_strip(h)
def dup_sqr(f, K): """ Square dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_sqr(x**2 + 1) x**4 + 2*x**2 + 1 """ df, h = dup_degree(f), [] for i in xrange(0, 2*df + 1): c = K.zero jmin = max(0, i - df) jmax = min(i, df) n = jmax - jmin + 1 jmax = jmin + n // 2 - 1 for j in xrange(jmin, jmax + 1): c += f[j]*f[i - j] c += c if n & 1: elem = f[jmax + 1] c += elem**2 h.append(c) return dup_strip(h)
def dup_sqr(f, K): """ Square dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x = ring("x", ZZ) >>> R.dup_sqr(x**2 + 1) x**4 + 2*x**2 + 1 """ df, h = len(f) - 1, [] for i in range(0, 2 * df + 1): c = K.zero jmin = max(0, i - df) jmax = min(i, df) n = jmax - jmin + 1 jmax = jmin + n // 2 - 1 for j in range(jmin, jmax + 1): c += f[j] * f[i - j] c += c if n & 1: elem = f[jmax + 1] c += elem**2 h.append(c) return dup_strip(h)
def dup_mul(f, g, K): """ Multiply dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dup_mul >>> f = ZZ.map([1, -2]) >>> g = ZZ.map([1, 2]) >>> dup_mul(f, g, ZZ) [1, 0, -4] """ if f == g: return dup_sqr(f, K) if not (f and g): return [] df = dup_degree(f) dg = dup_degree(g) h = [] for i in xrange(0, df + dg + 1): coeff = K.zero for j in xrange(max(0, i - dg), min(df, i) + 1): coeff += f[j] * g[i - j] h.append(coeff) return dup_strip(h)
def dup_mul(f, g, K): """ Multiply dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dup_mul >>> f = ZZ.map([1, -2]) >>> g = ZZ.map([1, 2]) >>> dup_mul(f, g, ZZ) [1, 0, -4] """ if f == g: return dup_sqr(f, K) if not (f and g): return [] df = dup_degree(f) dg = dup_degree(g) h = [] for i in xrange(0, df+dg+1): coeff = K.zero for j in xrange(max(0, i-dg), min(df, i)+1): coeff += f[j]*g[i-j] h.append(coeff) return dup_strip(h)
def dup_add(f, g, K): """ Add dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dup_add >>> f = ZZ.map([1, 0, -1]) >>> g = ZZ.map([1, -2]) >>> dup_add(f, g, ZZ) [1, 1, -3] """ if not f: return g if not g: return f df = dup_degree(f) dg = dup_degree(g) if df == dg: return dup_strip([a + b for a, b in zip(f, g)]) else: k = abs(df - dg) if df > dg: h, f = f[:k], f[k:] else: h, g = g[:k], g[k:] return h + [a + b for a, b in zip(f, g)]
def dup_add(f, g, K): """ Add dense polynomials in ``K[x]``. Examples ======== >>> from sympy.polys.domains import ZZ >>> from sympy.polys.densearith import dup_add >>> f = ZZ.map([1, 0, -1]) >>> g = ZZ.map([1, -2]) >>> dup_add(f, g, ZZ) [1, 1, -3] """ if not f: return g if not g: return f df = dup_degree(f) dg = dup_degree(g) if df == dg: return dup_strip([ a + b for a, b in zip(f, g) ]) else: k = abs(df - dg) if df > dg: h, f = f[:k], f[k:] else: h, g = g[:k], g[k:] return h + [ a + b for a, b in zip(f, g) ]
def dup_cyclotomic_p(f, K, irreducible=False): """ Efficiently test if ``f`` is a cyclotomic polnomial. Examples ======== >>> from sympy.polys.factortools import dup_cyclotomic_p >>> from sympy.polys.domains import ZZ >>> f = [1, 0, 1, 0, 0, 0,-1, 0, 1, 0,-1, 0, 0, 0, 1, 0, 1] >>> dup_cyclotomic_p(f, ZZ) False >>> g = [1, 0, 1, 0, 0, 0,-1, 0,-1, 0,-1, 0, 0, 0, 1, 0, 1] >>> dup_cyclotomic_p(g, ZZ) True """ if K.is_QQ: try: K0, K = K, K.get_ring() f = dup_convert(f, K0, K) except CoercionFailed: return False elif not K.is_ZZ: return False lc = dup_LC(f, K) tc = dup_TC(f, K) if lc != 1 or (tc != -1 and tc != 1): return False if not irreducible: coeff, factors = dup_factor_list(f, K) if coeff != K.one or factors != [(f, 1)]: return False n = dup_degree(f) g, h = [], [] for i in xrange(n, -1, -2): g.insert(0, f[i]) for i in xrange(n - 1, -1, -2): h.insert(0, f[i]) g = dup_sqr(dup_strip(g), K) h = dup_sqr(dup_strip(h), K) F = dup_sub(g, dup_lshift(h, 1, K), K) if K.is_negative(dup_LC(F, K)): F = dup_neg(F, K) if F == f: return True g = dup_mirror(f, K) if K.is_negative(dup_LC(g, K)): g = dup_neg(g, K) if F == g and dup_cyclotomic_p(g, K): return True G = dup_sqf_part(F, K) if dup_sqr(G, K) == F and dup_cyclotomic_p(G, K): return True return False
def dmp_zz_modular_resultant(f, g, p, u, K): """ Compute resultant of `f` and `g` modulo a prime `p`. Examples ======== >>> from sympy.polys import ring, ZZ >>> R, x,y = ring("x,y", ZZ) >>> f = x + y + 2 >>> g = 2*x*y + x + 3 >>> R.dmp_zz_modular_resultant(f, g, 5) -2*y**2 + 1 """ if not u: return gf_int(dup_prs_resultant(f, g, K)[0] % p, p) v = u - 1 n = dmp_degree(f, u) m = dmp_degree(g, u) N = dmp_degree_in(f, 1, u) M = dmp_degree_in(g, 1, u) B = n*M + m*N D, a = [K.one], -K.one r = dmp_zero(v) while dup_degree(D) <= B: while True: a += K.one if a == p: raise HomomorphismFailed('no luck') F = dmp_eval_in(f, gf_int(a, p), 1, u, K) if dmp_degree(F, v) == n: G = dmp_eval_in(g, gf_int(a, p), 1, u, K) if dmp_degree(G, v) == m: break R = dmp_zz_modular_resultant(F, G, p, v, K) e = dmp_eval(r, a, v, K) if not v: R = dup_strip([R]) e = dup_strip([e]) else: R = [R] e = [e] d = K.invert(dup_eval(D, a, K), p) d = dup_mul_ground(D, d, K) d = dmp_raise(d, v, 0, K) c = dmp_mul(d, dmp_sub(R, e, v, K), v, K) r = dmp_add(r, c, v, K) r = dmp_ground_trunc(r, p, v, K) D = dup_mul(D, [K.one, -a], K) D = dup_trunc(D, p, K) return r
def dup_zz_cyclotomic_p(f, K, irreducible=False): """ Efficiently test if ``f`` is a cyclotomic polnomial. **Examples** >>> from sympy.polys.factortools import dup_zz_cyclotomic_p >>> from sympy.polys.domains import ZZ >>> f = [1, 0, 1, 0, 0, 0,-1, 0, 1, 0,-1, 0, 0, 0, 1, 0, 1] >>> dup_zz_cyclotomic_p(f, ZZ) False >>> g = [1, 0, 1, 0, 0, 0,-1, 0,-1, 0,-1, 0, 0, 0, 1, 0, 1] >>> dup_zz_cyclotomic_p(g, ZZ) True """ if K.is_QQ: try: K0, K = K, K.get_ring() f = dup_convert(f, K0, K) except CoercionFailed: return False elif not K.is_ZZ: return False lc = dup_LC(f, K) tc = dup_TC(f, K) if lc != 1 or (tc != -1 and tc != 1): return False if not irreducible: coeff, factors = dup_factor_list(f, K) if coeff != K.one or factors != [(f, 1)]: return False n = dup_degree(f) g, h = [], [] for i in xrange(n, -1, -2): g.insert(0, f[i]) for i in xrange(n-1, -1, -2): h.insert(0, f[i]) g = dup_sqr(dup_strip(g), K) h = dup_sqr(dup_strip(h), K) F = dup_sub(g, dup_lshift(h, 1, K), K) if K.is_negative(dup_LC(F, K)): F = dup_neg(F, K) if F == f: return True g = dup_mirror(f, K) if K.is_negative(dup_LC(g, K)): g = dup_neg(g, K) if F == g and dup_zz_cyclotomic_p(g, K): return True G = dup_sqf_part(F, K) if dup_sqr(G, K) == F and dup_zz_cyclotomic_p(G, K): return True return False