Annotation of OpenXM_contrib/gmp/demos/qcn.c, Revision 1.1.1.1
1.1 maekawa 1: /* Use mpz_kronecker_ui() to calculate an estimate for the quadratic
2: class number h(d), for a given negative fundamental discriminant, using
3: Dirichlet's analytic formula. */
4:
5: /*
6: Copyright (C) 1999, 2000 Free Software Foundation, Inc.
7:
8: This file is part of the GNU MP Library.
9:
10: This program is free software; you can redistribute it and/or modify it
11: under the terms of the GNU General Public License as published by the Free
12: Software Foundation; either version 2 of the License, or (at your option)
13: any later version.
14:
15: This program is distributed in the hope that it will be useful, but WITHOUT
16: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18: more details.
19:
20: You should have received a copy of the GNU General Public License along with
21: this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22: Place - Suite 330, Boston, MA 02111-1307, USA. */
23:
24:
25: /* Usage: qcn <discriminant>...
26:
27: A fundamental discriminant means one of the form D or 4*D with D
28: square-free. Each argument is checked to see it's congruent to 0 or 1
29: mod 4 (as all discriminants must be), and that it's negative, but there's
30: no check on D being square-free.
31:
32: This program is a bit of a toy, there are better methods for calculating
33: the class number and class group structure.
34:
35: Reference:
36:
37: Daniel Shanks, "Class Number, A Theory of Factorization, and Genera",
38: Proc. Symp. Pure Math., vol 20, 1970, pages 415-440.
39:
40: */
41:
42: #include <math.h>
43: #include <stdio.h>
44:
45: #include "gmp.h"
46:
47:
48: /* A simple but slow primality test. */
49: int
50: prime_p (unsigned long n)
51: {
52: unsigned long i, limit;
53:
54: if (n == 2)
55: return 1;
56: if (n < 2 || !(n&1))
57: return 0;
58:
59: limit = (unsigned long) floor (sqrt ((double) n));
60: for (i = 3; i <= limit; i+=2)
61: if ((n % i) == 0)
62: return 0;
63:
64: return 1;
65: }
66:
67:
68: /* The formula is as follows, with d < 0.
69:
70: w * sqrt(-d) inf p
71: h(d) = ------------ * product --------
72: 2 * pi p=2 p - (d/p)
73:
74:
75: (d/p) is the Kronecker symbol and the product is over primes p. w is 6
76: when d=-3, 4 when d=-4, or 2 otherwise.
77:
78: Calculating the product up to p=infinity would take a long time, so for
79: the estimate primes up to 132,000 are used. Shanks found this giving an
80: accuracy of about 1 part in 1000, in normal cases. */
81:
82: double
83: qcn_estimate (mpz_t d)
84: {
85: #define P_LIMIT 132000
86:
87: double h;
88: unsigned long p;
89:
90: /* p=2 */
91: h = sqrt (-mpz_get_d (d)) / M_PI
92: * 2.0 / (2.0 - mpz_kronecker_ui (d, 2));
93:
94: if (mpz_cmp_si (d, -3) == 0) h *= 3;
95: else if (mpz_cmp_si (d, -4) == 0) h *= 2;
96:
97: for (p = 3; p < P_LIMIT; p += 2)
98: if (prime_p (p))
99: h *= (double) p / (double) (p - mpz_kronecker_ui (d, p));
100:
101: return h;
102: }
103:
104:
105: void
106: qcn_str (char *num)
107: {
108: mpz_t z;
109:
110: mpz_init_set_str (z, num, 0);
111:
112: if (mpz_sgn (z) >= 0)
113: {
114: mpz_out_str (stdout, 0, z);
115: printf (" is not supported (negatives only)\n");
116: }
117: else if (mpz_fdiv_ui (z, 4) != 0 && mpz_fdiv_ui (z, 4) != 1)
118: {
119: mpz_out_str (stdout, 0, z);
120: printf (" is not a discriminant (must == 0 or 1 mod 4)\n");
121: }
122: else
123: {
124: printf ("h(");
125: mpz_out_str (stdout, 0, z);
126: printf (") approx %.1f\n", qcn_estimate (z));
127: }
128: mpz_clear (z);
129: }
130:
131:
132: int
133: main (int argc, char *argv[])
134: {
135: int i;
136:
137: if (argc < 2)
138: {
139: qcn_str ("-85702502803"); /* is 16259 */
140: qcn_str ("-328878692999"); /* is 1499699 */
141: qcn_str ("-928185925902146563"); /* is 52739552 */
142: qcn_str ("-84148631888752647283"); /* is 496652272 */
143: }
144: else
145: {
146: for (i = 1; i < argc; i++)
147: qcn_str (argv[i]);
148: }
149:
150: return 0;
151: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>