Esempio n. 1
0
def test_fmpq_mat():
    Q = flint.fmpq_mat
    Z = flint.fmpz_mat
    assert Q(1,2,[3,4]) == Z(1,2,[3,4])
    assert Q(1,2,[3,4]) != Z(1,2,[5,4])
    assert Q(1,2,[3,4]) != Q(1,2,[5,4])
    assert Q(Q(1,2,[3,4])) == Q(1,2,[3,4])
    assert Q(Z(1,2,[3,4])) == Q(1,2,[3,4])
    assert Q(2,3,[1,2,3,4,5,6]) + Q(2,3,[4,5,6,7,8,9]) == Q(2,3,[5,7,9,11,13,15])
    assert Q(2,3,[1,2,3,4,5,6]) - Q(2,3,[4,5,6,7,8,9]) == Q(2,3,[-3,-3,-3,-3,-3,-3])
    assert Q(2,3,[1,2,3,4,5,6]) * Q(3,2,[4,5,6,7,8,9]) == Q(2,2,[40,46,94,109])
    assert Q(2,3,[1,2,3,4,5,6]) * Z(3,2,[4,5,6,7,8,9]) == Q(2,2,[40,46,94,109])
    assert Z(2,3,[1,2,3,4,5,6]) * Q(3,2,[4,5,6,7,8,9]) == Q(2,2,[40,46,94,109])
    assert -Q(2,1,[2,5]) == Q(2,1,[-2,-5])
    assert +Q(1,1,[3]) == Z(1,1,[3])
    assert Q(1,2,[3,4]) * 2 == Q(1,2,[6,8])
    assert Q(1,2,[3,4]) * flint.fmpq(1,3) == Q(1,2,[1,flint.fmpq(4,3)])
    assert Q(1,2,[3,4]) * flint.fmpq(5,3) == Q(1,2,[5,flint.fmpq(20,3)])
    assert 2 * Q(1,2,[3,4]) == Q(1,2,[6,8])
    assert flint.fmpq(1,3) * Q(1,2,[3,4]) == Q(1,2,[1,flint.fmpq(4,3)])
    assert Q(1,2,[3,4]) / 2 == Q(1,2,[flint.fmpq(3,2),2])
    assert Q(1,2,[3,4]) / flint.fmpq(2,3) == Q(1,2,[flint.fmpq(9,2),6])
    assert Q(3,2,range(6)).table() == Z(3,2,range(6)).table()
    assert Q(3,2,range(6)).entries() == Z(3,2,range(6)).entries()
    assert Q(3,2,range(6)).nrows() == 3
    assert Q(3,2,range(6)).ncols() == 2
    assert Q(2,2,[3,7,4,5]).det() == -13
    assert (Q(2,2,[3,7,4,5]) / 5).det() == flint.fmpq(-13,25)
    assert raises(lambda: Q(1,2,[1,2]).det(), ValueError)
    assert ~~Q(2,2,[1,2,3,4]) == Q(2,2,[1,2,3,4])
    assert raises(lambda: ~Q(2,2,[1,1,1,1]), ZeroDivisionError)
    assert raises(lambda: ~Q(2,1,[1,1]), ValueError)
Esempio n. 2
0
def test_nmod():
    G = flint.nmod
    assert G(0, 2) == G(2, 2) == G(-2, 2)
    assert G(1, 2) != G(0, 2)
    assert G(0, 2) != G(0, 3)
    assert G(3, 5) == G(8, 5)
    #assert G(3,5) == 8        # do we want this?
    #assert 8 == G(3,5)
    assert G(3, 5) != 7
    assert 7 != G(3, 5)
    assert G(-3, 5) == -G(3, 5) == G(2, 5)
    assert G(2, 5) + G(1, 5) == G(3, 5)
    assert G(2, 5) + 1 == G(3, 5)
    assert 1 + G(2, 5) == G(3, 5)
    assert G(2, 5) - G(3, 5) == G(4, 5)
    assert G(2, 5) - 3 == G(4, 5)
    assert 3 - G(2, 5) == G(1, 5)
    assert G(2, 5) * G(3, 5) == G(1, 5)
    assert G(2, 5) * 3 == G(1, 5)
    assert 3 * G(2, 5) == G(1, 5)
    assert G(3, 17) / G(2, 17) == G(10, 17)
    assert G(3, 17) / 2 == G(10, 17)
    assert 3 / G(2, 17) == G(10, 17)
    assert G(3, 17) * flint.fmpq(11, 5) == G(10, 17)
    assert G(3, 17) / flint.fmpq(11, 5) == G(6, 17)
    assert raises(lambda: G(2, 5) / G(0, 5), ZeroDivisionError)
    assert raises(lambda: G(2, 5) / 0, ZeroDivisionError)
    assert raises(lambda: G(2, 5) + G(2, 7), ValueError)
    assert raises(lambda: G(2, 5) - G(2, 7), ValueError)
    assert raises(lambda: G(2, 5) * G(2, 7), ValueError)
    assert raises(lambda: G(2, 5) / G(2, 7), ValueError)
    assert G(3, 17).modulus() == 17
Esempio n. 3
0
def test_nmod():
    G = flint.nmod
    assert G(0,2) == G(2,2) == G(-2,2)
    assert G(1,2) != G(0,2)
    assert G(0,2) != G(0,3)
    assert G(3,5) == G(8,5)
    #assert G(3,5) == 8        # do we want this?
    #assert 8 == G(3,5)
    assert G(3,5) != 7
    assert 7 != G(3,5)
    assert G(-3,5) == -G(3,5) == G(2,5)
    assert G(2,5) + G(1,5) == G(3,5)
    assert G(2,5) + 1 == G(3,5)
    assert 1 + G(2,5) == G(3,5)
    assert G(2,5) - G(3,5) == G(4,5)
    assert G(2,5) - 3 == G(4,5)
    assert 3 - G(2,5) == G(1,5)
    assert G(2,5) * G(3,5) == G(1,5)
    assert G(2,5) * 3 == G(1,5)
    assert 3 * G(2,5) == G(1,5)
    assert G(3,17) / G(2,17) == G(10,17)
    assert G(3,17) / 2 == G(10,17)
    assert 3 / G(2,17) == G(10,17)
    assert G(3,17) * flint.fmpq(11,5) == G(10,17)
    assert G(3,17) / flint.fmpq(11,5) == G(6,17)
    assert raises(lambda: G(2,5) / G(0,5), ZeroDivisionError)
    assert raises(lambda: G(2,5) / 0, ZeroDivisionError)
    assert raises(lambda: G(2,5) + G(2,7), ValueError)
    assert raises(lambda: G(2,5) - G(2,7), ValueError)
    assert raises(lambda: G(2,5) * G(2,7), ValueError)
    assert raises(lambda: G(2,5) / G(2,7), ValueError)
    assert G(3,17).modulus() == 17
Esempio n. 4
0
def test_fmpq_mat():
    Q = flint.fmpq_mat
    Z = flint.fmpz_mat
    assert Q(1,2,[3,4]) == Z(1,2,[3,4])
    assert Q(1,2,[3,4]) != Z(1,2,[5,4])
    assert Q(1,2,[3,4]) != Q(1,2,[5,4])
    assert Q(Q(1,2,[3,4])) == Q(1,2,[3,4])
    assert Q(Z(1,2,[3,4])) == Q(1,2,[3,4])
    assert Q(2,3,[1,2,3,4,5,6]) + Q(2,3,[4,5,6,7,8,9]) == Q(2,3,[5,7,9,11,13,15])
    assert Q(2,3,[1,2,3,4,5,6]) - Q(2,3,[4,5,6,7,8,9]) == Q(2,3,[-3,-3,-3,-3,-3,-3])
    assert Q(2,3,[1,2,3,4,5,6]) * Q(3,2,[4,5,6,7,8,9]) == Q(2,2,[40,46,94,109])
    assert Q(2,3,[1,2,3,4,5,6]) * Z(3,2,[4,5,6,7,8,9]) == Q(2,2,[40,46,94,109])
    assert Z(2,3,[1,2,3,4,5,6]) * Q(3,2,[4,5,6,7,8,9]) == Q(2,2,[40,46,94,109])
    assert -Q(2,1,[2,5]) == Q(2,1,[-2,-5])
    assert +Q(1,1,[3]) == Z(1,1,[3])
    assert Q(1,2,[3,4]) * 2 == Q(1,2,[6,8])
    assert Q(1,2,[3,4]) * flint.fmpq(1,3) == Q(1,2,[1,flint.fmpq(4,3)])
    assert Q(1,2,[3,4]) * flint.fmpq(5,3) == Q(1,2,[5,flint.fmpq(20,3)])
    assert 2 * Q(1,2,[3,4]) == Q(1,2,[6,8])
    assert flint.fmpq(1,3) * Q(1,2,[3,4]) == Q(1,2,[1,flint.fmpq(4,3)])
    assert Q(1,2,[3,4]) / 2 == Q(1,2,[flint.fmpq(3,2),2])
    assert Q(1,2,[3,4]) / flint.fmpq(2,3) == Q(1,2,[flint.fmpq(9,2),6])
    assert Q(3,2,range(6)).table() == Z(3,2,range(6)).table()
    assert Q(3,2,range(6)).entries() == Z(3,2,range(6)).entries()
    assert Q(3,2,range(6)).nrows() == 3
    assert Q(3,2,range(6)).ncols() == 2
    assert Q(2,2,[3,7,4,5]).det() == -13
    assert (Q(2,2,[3,7,4,5]) / 5).det() == flint.fmpq(-13,25)
    assert raises(lambda: Q(1,2,[1,2]).det(), ValueError)
    assert Q(2,2,[1,2,3,4]).inv().inv() == Q(2,2,[1,2,3,4])
    assert raises(lambda: Q(2,2,[1,1,1,1]).inv(), ZeroDivisionError)
    assert raises(lambda: Q(2,1,[1,1]).inv(), ValueError)
    assert raises(lambda: Q([1]), TypeError)
    assert raises(lambda: Q([[1],[2,3]]), ValueError)
    assert Q([[1,2,3],[4,5,6]]) == Q(2,3,[1,2,3,4,5,6])
Esempio n. 5
0
    def pow(self, n):
        if self.is_rational():
            c0 = self._minpoly[0]
            c1 = self._minpoly[1]
            if abs(n) > 2:
                check_bits_limit(c0.height_bits() * abs(n))
                check_bits_limit(c1.height_bits() * abs(n))
            if n >= 0:
                return alg(fmpq(c0**n) / (-c1)**n)
            else:
                return alg((-c1)**(-n) / fmpq(c0**(-n)))
        if n == 0:
            return alg(1)
        if n == 1:
            return self
        if n < 0:
            return (1 / self).pow(-n)

        # fast detection of perfect powers
        pol, d = self.minpoly().deflation()
        if d % n == 0:
            # todo: is factoring needed here?
            H = list(self.minpoly())
            H = H[::n]
            H = fmpz_poly(H)
            c, factors = H.factor()
            prec = 64
            orig_prec = ctx.prec
            try:
                while 1:
                    ctx.prec = prec
                    x = self.enclosure(pretty=True)
                    z = acb(x)**n
                    maybe_root = [
                        fac for fac, mult in factors if fac(z).contains(0)
                    ]
                    if len(maybe_root) == 1:
                        fac = maybe_root[0]
                        z2 = alg._validate_root_enclosure(fac, z)
                        if z2 is not None:
                            return alg(_minpoly=fac, _enclosure=z2)
                    prec *= 2
            finally:
                ctx.prec = orig_prec

        if n == 2:
            return self * self
        v = self.pow(n // 2)
        v = v * v
        if n % 2:
            v *= self
        return v
Esempio n. 6
0
def composed_op(P1, P2, operation):
    d1 = P1.degree()
    d2 = P2.degree()
    # print("compose", d1, d2)
    assert d1 >= 1 and d2 >= 1
    cap = d1 * d2 + 1
    if operation == operator.truediv:
        P2 = list(P2)
        if P2[0] == 0:
            raise ZeroDivisionError
        P2 = fmpq_poly(P2[::-1])
    if operation == operator.sub:
        P2 = list(P2)
        for i in range(1, len(P2), 2):
            P2[i] = -P2[i]
        P2 = fmpq_poly(P2)
    orig_cap = ctx.cap
    try:
        ctx.cap = cap
        P1rev = list(P1)[::-1]
        P1drev = list(P1.derivative())[::-1]
        P2rev = list(P2)[::-1]
        P2drev = list(P2.derivative())[::-1]
        NP1 = fmpq_series(P1drev) / fmpq_series(P1rev)
        NP2 = fmpq_series(P2drev) / fmpq_series(P2rev)
        if operation in (operator.add, operator.sub):
            c = fmpq(1)
            a1, a2 = [NP1[0]], [NP2[0]]
            for j in range(1, cap):
                c *= j
                a1.append(NP1[j] / c)
                a2.append(NP2[j] / c)
            NP1E = fmpq_series(a1)
            NP2E = fmpq_series(a2)
            NP3E = NP1E * NP2E
            c = fmpq(-1)
            a3 = [fmpq(0)]
            for j in range(1, cap):
                a3.append(NP3E[j] * c)
                c *= j
            NP = fmpq_series(a3)
            Q = NP
        else:
            NP = fmpq_series([-NP1[j] * NP2[j] for j in range(1, cap)])
            Q = NP.integral()
        Q = Q.exp()
        Q = fmpq_poly([Q[i] for i in range(cap)][::-1])
        Q = Q.p
        return Q
    finally:
        # print("end compose")
        ctx.cap = orig_cap
Esempio n. 7
0
def guessrational(q):
    if isinstance(q, fmpq):
        return q
    minus, fraction = cfrac(q)
    numer = 1
    denom = 0
    for j in fraction[::-1]:
        denom, numer = numer, denom
        numer += denom * j
    numer *= minus
    return fmpq(numer, denom)
Esempio n. 8
0
 def test_misc_bugs(self):
     x = (
         (1 /
          (alg(3).sqrt() + alg(5).sqrt()) + 1).root(3) + 1)**2 + fmpq(1, 3)
     x + alg.i()
     u = (x + alg.i()).root(3)
     P = alg.polynomial_roots([
         340282366920938463463374607431768211456,
         4454982093016792820459821542203090534400000000,
         179577734764660553639051786303255347200000000000000,
         -669109415404441101038544285174988800000000000000000000,
         17329972089242952969786575138568878173828125
     ])[0][0].expr()
     assert P is not None
Esempio n. 9
0
    def test_examples(self):
        assert sum(1 / alg(n) for n in range(1, 101)) == fmpq.harmonic(100)
        sqrt = lambda n: alg(n).sqrt()
        x = sqrt(2 * sqrt(3) * sqrt(2 * sqrt(10) + 7) + 2 * sqrt(10) + 10)
        y = sqrt(2) + sqrt(3) + sqrt(5)
        assert x == y

        def R(a, n):
            return alg(a).root(n)

        assert R(2, 1) + R(2, 2) - R(2, 2) - R(2, 1) == 0
        assert R(2, 1) + R(2, 2) + R(2, 3) - R(2, 2) - R(2, 1) - R(2, 3) == 0
        assert R(2, 4) + R(2, 1) + R(2, 2) + R(2, 3) - R(2, 2) - R(2, 1) - R(
            2, 3) - R(2, 4) == 0
        assert 7 < sum(R(2, n) for n in [1, 2, 3, 4, 5]) < fmpq(702, 100)
Esempio n. 10
0
 def exp_two_pi_i(x):
     x = fmpq(x)
     check_degree_limit(10 * x.q)
     poly = fmpz_poly.cyclotomic(x.q)
     prec = ctx.prec
     ctx.prec = 64
     try:
         while 1:
             a = arb.cos_pi_fmpq(2 * x)
             b = arb.sin_pi_fmpq(2 * x)
             z = acb(a, b)
             z2 = alg._validate_root_enclosure(poly, z)
             if z2 is not None:
                 return alg(_minpoly=poly, _enclosure=z2)
             ctx.prec *= 2
     finally:
         ctx.prec = prec
Esempio n. 11
0
def test_fmpz_mat():
    M = flint.fmpz_mat
    a = M(2, 3, [1, 2, 3, 4, 5, 6])
    b = M(2, 3, [4, 5, 6, 7, 8, 9])
    assert a == a
    assert a == M(a)
    assert a != b
    assert a.nrows() == 2
    assert a.ncols() == 3
    assert a.entries() == [1, 2, 3, 4, 5, 6]
    assert a.table() == [[1, 2, 3], [4, 5, 6]]
    assert (a + b).entries() == [5, 7, 9, 11, 13, 15]
    assert raises(a.det, ValueError)
    assert +a == a
    assert -a == M(2, 3, [-1, -2, -3, -4, -5, -6])
    c = M(2, 2, [1, 2, 3, 4])
    assert c.det() == -2
    assert raises(lambda: a + c, ValueError)
    assert (a * 3).entries() == [3, 6, 9, 12, 15, 18]
    assert (3 * a).entries() == [3, 6, 9, 12, 15, 18]
    assert (a * long(3)).entries() == [3, 6, 9, 12, 15, 18]
    assert (long(3) * a).entries() == [3, 6, 9, 12, 15, 18]
    assert (a * flint.fmpz(3)).entries() == [3, 6, 9, 12, 15, 18]
    assert (flint.fmpz(3) * a).entries() == [3, 6, 9, 12, 15, 18]
    assert M.randrank(5, 7, 3, 10).rank() == 3
    A = M.randbits(5, 3, 2)
    B = M.randtest(3, 7, 3)
    C = M.randtest(7, 2, 4)
    assert A * (B * C) == (A * B) * C
    assert bool(M(2, 2, [0, 0, 0, 0])) == False
    assert bool(M(2, 2, [0, 0, 0, 1])) == True
    ctx.pretty = False
    assert repr(M(2, 2, [1, 2, 3, 4])) == 'fmpz_mat(2, 2, [1, 2, 3, 4])'
    ctx.pretty = True
    assert str(M(2, 2, [1, 2, 3, 4])) == '[1, 2]\n[3, 4]'
    assert M(1, 2, [3, 4]) * flint.fmpq(1, 3) == flint.fmpq_mat(
        1, 2, [1, flint.fmpq(4, 3)])
    assert flint.fmpq(1, 3) * M(1, 2, [3, 4]) == flint.fmpq_mat(
        1, 2, [1, flint.fmpq(4, 3)])
    assert M(1, 2, [3, 4]) / 3 == flint.fmpq_mat(1, 2, [1, flint.fmpq(4, 3)])
    assert M(2, 2,
             [1, 2, 3, 4
              ]).inv().det() == flint.fmpq(1) / M(2, 2, [1, 2, 3, 4]).det()
    assert M(2, 2, [1, 2, 3, 4]).inv().inv() == M(2, 2, [1, 2, 3, 4])
    assert raises(lambda: M.randrank(4, 3, 4, 1), ValueError)
    assert raises(lambda: M.randrank(3, 4, 4, 1), ValueError)
    assert M(1, 1, [3])**5 == M(1, 1, [3**5])
    assert raises(lambda: M(1, 2)**3, ValueError)
    assert raises(lambda: M(1, 1)**M(1, 1), TypeError)
    assert raises(lambda: 1**M(1, 1), TypeError)
    assert raises(lambda: M([1]), TypeError)
    assert raises(lambda: M([[1], [2, 3]]), ValueError)
    assert M([[1, 2, 3], [4, 5, 6]]) == M(2, 3, [1, 2, 3, 4, 5, 6])
Esempio n. 12
0
 def cos_pi(x, monic=False):
     x = fmpq(x)
     check_degree_limit(10 * x.q)
     x2 = x / 2
     poly = fmpz_poly.cos_minpoly(x2.q)
     prec = ctx.prec
     ctx.prec = 64
     try:
         while 1:
             z = 2 * arb.cos_pi_fmpq(x)
             z2 = alg._validate_root_enclosure(poly, z)
             if z2 is not None:
                 v = alg(_minpoly=poly, _enclosure=z2)
                 if not monic:
                     v /= 2
                 return v
             ctx.prec *= 2
     finally:
         ctx.prec = prec
Esempio n. 13
0
def float_to_fmpq(c):
    """
    **Description:**
    Converts a float to an fmpq.

    **Arguments:**
    - `c` *(float)*: The input number.

    **Returns:**
    *(flint.fmpq)* The rational number that most reasonably approximates the
    input.

    **Example:**
    We convert a few floats to rational numbers.
    ```python {2}
    from cytools.utils import float_to_fmpq
    float_to_fmpq(0.1), float_to_fmpq(0.333333333333), float_to_fmpq(2.45)
    # (1/10, 1/3, 49/20)
    ```
    """
    f = Fraction(c).limit_denominator()
    return fmpq(f.numerator, f.denominator)
Esempio n. 14
0
def test_fmpz_mat():
    M = flint.fmpz_mat
    a = M(2,3,[1,2,3,4,5,6])
    b = M(2,3,[4,5,6,7,8,9])
    assert a == a
    assert a == M(a)
    assert a != b
    assert a.nrows() == 2
    assert a.ncols() == 3
    assert a.entries() == [1,2,3,4,5,6]
    assert a.table() == [[1,2,3],[4,5,6]]
    assert (a + b).entries() == [5,7,9,11,13,15]
    assert raises(a.det, ValueError)
    assert +a == a
    assert -a == M(2,3,[-1,-2,-3,-4,-5,-6])
    c = M(2,2,[1,2,3,4])
    assert c.det() == -2
    assert raises(lambda: a + c, ValueError)
    assert (a * 3).entries() == [3,6,9,12,15,18]
    assert (3 * a).entries() == [3,6,9,12,15,18]
    assert (a * 3L).entries() == [3,6,9,12,15,18]
    assert (3L * a).entries() == [3,6,9,12,15,18]
    assert (a * flint.fmpz(3)).entries() == [3,6,9,12,15,18]
    assert (flint.fmpz(3) * a).entries() == [3,6,9,12,15,18]
    assert M.randrank(5,7,3,10).rank() == 3
    A = M.randbits(5,3,2)
    B = M.randtest(3,7,3)
    C = M.randtest(7,2,4)
    assert A*(B*C) == (A*B)*C
    assert bool(M(2,2,[0,0,0,0])) == False
    assert bool(M(2,2,[0,0,0,1])) == True
    assert repr(M(2,2,[1,2,3,4])) == 'fmpz_mat(2, 2, [1, 2, 3, 4])'
    assert str(M(2,2,[1,2,3,4])) == '[1, 2]\n[3, 4]'
    assert M(1,2,[3,4]) * flint.fmpq(1,3) == flint.fmpq_mat(1, 2, [1, flint.fmpq(4,3)])
    assert flint.fmpq(1,3) * M(1,2,[3,4]) == flint.fmpq_mat(1, 2, [1, flint.fmpq(4,3)])
    assert M(1,2,[3,4]) / 3 == flint.fmpq_mat(1, 2, [1, flint.fmpq(4,3)])
    assert (~M(2,2,[1,2,3,4])).det() == flint.fmpq(1) / M(2,2,[1,2,3,4]).det()
    assert ~~M(2,2,[1,2,3,4]) == M(2,2,[1,2,3,4])
    assert raises(lambda: M.randrank(4,3,4,1), ValueError)
    assert raises(lambda: M.randrank(3,4,4,1), ValueError)
    assert M(1,1,[3]) ** 5 == M(1,1,[3**5])
    assert raises(lambda: M(1,2) ** 3, ValueError)
    assert raises(lambda: M(1,1) ** M(1,1), TypeError)
    assert raises(lambda: 1 ** M(1,1), TypeError)
Esempio n. 15
0
def reconstruct_lehmer_lower(B, m, ys):
    """
    Reconstructs the lower bits :math:`zs` of a system of linear congurential equations in lattice form with
    :math:`B \\cdot xs = 0 \\mod m` for solution :math:`xs`, where :math:`xs = ys + zs`.
    It works by computing a smaller basis :math:`B` from the basis :math:`L` and solving equations in the smaller basis.

    :param B: The system of linear equation in matrix form (evaluating to 0)
    :param m: The modulus used for all the equations
    :param ys: Partial solutions for the variables (xs = ys + zs)
    :return: The remaining operands of the solutions zs
    """
    ys = fmpz_mat([[y] for y in ys])

    Bys = B * ys

    # TODO: There might be a better solution to find the individual ks
    # NB: B * (ys + zs) = m * ks for some ks
    ks = fmpz_mat([[_round_fmpq(fmpq(By) / m)] for By in Bys])

    # We now solve the system of linear equations B zs = m * ks - B ys for zs
    Bzs = m * ks - Bys
    zs = B.solve(Bzs)
    assert all(z.denom() == 1 for z in zs)
    return [z.numer() % m for z in zs]
Esempio n. 16
0
def test_fmpz_poly():
    Z = flint.fmpz_poly
    assert Z() == Z([])
    assert Z() == Z([0])
    assert Z() == Z([0, flint.fmpz(0), 0])
    assert Z() == Z([0, 0, 0])
    assert Z() != Z([1])
    assert Z([1]) == Z([1])
    assert Z([1]) == Z([flint.fmpz(1)])
    assert Z(Z([1, 2])) == Z([1, 2])
    for ztype in [int, long, flint.fmpz]:
        assert Z([1, 2, 3]) + ztype(5) == Z([6, 2, 3])
        assert ztype(5) + Z([1, 2, 3]) == Z([6, 2, 3])
        assert Z([1, 2, 3]) - ztype(5) == Z([-4, 2, 3])
        assert ztype(5) - Z([1, 2, 3]) == Z([4, -2, -3])
        assert Z([1, 2, 3]) * ztype(5) == Z([5, 10, 15])
        assert ztype(5) * Z([1, 2, 3]) == Z([5, 10, 15])
        assert Z([11, 6, 2]) // ztype(5) == Z([2, 1])
        assert ztype(5) // Z([-2]) == Z([-3])
        assert ztype(5) // Z([1, 2]) == 0
        assert Z([11, 6, 2]) % ztype(5) == Z([1, 1, 2])
        assert ztype(5) % Z([-2]) == Z([-1])
        assert ztype(5) % Z([1, 2]) == 5
        assert Z([1, 2, 3])**ztype(0) == 1
        assert Z([1, 2, 3])**ztype(1) == Z([1, 2, 3])
        assert Z([1, 2, 3])**ztype(2) == Z([1, 4, 10, 12, 9])
    assert +Z([1, 2]) == Z([1, 2])
    assert -Z([1, 2]) == Z([-1, -2])
    assert raises(lambda: Z([1, 2, 3])**-1, (OverflowError, ValueError))
    assert raises(lambda: Z([1, 2, 3])**Z([1, 2]), TypeError)
    assert raises(lambda: Z([1, 2]) // Z([]), ZeroDivisionError)
    assert raises(lambda: Z([]) // Z([]), ZeroDivisionError)
    assert raises(lambda: Z([1, 2]) % Z([]), ZeroDivisionError)
    assert raises(lambda: divmod(Z([1, 2]), Z([])), ZeroDivisionError)
    assert Z([]).degree() == -1
    assert Z([]).length() == 0
    p = Z([1, 2])
    assert p.length() == 2
    assert p.degree() == 1
    assert p[0] == 1
    assert p[1] == 2
    assert p[2] == 0
    assert p[-1] == 0
    assert raises(lambda: p.__setitem__(-1, 1), ValueError)
    p[0] = 3
    assert p[0] == 3
    p[4] = 7
    assert p.degree() == 4
    assert p[4] == 7
    assert p[3] == 0
    p[4] = 0
    assert p.degree() == 1
    assert p.coeffs() == [3, 2]
    assert Z([]).coeffs() == []
    assert bool(Z([])) == False
    assert bool(Z([1])) == True
    ctx.pretty = False
    assert repr(Z([1, 2])) == "fmpz_poly([1, 2])"
    ctx.pretty = True
    assert str(Z([1, 2])) == "2*x + 1"
    p = Z([3, 4, 5])
    assert p(2) == 31
    assert p(flint.fmpq(2, 3)) == flint.fmpq(71, 9)
    assert p(Z([1, -1])) == Z([12, -14, 5])
    assert p(flint.fmpq_poly([2, 3], 5)) == flint.fmpq_poly([27, 24, 9], 5)
    assert p(flint.arb("1.1")).overlaps(flint.arb("13.45"))
    assert p(flint.acb("1.1", "1.2")).overlaps(flint.acb("6.25", "18.00"))
Esempio n. 17
0
def test_fmpq_poly():
    Q = flint.fmpq_poly
    Z = flint.fmpz_poly
    assert Q() == Q([]) == Q([0]) == Q([0, 0])
    assert Q() != Q([1])
    assert Q([1]) == Q([1])
    assert bool(Q()) == False
    assert bool(Q([1])) == True
    assert Q(Q([1, 2])) == Q([1, 2])
    assert Q(Z([1, 2])) == Q([1, 2])
    assert Q([1, 2]) + 3 == Q([4, 2])
    assert 3 + Q([1, 2]) == Q([4, 2])
    assert Q([1, 2]) - 3 == Q([-2, 2])
    assert 3 - Q([1, 2]) == Q([2, -2])
    assert -Q([1, 2]) == Q([-1, -2])
    assert Q([flint.fmpq(1, 2), 1]) * 2 == Q([1, 2])
    assert Q([1, 2]) == Z([1, 2])
    assert Z([1, 2]) == Q([1, 2])
    assert Q([1, 2]) != Z([3, 2])
    assert Z([1, 2]) != Q([3, 2])
    assert Q([1, 2, 3]) * Q([1, 2]) == Q([1, 4, 7, 6])
    assert Q([1, 2, 3]) * Z([1, 2]) == Q([1, 4, 7, 6])
    assert Q([1, 2, 3]) * 3 == Q([3, 6, 9])
    assert 3 * Q([1, 2, 3]) == Q([3, 6, 9])
    assert Q([1, 2, 3]) * flint.fmpq(2, 3) == (Q([1, 2, 3]) * 2) / 3
    assert flint.fmpq(2, 3) * Q([1, 2, 3]) == (Q([1, 2, 3]) * 2) / 3
    assert raises(lambda: Q([1, 2]) / Q([1, 2]), TypeError)
    assert Q([1, 2, 3]) / flint.fmpq(2, 3) == Q([1, 2, 3]) * flint.fmpq(3, 2)
    assert Q([1, 2, 3])**2 == Q([1, 2, 3]) * Q([1, 2, 3])
    assert Q([1, 2, flint.fmpq(1, 2)]).coeffs() == [1, 2, flint.fmpq(1, 2)]
    assert Q().coeffs() == []
    assert Q().degree() == -1
    assert Q([1]).degree() == 0
    assert Q([1, 2]).degree() == 1
    assert Q().length() == 0
    assert Q([1]).length() == 1
    assert Q([1, 2]).length() == 2
    assert (Q([1, 2, 3]) / 5).numer() == (Q([1, 2, 3]) / 5).p == Z([1, 2, 3])
    assert (Q([1, 2, 3]) / 5).denom() == (Q([1, 2, 3]) / 5).q == 5
    ctx.pretty = False
    assert repr(Q([15, 20, 10]) / 25) == "fmpq_poly([3, 4, 2], 5)"
    ctx.pretty = True
    assert str(Q([3, 4, 2], 5)) == "2/5*x^2 + 4/5*x + 3/5"
    a = Q([2, 2, 3], 4)
    assert a[2] == flint.fmpq(3, 4)
    a[2] = 4
    assert a == Q([1, 1, 8], 2)
    p = Q([3, 4, 5], 7)
    assert p(2) == flint.fmpq(31, 7)
    assert p(flint.fmpq(2, 3)) == flint.fmpq(71, 63)
    assert p(Z([1, -1])) == Q([12, -14, 5], 7)
    assert p(flint.fmpq_poly([2, 3], 5)) == flint.fmpq_poly([27, 24, 9], 7 * 5)
Esempio n. 18
0
    def polynomial_roots(poly, canonical_order=True):
        """
        Returns all the roots of the given *fmpz_poly* or *fmpq_poly*,
        or list of coefficients that can be converted to an *fmpq_poly*.
        (At this time, this function does not support algebraic coefficients.)

        The output is a list of pairs (*root*, *m*) where root
        is an algebraic number and *m* >= 1 is its multiplicity.

        With *canonical_order* set to *True*, the roots are sorted in
        a mathematically well-defined way, ensuring a consistent
        ordering of algebraic numbers.
        """
        poly = fmpq_poly(poly).numer()
        # todo: flag to assume irreducible?
        c, factors = poly.factor()
        roots = []
        orig = ctx.prec
        maxprec = 64
        try:
            for fac, mult in factors:
                if fac.degree() == 1:
                    a, b = list(fac)
                    roots.append((alg(fmpq(-a, b)), mult))
                    continue
                ctx.prec = 64
                while 1:
                    fac_roots = fac.roots()
                    checked_roots = []
                    for r, _ in fac_roots:
                        r = alg._validate_root_enclosure(fac, r)
                        if r is not None:
                            checked_roots.append(r)
                        else:
                            break
                    if len(checked_roots) == len(fac_roots):
                        for i in range(len(fac_roots)):
                            a = alg(_minpoly=fac, _enclosure=checked_roots[i])
                            roots.append((a, mult))
                        break
                    ctx.prec *= 2
                    maxprec = max(maxprec, ctx.prec)
            if len(roots) > 1 and canonical_order:
                from functools import cmp_to_key
                real = []
                nonreal = []
                ctx.prec = 64
                for (r, m) in roots:
                    if r.is_real():
                        real.append((r, m))
                    else:
                        z = r.enclosure()
                        if z.imag > 0:
                            nonreal.append((r, m))
                        else:
                            assert z.imag < 0

                def complex_algebraic_cmp(a, b):
                    a, _ = a
                    b, _ = b
                    ctx.prec = 64
                    while 1:
                        ac = a.enclosure()
                        bc = b.enclosure()
                        ac = ac.real + ac.imag * arb.pi()
                        bc = bc.real + bc.imag * arb.pi()
                        if ac.overlaps(bc):
                            ctx.prec *= 2
                        else:
                            if ac < bc:
                                return -1
                            else:
                                return 1

                roots = sorted(real, reverse=True)
                nonreal = sorted(nonreal,
                                 key=cmp_to_key(complex_algebraic_cmp),
                                 reverse=True)
                for r, m in nonreal:
                    roots.append((r, m))
                    roots.append((r.conjugate(), m))
        finally:
            ctx.prec = orig
        return roots
Esempio n. 19
0
def test_fmpz_poly():
    Z = flint.fmpz_poly
    assert Z() == Z([])
    assert Z() == Z([0])
    assert Z() == Z([0,flint.fmpz(0),0])
    assert Z() == Z([0,0L,0])
    assert Z() != Z([1])
    assert Z([1]) == Z([1L])
    assert Z([1]) == Z([flint.fmpz(1)])
    assert Z(Z([1,2])) == Z([1,2])
    for ztype in [int, long, flint.fmpz]:
        assert Z([1,2,3]) + ztype(5) == Z([6,2,3])
        assert ztype(5) + Z([1,2,3]) == Z([6,2,3])
        assert Z([1,2,3]) - ztype(5) == Z([-4,2,3])
        assert ztype(5) - Z([1,2,3]) == Z([4,-2,-3])
        assert Z([1,2,3]) * ztype(5) == Z([5,10,15])
        assert ztype(5) * Z([1,2,3]) == Z([5,10,15])
        assert Z([11,6,2]) // ztype(5) == Z([2,1])
        assert ztype(5) // Z([-2]) == Z([-3])
        assert ztype(5) // Z([1,2]) == 0
        assert Z([11,6,2]) % ztype(5) == Z([1,1,2])
        assert ztype(5) % Z([-2]) == Z([-1])
        assert ztype(5) % Z([1,2]) == 5
        assert Z([1,2,3]) ** ztype(0) == 1
        assert Z([1,2,3]) ** ztype(1) == Z([1,2,3])
        assert Z([1,2,3]) ** ztype(2) == Z([1,4,10,12,9])
    assert +Z([1,2]) == Z([1,2])
    assert -Z([1,2]) == Z([-1,-2])
    assert raises(lambda: Z([1,2,3]) ** -1, (OverflowError, ValueError))
    assert raises(lambda: Z([1,2,3]) ** Z([1,2]), TypeError)
    assert raises(lambda: Z([1,2]) // Z([]), ZeroDivisionError)
    assert raises(lambda: Z([]) // Z([]), ZeroDivisionError)
    assert raises(lambda: Z([1,2]) % Z([]), ZeroDivisionError)
    assert raises(lambda: divmod(Z([1,2]), Z([])), ZeroDivisionError)
    assert Z([]).degree() == -1
    assert Z([]).length() == 0
    p = Z([1,2])
    assert p.length() == 2
    assert p.degree() == 1
    assert p[0] == 1
    assert p[1] == 2
    assert p[2] == 0
    assert p[-1] == 0
    assert raises(lambda: p.__setitem__(-1, 1), ValueError)
    p[0] = 3
    assert p[0] == 3
    p[4] = 7
    assert p.degree() == 4
    assert p[4] == 7
    assert p[3] == 0
    p[4] = 0
    assert p.degree() == 1
    assert p.coeffs() == [3,2]
    assert Z([]).coeffs() == []
    assert bool(Z([])) == False
    assert bool(Z([1])) == True
    assert repr(Z([1,2])) == "fmpz_poly([1, 2])"
    assert str(Z([1,2])) == "2*x+1"
    p = Z([3,4,5])
    assert p(2) == 31
    assert p(flint.fmpq(2,3)) == flint.fmpq(71,9)
    assert p(Z([1,-1])) == Z([12,-14,5])
    assert p(flint.fmpq_poly([2,3],5)) == flint.fmpq_poly([27,24,9],5)
Esempio n. 20
0
 def fmpq(self):
     if not self.is_rational():
         raise ValueError("fmpq() requires a rational value")
     c0 = self._minpoly[0]
     c1 = self._minpoly[1]
     return fmpq(c0) / (-c1)
Esempio n. 21
0
    def as_quadratic(self, factor_limit=2**64):
        """
        Assuming that *self* has degree 1 or 2, returns (*a*, *b*, *c*)
        where *a* and *b* are *fmpq* rational numbers and *c* is a *fmpz*
        integer, such that *self* equals `a + b \sqrt{c}`.

        The integer *c* will not be a perfect square, but might not be
        squarefree since ensuring this property requires integer factorization.
        If *|c|* is initially smaller than *factor_limit*, it will be
        completely factored into its squarefree part (with the square content
        moved to *b*); otherwise, only a partial factorization will be performed.

            >>> alg(-23).as_quadratic()
            (-23, 0, 0)
            >>> (2 + alg.i() / 3).as_quadratic()
            (2, 1/3, -1)
            >>> x = (alg(5)/2 + alg(24).sqrt())**5
            >>> x.as_quadratic()
            (353525/32, 36341/8, 6)
            >>> x == alg(353525)/32 + alg(36341)/8 * alg(6).sqrt()
            True
            >>> alg(3 * 29**2 * (10**20+39)**2).sqrt().as_quadratic()
            (0, 2900000000000000001131, 3)
            >>> x = alg(3 * (10**10+1)**3 * (10**15+1)**2).sqrt()
            >>> a, b, c = x.as_quadratic()
            >>> (a, b, c)
            (0, 39340116598834051, 1938429316132524961593868203)
            >>> x == a + b*alg(c).sqrt()
            True
            >>> a, b, c = x.as_quadratic(factor_limit=10**50)
            >>> (a, b, c)
            (0, 10000000001000010000000001, 30000000003)
            >>> x == a + b*alg(c).sqrt()
            True

        """
        poly = self._minpoly
        if poly.degree() == 1:
            return (self.fmpq(), fmpq(), fmpz())
        if poly.degree() != 2:
            raise ValueError
        c, b, a = list(self.minpoly())
        D = b**2 - 4 * a * c
        Dsqrt = alg(D).sqrt()
        x = (-b + Dsqrt) / (2 * a)
        if self == x:
            bsign = 1
        else:
            x = (-b - Dsqrt) / (2 * a)
            bsign = -1
        a, b, c = fmpq(-b) / (2 * a), fmpq(bsign, 2 * a), D
        if abs(c) >= 4:
            if abs(c) < factor_limit:
                fac = c.factor()
            else:
                fac = c.factor(trial_limit=1000)
                # todo: the partial factoring in flint is wonky;
                # it should at least do a perfect power test or single-word
                # factorisation of the last factor
                if 1:
                    rem, reme = fac[-1]
                    if rem < factor_limit:
                        fac = fac[:-1] + [(pp, ee * reme)
                                          for (pp, ee) in rem.factor()]
                    elif rem.is_perfect_power():
                        for e in range(64, 1, -1):
                            p = rem.root(e)
                            if p**e == rem:
                                if p < factor_limit:
                                    fac2 = rem.factor()
                                    fac = fac[:-1]
                                    for (p, f) in fac2:
                                        fac.append((p, e * f * reme))
                                else:
                                    fac = fac[:-1] + [(p, e * reme)]
                                break
                check = 1
                for p, e in fac:
                    check *= p**e
                # assert check == abs(c)
            square = fmpz(1)
            squarefree = fmpz(1)
            for p, e in fac:
                if e % 2 == 0:
                    square *= p**(e // 2)
                else:
                    square *= p**(e // 2)
                    squarefree *= p
            if c < 0:
                squarefree = -squarefree
            b *= square
            c = squarefree
        # assert self == alg(a) + alg(b) * alg(c).sqrt()
        return a, b, c
Esempio n. 22
0
def test_fmpq_poly():
    Q = flint.fmpq_poly
    Z = flint.fmpz_poly
    assert Q() == Q([]) == Q([0]) == Q([0,0])
    assert Q() != Q([1])
    assert Q([1]) == Q([1])
    assert bool(Q()) == False
    assert bool(Q([1])) == True
    assert Q(Q([1,2])) == Q([1,2])
    assert Q(Z([1,2])) == Q([1,2])
    assert Q([1,2]) + 3 == Q([4,2])
    assert 3 + Q([1,2]) == Q([4,2])
    assert Q([1,2]) - 3 == Q([-2,2])
    assert 3 - Q([1,2]) == Q([2,-2])
    assert -Q([1,2]) == Q([-1,-2])
    assert Q([flint.fmpq(1,2),1]) * 2 == Q([1,2])
    assert Q([1,2]) == Z([1,2])
    assert Z([1,2]) == Q([1,2])
    assert Q([1,2]) != Z([3,2])
    assert Z([1,2]) != Q([3,2])
    assert Q([1,2,3])*Q([1,2]) == Q([1,4,7,6])
    assert Q([1,2,3])*Z([1,2]) == Q([1,4,7,6])
    assert Q([1,2,3]) * 3 == Q([3,6,9])
    assert 3 * Q([1,2,3]) == Q([3,6,9])
    assert Q([1,2,3]) * flint.fmpq(2,3) == (Q([1,2,3]) * 2) / 3
    assert flint.fmpq(2,3) * Q([1,2,3]) == (Q([1,2,3]) * 2) / 3
    assert raises(lambda: Q([1,2]) / Q([1,2]), TypeError)
    assert Q([1,2,3]) / flint.fmpq(2,3) == Q([1,2,3]) * flint.fmpq(3,2)
    assert Q([1,2,3]) ** 2 == Q([1,2,3]) * Q([1,2,3])
    assert Q([1,2,flint.fmpq(1,2)]).coeffs() == [1,2,flint.fmpq(1,2)]
    assert Q().coeffs() == []
    assert Q().degree() == -1
    assert Q([1]).degree() == 0
    assert Q([1,2]).degree() == 1
    assert Q().length() == 0
    assert Q([1]).length() == 1
    assert Q([1,2]).length() == 2
    assert (Q([1,2,3]) / 5).numer() == (Q([1,2,3]) / 5).p == Z([1,2,3])
    assert (Q([1,2,3]) / 5).denom() == (Q([1,2,3]) / 5).q == 5
    assert repr(Q([15,20,10]) / 25) == "fmpq_poly([3, 4, 2], 5)"
    assert str(Q([3,4,2],5)) == "2/5*x^2 + 4/5*x + 3/5"
    a = Q([2,2,3],4)
    assert a[2] == flint.fmpq(3,4)
    a[2] = 4
    assert a == Q([1,1,8],2)
    p = Q([3,4,5],7)
    assert p(2) == flint.fmpq(31,7)
    assert p(flint.fmpq(2,3)) == flint.fmpq(71,63)
    assert p(Z([1,-1])) == Q([12,-14,5],7)
    assert p(flint.fmpq_poly([2,3],5)) == flint.fmpq_poly([27,24,9],7*5)
Esempio n. 23
0
 def w():
     return alg(-1)**fmpq(2, 3)
Esempio n. 24
0
 def enclosure(self, pretty=False):
     if self.degree() == 1:
         c0 = self._minpoly[0]
         c1 = self._minpoly[1]
         return arb(c0) / (-c1)
     elif pretty:
         z = self.enclosure()
         re = z.real
         im = z.imag
         # detect zero real/imag part
         if z.real.contains(0):
             if self.real_sgn() == 0:
                 re = arb(0)
         if z.imag.contains(0):
             if self.imag_sgn() == 0:
                 im = arb(0)
         # detect exact (dyadic) real/imag parts
         # fixme: extracting real and imag parts and checking if
         # they are exact can be slow at high degree; this is a workaround
         # until that operation can be improved
         scale = fmpz(2)**max(10, ctx.prec - 20)
         if not re.is_exact() and (re * scale).unique_fmpz() is not None:
             n = (re * scale).unique_fmpz()
             b = self - fmpq(n, scale)
             if b.real_sgn() == 0:
                 re = arb(fmpq(n, scale))
         if not im.is_exact() and (im * scale).unique_fmpz() is not None:
             n = (im * scale).unique_fmpz()
             b = self - fmpq(n, scale) * alg.i()
             if b.imag_sgn() == 0:
                 im = arb(fmpq(n, scale))
         if im == 0:
             return arb(re)
         else:
             return acb(re, im)
     else:
         orig_prec = ctx.prec
         x = self._enclosure
         if x.rel_accuracy_bits() >= orig_prec - 2:
             return x
         # Try interval newton refinement
         f = self._minpoly
         g = self._minpoly.derivative()
         try:
             ctx.prec = max(x.rel_accuracy_bits(), 32) + 10
             for step in range(40):
                 ctx.prec *= 2
                 if ctx.prec > 1000000:
                     raise ValueError("excessive precision")
                 # print("root-refinement prec", ctx.prec)
                 # print(x.mid().str(10), x.rad().str(10))
                 xmid = x.mid()
                 y = xmid - f(xmid) / g(x)
                 if y.rel_accuracy_bits() >= 1.1 * orig_prec:
                     self._enclosure = y
                     return y
                 if y.rel_accuracy_bits() < 1.5 * x.rel_accuracy_bits() + 1:
                     # print("refinement failed -- recomputing roots")
                     roots = self._minpoly.roots()
                     near = [r for (r, mult) in roots if acb(r).overlaps(x)]
                     if len(near) == 1:
                         y = near[0]
                         if y.rel_accuracy_bits() >= 1.1 * orig_prec:
                             self._enclosure = y
                             return y
                 x = y
             raise ValueError("root refinement did not converge")
         finally:
             ctx.prec = orig_prec
Esempio n. 25
0
 def sin_pi(x, monic=False):
     return alg.cos_pi(fmpq(1, 2) - x, monic=monic)
Esempio n. 26
0
 def exp_pi_i(x):
     x = fmpq(x)
     return alg.exp_two_pi_i(x / 2)