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)
Пример #2
0
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)
Пример #3
0
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.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
Пример #5
0
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
Пример #6
0
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
Пример #7
0
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.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
Пример #9
0
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
Пример #10
0
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
Пример #11
0
 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)
Пример #12
0
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
Пример #13
0
 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)
Пример #14
0
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)]