def dmp_norm(f, u, K): """ Norm of ``f`` in ``K[X1, ..., Xn]``, often not square-free. """ if not K.is_Algebraic: raise DomainError("ground domain must be algebraic") g = dmp_raise(K.mod.rep, u + 1, 0, K.dom) h, _ = dmp_inject(f, u, K, front=True) return dmp_resultant(g, h, u + 1, K.dom)
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 sympy.polys import ring, QQ >>> from sympy 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.dom) 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.dom) if dmp_sqf_p(r, u, K.dom): break else: f, s = dmp_compose(f, F, u, K), s + 1 return s, f, r
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 sympy import I >>> from sympy.polys.domains import QQ >>> from sympy.polys.sqfreetools import dmp_sqf_norm >>> K = QQ.algebraic_field(I) >>> s, f, r = dmp_sqf_norm([[K(1), K(0)], [K(1), K(0), K(0)]], 1, K) >>> s == 1 True >>> f == [[K(1), K(0)], [K(1), K([QQ(-1), QQ(0)]), K(0)]] True >>> r == [[1, 0, 0], [2, 0, 0, 0], [1, 0, 1, 0, 0]] 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.dom) 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.dom) if dmp_sqf_p(r, u, K.dom): break else: f, s = dmp_compose(f, F, u, K), s + 1 return s, f, r
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 sympy.polys import ring, QQ >>> from sympy 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.dom) while True: h, _ = dmp_inject(f, 0, K, front=True) r = dmp_resultant(g, h, 1, K.dom) if dup_sqf_p(r, K.dom): break else: f, s = dup_shift(f, -K.unit, K), s + 1 return s, f, r
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 sympy import sqrt >>> from sympy.polys.domains import QQ >>> from sympy.polys.sqfreetools import dup_sqf_norm >>> K = QQ.algebraic_field(sqrt(3)) >>> s, f, r = dup_sqf_norm([K(1), K(0), K(-2)], K) >>> s == 1 True >>> f == [K(1), K([QQ(-2), QQ(0)]), K(1)] True >>> r == [1, 0, -10, 0, 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.dom) while True: h, _ = dmp_inject(f, 0, K, front=True) r = dmp_resultant(g, h, 1, K.dom) if dup_sqf_p(r, K.dom): break else: f, s = dup_shift(f, -K.unit, K), s+1 return s, f, r
def test_dmp_subresultants(): assert dmp_resultant([[]], [[]], 1, ZZ) == [] assert dmp_prs_resultant([[]], [[]], 1, ZZ)[0] == [] assert dmp_zz_collins_resultant([[]], [[]], 1, ZZ) == [] assert dmp_qq_collins_resultant([[]], [[]], 1, ZZ) == [] assert dmp_resultant([[ZZ(1)]], [[]], 1, ZZ) == [] assert dmp_resultant([[ZZ(1)]], [[]], 1, ZZ) == [] assert dmp_resultant([[ZZ(1)]], [[]], 1, ZZ) == [] assert dmp_resultant([[]], [[ZZ(1)]], 1, ZZ) == [] assert dmp_prs_resultant([[]], [[ZZ(1)]], 1, ZZ)[0] == [] assert dmp_zz_collins_resultant([[]], [[ZZ(1)]], 1, ZZ) == [] assert dmp_qq_collins_resultant([[]], [[ZZ(1)]], 1, ZZ) == [] f = dmp_normal([[3, 0], [], [-1, 0, 0, -4]], 1, ZZ) g = dmp_normal([[1], [1, 0, 0, 0], [-9]], 1, ZZ) a = dmp_normal([[3, 0, 0, 0, 0], [1, 0, -27, 4]], 1, ZZ) b = dmp_normal([[-3, 0, 0, -12, 1, 0, -54, 8, 729, -216, 16]], 1, ZZ) r = dmp_LC(b, ZZ) assert dmp_subresultants(f, g, 1, ZZ) == [f, g, a, b] assert dmp_resultant(f, g, 1, ZZ) == r assert dmp_prs_resultant(f, g, 1, ZZ)[0] == r assert dmp_zz_collins_resultant(f, g, 1, ZZ) == r assert dmp_qq_collins_resultant(f, g, 1, ZZ) == r f = dmp_normal([[-1], [], [], [5]], 1, ZZ) g = dmp_normal([[3, 1], [], []], 1, ZZ) a = dmp_normal([[45, 30, 5]], 1, ZZ) b = dmp_normal([[675, 675, 225, 25]], 1, ZZ) r = dmp_LC(b, ZZ) assert dmp_subresultants(f, g, 1, ZZ) == [f, g, a] assert dmp_resultant(f, g, 1, ZZ) == r assert dmp_prs_resultant(f, g, 1, ZZ)[0] == r assert dmp_zz_collins_resultant(f, g, 1, ZZ) == r assert dmp_qq_collins_resultant(f, g, 1, ZZ) == r f = [[[[[6]]]], [[[[-3]]], [[[-2]], [[]]]], [[[[1]], [[]]], [[[]]]]] g = [[[[[1]]]], [[[[-1], [-1, 0]]]], [[[[1, 0], []]]]] r = [[[[1]], [[-3], [-3, 0]], [[9, 0], []]], [[[-2], [-2, 0]], [[6], [12, 0], [6, 0, 0]], [[-18, 0], [-18, 0, 0], []]], [[[4, 0], []], [[-12, 0], [-12, 0, 0], []], [[36, 0, 0], [], []]]] assert dmp_zz_collins_resultant(f, g, 4, ZZ) == r f = [[[[[QQ(1, 1)]]]], [[[[QQ(-1, 2)]]], [[[QQ(-1, 3)]], [[]]]], [[[[QQ(1, 6)]], [[]]], [[[]]]]] g = [[[[[QQ(1, 1)]]]], [[[[QQ(-1, 1)], [QQ(-1, 1), QQ(0, 1)]]]], [[[[QQ(1, 1), QQ(0, 1)], []]]]] r = [[[[QQ(1, 36)]], [[QQ(-1, 12)], [QQ(-1, 12), QQ(0, 1)]], [[QQ(1, 4), QQ(0, 1)], []]], [[[QQ(-1, 18)], [QQ(-1, 18), QQ(0, 1)]], [[QQ(1, 6)], [QQ(1, 3), QQ(0, 1)], [QQ(1, 6), QQ(0, 1), QQ(0, 1)]], [[QQ(-1, 2), QQ(0, 1)], [QQ(-1, 2), QQ(0, 1), QQ(0, 1)], []]], [[[QQ(1, 9), QQ(0, 1)], []], [[QQ(-1, 3), QQ(0, 1)], [QQ(-1, 3), QQ(0, 1), QQ(0, 1)], []], [[QQ(1, 1), QQ(0, 1), QQ(0, 1)], [], []]]] assert dmp_qq_collins_resultant(f, g, 4, QQ) == r
def resultant(f, g): """Computes resultant of `f` and `g` via PRS. """ lev, dom, per, F, G = f.unify(g) return per(dmp_resultant(F, G, lev, dom), kill=True)
def test_dmp_subresultants(): assert dmp_resultant([[]], [[]], 1, ZZ) == [] assert dmp_prs_resultant([[]], [[]], 1, ZZ)[0] == [] assert dmp_zz_collins_resultant([[]], [[]], 1, ZZ) == [] assert dmp_qq_collins_resultant([[]], [[]], 1, ZZ) == [] assert dmp_resultant([[ZZ(1)]], [[]], 1, ZZ) == [] assert dmp_resultant([[ZZ(1)]], [[]], 1, ZZ) == [] assert dmp_resultant([[ZZ(1)]], [[]], 1, ZZ) == [] assert dmp_resultant([[]], [[ZZ(1)]], 1, ZZ) == [] assert dmp_prs_resultant([[]], [[ZZ(1)]], 1, ZZ)[0] == [] assert dmp_zz_collins_resultant([[]], [[ZZ(1)]], 1, ZZ) == [] assert dmp_qq_collins_resultant([[]], [[ZZ(1)]], 1, ZZ) == [] f = dmp_normal([[3,0],[],[-1,0,0,-4]], 1, ZZ) g = dmp_normal([[1],[1,0,0,0],[-9]], 1, ZZ) a = dmp_normal([[3,0,0,0,0],[1,0,-27,4]], 1, ZZ) b = dmp_normal([[-3,0,0,-12,1,0,-54,8,729,-216,16]], 1, ZZ) r = dmp_LC(b, ZZ) assert dmp_subresultants(f, g, 1, ZZ) == [f, g, a, b] assert dmp_resultant(f, g, 1, ZZ) == r assert dmp_prs_resultant(f, g, 1, ZZ)[0] == r assert dmp_zz_collins_resultant(f, g, 1, ZZ) == r assert dmp_qq_collins_resultant(f, g, 1, ZZ) == r f = dmp_normal([[-1],[],[],[5]], 1, ZZ) g = dmp_normal([[3,1],[],[]], 1, ZZ) a = dmp_normal([[45,30,5]], 1, ZZ) b = dmp_normal([[675,675,225,25]], 1, ZZ) r = dmp_LC(b, ZZ) assert dmp_subresultants(f, g, 1, ZZ) == [f, g, a] assert dmp_resultant(f, g, 1, ZZ) == r assert dmp_prs_resultant(f, g, 1, ZZ)[0] == r assert dmp_zz_collins_resultant(f, g, 1, ZZ) == r assert dmp_qq_collins_resultant(f, g, 1, ZZ) == r f = [[[[[6]]]], [[[[-3]]], [[[-2]], [[]]]], [[[[1]], [[]]], [[[]]]]] g = [[[[[1]]]], [[[[-1], [-1, 0]]]], [[[[1, 0], []]]]] r = [[[[1]], [[-3], [-3, 0]], [[9, 0], []]], [[[-2], [-2, 0]], [[6], [12, 0], [6, 0, 0]], [[-18, 0], [-18, 0, 0], []]], [[[4, 0], []], [[-12, 0], [-12, 0, 0], []], [[36, 0, 0], [], []]]] assert dmp_zz_collins_resultant(f, g, 4, ZZ) == r f = [[[[[QQ(1,1)]]]], [[[[QQ(-1,2)]]], [[[QQ(-1,3)]], [[]]]], [[[[QQ(1,6)]], [[]]], [[[]]]]] g = [[[[[QQ(1,1)]]]], [[[[QQ(-1,1)], [QQ(-1,1), QQ(0, 1)]]]], [[[[QQ(1,1), QQ(0,1)], []]]]] r = [[[[QQ(1,36)]], [[QQ(-1,12)], [QQ(-1,12), QQ(0,1)]], [[QQ(1,4), QQ(0,1)], []]], [[[QQ(-1,18)], [QQ(-1,18), QQ(0,1)]], [[QQ(1,6)], [QQ(1,3), QQ(0,1)], [QQ(1,6), QQ(0,1), QQ(0,1)]], [[QQ(-1,2), QQ(0,1)], [QQ(-1,2), QQ(0,1), QQ(0,1)], []]], [[[QQ(1,9), QQ(0,1)], []], [[QQ(-1,3), QQ(0,1)], [QQ(-1,3), QQ(0,1), QQ(0,1)], []], [[QQ(1,1), QQ(0,1), QQ(0,1)], [], []]]] assert dmp_qq_collins_resultant(f, g, 4, QQ) == r
def test_dup_sqf(): assert dup_sqf_part([], ZZ) == [] assert dup_sqf_p([], ZZ) == True assert dup_sqf_part([7], ZZ) == [1] assert dup_sqf_p([7], ZZ) == True assert dup_sqf_part([2,2], ZZ) == [1,1] assert dup_sqf_p([2,2], ZZ) == True assert dup_sqf_part([1,0,1,1], ZZ) == [1,0,1,1] assert dup_sqf_p([1,0,1,1], ZZ) == True assert dup_sqf_part([-1,0,1,1], ZZ) == [1,0,-1,-1] assert dup_sqf_p([-1,0,1,1], ZZ) == True assert dup_sqf_part([2,3,0,0], ZZ) == [2,3,0] assert dup_sqf_p([2,3,0,0], ZZ) == False assert dup_sqf_part([-2,3,0,0], ZZ) == [2,-3,0] assert dup_sqf_p([-2,3,0,0], ZZ) == False assert dup_sqf_list([], ZZ) == (0, []) assert dup_sqf_list([1], ZZ) == (1, []) assert dup_sqf_list([1,0], ZZ) == (1, [([1,0], 1)]) assert dup_sqf_list([2,0,0], ZZ) == (2, [([1,0], 2)]) assert dup_sqf_list([3,0,0,0], ZZ) == (3, [([1,0], 3)]) assert dup_sqf_list([ZZ(2),ZZ(4),ZZ(2)], ZZ) == \ (ZZ(2), [([ZZ(1),ZZ(1)], 2)]) assert dup_sqf_list([QQ(2),QQ(4),QQ(2)], QQ) == \ (QQ(2), [([QQ(1),QQ(1)], 2)]) assert dup_sqf_list([-1,1,0,0,1,-1], ZZ) == \ (-1, [([1,1,1,1], 1), ([1,-1], 2)]) assert dup_sqf_list([1,0,6,0,12,0,8,0,0], ZZ) == \ (1, [([1,0], 2), ([1,0,2], 3)]) K = FF(2) f = map(K, [1,0,1]) assert dup_sqf_list(f, K) == \ (K(1), [([K(1),K(1)], 2)]) K = FF(3) f = map(K, [1,0,0,2,0,0,2,0,0,1,0]) assert dup_sqf_list(f, K) == \ (K(1), [([K(1), K(0)], 1), ([K(1), K(1)], 3), ([K(1), K(2)], 6)]) f = [1,0,0,1] g = map(K, f) assert dup_sqf_part(f, ZZ) == f assert dup_sqf_part(g, K) == [K(1), K(1)] assert dup_sqf_p(f, ZZ) == True assert dup_sqf_p(g, K) == False A = [[1],[],[-3],[],[6]] D = [[1],[],[-5],[],[5],[],[4]] f, g = D, dmp_sub(A, dmp_mul(dmp_diff(D, 1, 1, ZZ), [[1,0]], 1, ZZ), 1, ZZ) res = dmp_resultant(f, g, 1, ZZ) assert dup_sqf_list(res, ZZ) == (45796, [([4,0,1], 3)]) assert dup_sqf_list_include([DMP([1, 0, 0, 0], ZZ), DMP([], ZZ), DMP([], ZZ)], ZZ[x]) == \ [([DMP([1, 0, 0, 0], ZZ)], 1), ([DMP([1], ZZ), DMP([], ZZ)], 2)]