예제 #1
0
def class_nr_pos_def_qf(D):
    r"""
    Compute the class number of positive definite quadratic forms.
    For fundamental discriminants this is the class number of Q(sqrt(D)),
    otherwise it is computed using: Cohen 'A course in Computational Algebraic Number Theory', p. 233
    """
    if D>0:
        return 0
    D4 = D % 4
    if D4 == 3 or D4==2:
        return 0
    K = QuadraticField(D)
    if is_fundamental_discriminant(D):
        return K.class_number()
    else:
        D0 = K.discriminant()
        Df = ZZ(D).divide_knowing_divisible_by(D0)
        if not is_square(Df):
            raise ArithmeticError,"DId not get a discrinimant * square! D={0} disc(D)={1}".format(D,D0)
        D2 = sqrt(Df)
        h0 = QuadraticField(D0).class_number()
        w0 = _get_w(D0)
        w = _get_w(D)
        #print "w,w0=",w,w0
        #print "h0=",h0
        h = 1
        for p in prime_divisors(D2):
            h = QQ(h)*(1-kronecker(D0,p)/QQ(p))
        #print "h=",h
        #print "fak=",
        h=QQ(h*h0*D2*w)/QQ(w0)
        return h
예제 #2
0
    def lpp_table(self):
        """generate the large putative primes table"""

        output_str = r"${Delta_K}$ & $\Q(\sqrt{{{D}}})$ & {large_putative_primes}\\"
        latex_output = []
        for D in range(-self.range, self.range + 1):
            if Integer(D).is_squarefree():
                if not D in CLASS_NUMBER_ONE_DISCS:
                    if D != 1:
                        K = QuadraticField(D)
                        Delta_K = K.discriminant()
                        candidates = get_isogeny_primes(K,
                                                        aux_prime_count=25,
                                                        bound=2000,
                                                        loop_curves=False)
                        candidates = [
                            c for c in candidates
                            if c not in EC_Q_ISOGENY_PRIMES
                        ]
                        candidates = [c for c in candidates if c > 71]
                        candidates.sort()
                        large_putative_primes = ", ".join(map(str, candidates))
                        output_here = output_str.format(
                            Delta_K=Delta_K,
                            D=D,
                            large_putative_primes=large_putative_primes,
                        )
                        latex_output.append(output_here)

        for one_line in latex_output:
            print(one_line)
예제 #3
0
def class_nr_pos_def_qf(D):
    r"""
    Compute the class number of positive definite quadratic forms.
    For fundamental discriminants this is the class number of Q(sqrt(D)),
    otherwise it is computed using: Cohen 'A course in Computational Algebraic Number Theory', p. 233
    """
    if D>0:
        return 0
    D4 = D % 4
    if D4 == 3 or D4==2:
        return 0
    K = QuadraticField(D)
    if is_fundamental_discriminant(D):
        return K.class_number()
    else:
        D0 = K.discriminant()
        Df = ZZ(D).divide_knowing_divisible_by(D0)
        if not is_square(Df):
            raise ArithmeticError("Did not get a discrimimant * square! D={0} disc(D)={1}".format(D,D0))
        D2 = sqrt(Df)
        h0 = QuadraticField(D0).class_number()
        w0 = _get_w(D0)
        w = _get_w(D)
        #print "w,w0=",w,w0
        #print "h0=",h0
        h = 1
        for p in prime_divisors(D2):
            h = QQ(h)*(1-kronecker(D0,p)/QQ(p))
        #print "h=",h
        #print "fak=",
        h=QQ(h*h0*D2*w)/QQ(w0)
        return h
예제 #4
0
def oezman_sieve(p, N):
    """Returns True iff p is in S_N. Only makes sense if p ramifies in K"""

    M = QuadraticField(-N)
    h_M = M.class_number()
    H = M.hilbert_class_field("b")
    primes_above_p = M.primes_above(p)

    primes_tot_split_in_hcf = []

    for P in primes_above_p:
        if len(H.primes_above(P)) == h_M:
            primes_tot_split_in_hcf.append(P)

    if not primes_tot_split_in_hcf:
        return False

    f = R(hilbert_class_polynomial(M.discriminant()))
    B = NumberField(f, name="t")
    assert B.degree() == h_M

    possible_nus = B.primes_above(p)

    for nu in possible_nus:
        if nu.residue_class_degree() == 1:
            return True

    return False
예제 #5
0
def test_interval(D):
    K = QuadraticField(D)
    if not K.discriminant() in CLASS_NUMBER_ONE_DISCS:
        superset, _ = get_isogeny_primes(K, **TEST_SETTINGS)
        # test that there are not too many primes left over
        todo = set(superset).difference(EC_Q_ISOGENY_PRIMES)
        assert len(todo) == 0 or max(todo) <= 109
        assert len(todo) <= 2 or max(todo) <= 31
예제 #6
0
def oezman_sieve(p, N):
    """If p is unramified in Q(sqrt(-N)) this always returns True.
    Otherwise returns True iff p is in S_N or . Only makes sense if p ramifies in K"""

    M = QuadraticField(-N)
    if p.divides(M.discriminant()):
        return True

    pp = (M * p).factor()[0][0]
    C_M = M.class_group()
    if C_M(pp).order() == 1:
        return True

    return False
예제 #7
0
def main():
    for D in square_free_D:
        K = QuadraticField(D)
        if not K.discriminant() in CLASS_NUMBER_ONE_DISCS:
            superset, _ = get_isogeny_primes(
                K,
                bound=1000,
                ice_filter=True,
                appendix_bound=1000,
                norm_bound=50,
                auto_stop_strategy=True,
                repeat_bound=4,
            )
            possible_new_isog_primes = superset - EC_Q_ISOGENY_PRIMES
            possible_new_isog_primes_list = list(possible_new_isog_primes)
            possible_new_isog_primes_list.sort()
            if possible_new_isog_primes_list:
                print(f"D = {D} possible isogenies = {possible_new_isog_primes_list}")
예제 #8
0
    def dlmv_table(self):
        """generate the dlmv table"""

        output_str = (
            r"${Delta_K}$ & $\Q(\sqrt{{{D}}})$ & ${rem} \times 10^{{{exp_at_10}}}$\\"
        )
        for D in range(-self.range, self.range + 1):
            if Integer(D).is_squarefree():
                if not D in CLASS_NUMBER_ONE_DISCS:
                    if D != 1:
                        K = QuadraticField(D)
                        Delta_K = K.discriminant()
                        dlmv_bound = RR(DLMV(K))
                        log_dlmv_bound = dlmv_bound.log10()
                        exp_at_10 = int(log_dlmv_bound)
                        rem = log_dlmv_bound - exp_at_10
                        rem = 10**rem
                        rem = rem.numerical_approx(digits=3)
                        output_here = output_str.format(Delta_K=Delta_K,
                                                        D=D,
                                                        rem=rem,
                                                        exp_at_10=exp_at_10)
                        print(output_here)