Example #1
0
def sievesum1(n, p):
    """
    Return the sum of all of the numbers not
    excluded by a sieve of [1..n] by all primes
    up to and including p.
    
    Uses the lucy_hedgehog algorithm for summing
    the primes in [0, n] (faster than a sieve)

    In theory this works.  But for large n we
    hit maximum stack depth.  And we are using
    prime() to check primality when we should
    be able to determine it from our own
    computation.
    """

    if n == 0:
        retval = 0
    elif p == 0:
        retval = n * (n + 1) // 2 - 1
    elif (n, p) in sievesum_hash:
        return sievesum_hash[(n, p)]
    else:
        while not isprime(p):
            p -= 1
        retval = sievesum(n, p - 1)
        if isprime(p) and p * p <= n:
            num_excluded = sievesum(n // p, p - 1) - sievesum(p - 1, p - 1)
            retval -= p * num_excluded

    sievesum_hash[(n, p)] = retval
    return retval
Example #2
0
def biquadratic_residue_table():
    print("""A table of biquadratic residues.  Each column shows
    the values of the character associated with the prime at the
    top of the column
    """)

    maxp = 75
    qprimes = [(flip(jacobi_sum_quartic(qq)) if
                (qq % 4 == 1) else GaussianInteger(qq))
               for qq in range(3, maxp, 2) if isprime(qq)]
    pprimes = qprimes

    print('%5s' % ' ', end=' ')
    for pi2 in qprimes:
        print('%4s' % (GaussianInteger(pi2.real(), 0), ), end=' ')
    print('')

    print('%5s' % ' ', end=' ')
    for pi2 in qprimes:
        if pi2.imag() == 0:
            print('%4s' % ' ', end=' ')
        else:
            print('%+4s' % (GaussianInteger(0, pi2.imag()), ), end=' ')
    print('')

    for pi1 in pprimes:
        print('%5s' % (pi1, ), end=' ')
        for pi2 in qprimes:
            if pi1 == pi2:
                print('%4s' % ' ', end=' ')
            else:
                print('%4s' % (biquad(pi2, pi1), ), end=' ')
        print('')
Example #3
0
def run():
    print(u"""
    For the curve given by the affine equation

    x\u00B2 + y\u00B2 + x\u00B2y\u00B2 = 1

    calculate the number of points on curve over
    the finite field Z/pZ.

    If p\u22611(4), and we write p=a\u00B2+b\u00B2 with
    a odd and b even and

    a\u22613(4) if b\u2261 2(4)
    a\u22611(4) if b\u2261 0(4)

    then Gauss conjectured that the number of points
    on this curve, including the 2 add'l points at
    infinity, should equal

    p-1-2a.

    Do a brute force calculation and verify this for
    such primes up to 199.
    """)

    for p in range(5, 200, 4):
        if isprime(p):
            ff = FiniteField(p, 1)
            f = gauss_polynomial(ff)
            np = count_curve_points_affine(f, ff)
            js = ff.jacobi_sum(4)
            a, b = normalize(js[0], js[1])
            print('%4d %5d+2 = p-1%+3d, J=%+2.0f%+2.0fi' %
                  (p, np, (np + 2 - p + 1), a, b))
Example #4
0
def table2():
    maxp = 75
    q2primes = [
        flip(jacobi_sum_quartic(qq)) for qq in range(5, maxp, 4) if isprime(qq)
    ]

    for pi1 in q2primes:
        for pi in [
                pi1,
                GaussianInteger(pi1.real(), -pi1.imag()),
                GaussianInteger(-pi1.imag(), pi1.real()),
                GaussianInteger(-pi1.real(), -pi1.imag()),
                GaussianInteger(pi1.imag(), -pi1.real()),
                GaussianInteger(pi1.real(), -pi1.imag()),
                GaussianInteger(pi1.imag(), pi1.real()),
                GaussianInteger(-pi1.real(), pi1.imag()),
                GaussianInteger(-pi1.imag(), -pi1.real())
        ]:

            chi = Character(pi)
            chi2 = chi * chi

            print('%10s %10s %10s %10s' %
                  (pi, chi(GaussianInteger(-1)), jacobi_sum(
                      chi, chi, pi.norm()), jacobi_sum(chi, chi2, pi.norm())))
def repsmod11():
    p = 1
    gen = genus(1, 0, 11)
    while True:
        if (p % 44) in gen and isprime(p):
            yield p, repmod11(p)
        p += 1
Example #6
0
def legendre_ch(d):
    """
    Return the mod abs(disc Q[√d]) Legendre character.

    This is the character ch with modulus D=abs(disc Q[√d])
    such that for any odd prime p, ch(p)=(d/p) (i.e.

    ch(p)=0 if p|d
    ch(p)=1 if d is a square mod p
    ch(p)=-1 if d is not a square mod p
    """
    if not squarefree(d):
        raise ValueError('%d is not square free' % (d, ))

    abs_disc = abs(discriminant(d))

    vals = [0] * abs_disc

    for k in range(abs_disc):
        if gcd(abs_disc, k) == 1:
            n = k
            while True:
                if isprime(n) and n % 2 == 1:
                    vals[k] = legendre(d, n)
                    break
                n += abs_disc
    return lambda a: vals[a % abs_disc]
Example #7
0
def run1():
    """
    Calculate the Jacobi sums of a cubic character
    for some finite fields of order p^2
    """

    zeta3 = np.cos(2*np.pi/3) + 1j*np.sin(2*np.pi/3)

    # These are all going to
    for p in (pp for pp in range(7, 200, 12) if isprime(pp)):

        nnp = p if (p % 4 == 1) else p*p

        # print 'Finite Field with %d^2=%d elements' % (p, p*p)
        def mul(a, b):
            # Here's how we multiply Gaussian integers
            return (a[0]*b[0]-a[1]*b[1]) % p, (a[0]*b[1]+a[1]*b[0]) % p

        def add(a, b):
            # Here's how we add Gaussian integers
            return ((a[0]+b[0]) % p), ((a[1]+b[1]) % p)

        def order(a):
            retval = 1
            b = a
            while b != (1, 0):
                b = mul(b, a)
                retval += 1
            return retval

        def prim_elt():
            for x in range(p):
                for y in range(p):
                    elt = (x, y)
                    if elt == (0, 0):
                        continue
                    if order(elt) == p*p-1:
                        return elt

        xx = prim_elt()
        powers = [(0, 0), (1, 0)]
        cnt = 0
        while cnt < nnp-2:
            powers.append(mul(powers[-1], xx))
            cnt += 1

        chars = [0.0] + list(map(lambda n: zeta3**n, range(p*p)))
        avals = powers
        bvals = map(lambda yy: add((1, 0), mul((-1, 0), yy)), avals)
        bindices = [avals.index(bb) for bb in bvals]
        bchars = [chars[bi] for bi in bindices]
        jsum = sum(aa*bb for (aa, bb) in zip(chars, bchars))

        # express jsum as an integral combination of 1 and zeta3=(-1+sqrt(3))/2
        #
        c2 = jsum.imag/(np.sqrt(3.0)/2.0)
        tmp = jsum - c2*zeta3
        c1 = tmp.real

        print('%6d %10d %35s %7.1f %7.1f %35s %s' % (p, p*p, jsum, c1, c2, c1+c2*zeta3, '%d+%di' % xx))
Example #8
0
def primesum_naive(n):
    """
    A slow, reference implementation.  Add up
    the all of the primes in the range [0, n]
    """
    retval = 0
    k = 2
    while k <= n:
        if isprime(k):
            retval += k
        k += 1
    return retval
Example #9
0
def run2():
    for p in []:
        if not isprime(p):
            continue
            # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61] :
        cnt = 0
        for x in range(p):
            for y in range(p):
                cnt += f(x, y, p) == 0
        bound = 2*int(np.sqrt(p))
        if abs(cnt-p) >= bound:
            print('%5d %5d %5d %5d' % (p, cnt, cnt - p, bound))
Example #10
0
 def test_isprime(self):
     self.assertEqual(False, isprime(0), 'zero is not a (maximal) prime')
     self.assertEqual(False, isprime(1), 'units are not prime')
     self.assertEqual(True, isprime(7), 'yes, 7 is a prime')
     self.assertEqual(False, isprime(49), 'a non-unit square is not prime')
     self.assertEqual(False, isprime(91), '91=7*13 is not prime')
     self.assertEqual(True, isprime(-7),
                      '(some) negative numbers are prime')
     self.assertRaises(TypeError, isprime, 7.0)
Example #11
0
def class_group_info(d):
    r"""
    :param d: a non-square integer
    :return: prints information relevant to the class group of the ring
             of integers in :math:`\mathbb{Q}(\sqrt{d})`
    """
    mb = minkowski_bound(d)
    disc = discriminant(d)
    print('Discriminant = %d' % disc)
    print('Minkowski Bound = %d' % (mb, ))
    split_primes = []
    for p in [pp for pp in range(2, mb + 1) if isprime(pp)]:
        fact = factorize_in(p, d)
        if fact == (p, ):
            print(fact)
        else:
            md = norm_search(p, d)
            print(fact, md)
            if md is None:
                split_primes.append(p)

    if (d % 4) != 1 and d > 0:
        print('approximant based elements and norms')
        print([(xx, xx.norm()) for xx in approximants(d)])

    if not split_primes:
        print('No non principal primes under the Minkowski bound!')
        return
    print('Split primes')
    print(split_primes)
    print('Split primes that are not squares mod %d' % (d, ))
    sq = squares_mod_d(d)
    print(
        [pp for pp in split_primes if (pp not in sq) and ((d - pp) not in sq)])

    for ii in range(len(split_primes)):
        for jj in range(ii, len(split_primes)):
            p = split_primes[ii] * split_primes[jj]
            md = norm_search(p, d)
            print(p, md)

    for ii in range(len(split_primes)):
        for jj in range(ii, len(split_primes)):
            for kk in range(jj, len(split_primes)):
                p = split_primes[ii] * split_primes[jj] * split_primes[kk]
                md = norm_search(p, d)
                print(p, md)
Example #12
0
def all_modm_chars(m):
    r"""
    Returns a list of all mod m characters,
    starting with the trivial character.  Only
    works with prime m for now.
    """
    if not isprime(m):
        raise ValueError("%d is not a prime." % (m, ))
    a = primitive_root(m)
    zz = np.exp(2.0j * np.pi / (m - 1))

    vals = [None] * (m - 1)
    pows = [0] + [modpow(a, k, m) for k in range(m - 1)]
    for k in range(m - 1):
        pows2 = [0] + [(zz**k)**i for i in range(m - 1)]
        vals[k] = dict(zip(pows, pows2))
    return map(lambda val: (lambda ii: val[ii % m]), vals)
def run():
    print(u"""
    For a fixed characteristic p (where 3 divides p-1), there
    is a unique (up to conjugation) non-trivial cubic
    character \u03C7 on F_{p^k}, and so the real part of
    the Jacobi sum J(\u03C7, \u03C7) only depends on the
    field F_{p^k}.

    Calculate J(\u03C7, \u03C7) for range of values of k
    to get an idea of how these values are related to
    each other.
    """)

    theta = 2*np.pi/3
    zeta = np.cos(theta)+1j*np.sin(theta)
    pi = -1-3*zeta
    for p in [7, 13]:
        if isprime(p):
            for ii in range(1, 5):
                ff = FiniteField(p, ii)
                c0, c1 = ff.jacobi_sum(3)
                nk = count_diagonal_cubic_points(ff)
                print(u'%6d    %+.0f%+.0f\u03c9   %4.0f   %4d' %
                      (p**ii, c0, c1, (p**ii+1)-(-1)**ii*(pi**ii + pi.conj()**ii).real, nk))
Example #14
0
def legendre(a, p):
    """
    Return (a/p), the Legendre symbol (p is prime)

    (a/p) = 0 if p|a
          = 1 if a is a quad residue mod p
          = -1 if a is a quad non-residue mod p
    """
    a = a % p
    if a == 0:
        return 0
    if a == 1:
        return 1
    if a == -1:
        if p % 4 == 3:
            return -1
        elif p % 4 == 1:
            return 1
        else:
            return 0
    if a == 2:
        p_mod_8 = p % 8
        if p_mod_8 == 1 or p_mod_8 == 7:
            return 1
        elif p_mod_8 == 3 or p_mod_8 == 5:
            return -1
        else:
            return 0

    if not isprime(a):
        return prod([legendre(q, p) for q, e in factorize2(a) if e % 2])

    if p % 4 == 1 or a % 4 == 1:
        return legendre(p % a, a)
    else:
        return -legendre(p % a, a)