Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 1d63916

Browse files
committed
Test non-monic case.
1 parent d864324 commit 1d63916

File tree

6 files changed

+166
-4
lines changed

6 files changed

+166
-4
lines changed

nf/init_randtest.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ void nf_init_randtest(nf_t nf, flint_rand_t state,
2222
{
2323
fmpq_poly_t pol;
2424
fmpz_poly_t q;
25+
fmpz_t d;
2526

2627
if (len < 2 || bits_in < 1)
2728
{
@@ -53,7 +54,15 @@ void nf_init_randtest(nf_t nf, flint_rand_t state,
5354
fmpz_randtest_not_zero(fmpq_poly_denref(pol), state, bits_in);
5455
fmpq_poly_canonicalise(pol);
5556

57+
fmpz_init(d);
58+
59+
_fmpz_vec_content(d, fmpq_poly_numref(pol), fmpq_poly_length(pol));
60+
61+
if (!fmpz_is_one(d))
62+
_fmpz_vec_scalar_divexact_fmpz(fmpq_poly_numref(pol), fmpq_poly_numref(pol), fmpq_poly_length(pol), d);
63+
5664
nf_init(nf, pol);
5765
fmpq_poly_clear(pol);
5866
fmpz_poly_clear(q);
67+
fmpz_clear(d);
5968
}

nf_elem.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ FLINT_DLL void nf_elem_clear(nf_elem_t a, const nf_t nf);
8383
FLINT_DLL void nf_elem_randtest(nf_elem_t a, flint_rand_t state,
8484
mp_bitcnt_t bits, const nf_t nf);
8585

86+
FLINT_DLL void nf_elem_randtest_bounded(nf_elem_t a, flint_rand_t state,
87+
mp_bitcnt_t bits, const nf_t nf);
88+
8689
FLINT_DLL void nf_elem_randtest_not_zero(nf_elem_t a, flint_rand_t state,
8790
mp_bitcnt_t bits, const nf_t nf);
8891

nf_elem/doc/nf_elem.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,14 @@ void nf_elem_randtest(nf_elem_t a, flint_rand_t state,
3434
mp_bitcnt_t bits, const nf_t nf)
3535

3636
Generate a random number field element $a$ in the number field \code{nf}
37-
whose coefficients have up to the given number of bits.
37+
whose rational coefficients have up to the given number of bits.
38+
39+
void nf_elem_randtest_bounded(nf_elem_t a, flint_rand_t state,
40+
mp_bitcnt_t bits, const nf_t nf)
41+
42+
Generate a random number field element $a$ in the number field \code{nf}
43+
whose coefficients have up to the given number of bits, with combined
44+
denominator also bounded by the given number of bits.
3845

3946
void nf_elem_canonicalise(nf_elem_t a, nf_t nf)
4047

nf_elem/randtest.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,84 @@ void nf_elem_randtest(nf_elem_t a, flint_rand_t state,
6666
}
6767
}
6868

69+
void nf_elem_randtest_bounded(nf_elem_t a, flint_rand_t state,
70+
mp_bitcnt_t bits, const nf_t nf)
71+
{
72+
if (nf->flag & NF_LINEAR)
73+
{
74+
fmpz_randtest(LNF_ELEM_NUMREF(a), state, bits);
75+
76+
if (n_randint(state, 2))
77+
{
78+
fmpz_randtest_not_zero(LNF_ELEM_DENREF(a), state, bits);
79+
fmpz_abs(LNF_ELEM_DENREF(a), LNF_ELEM_DENREF(a));
80+
81+
_fmpq_canonicalise(LNF_ELEM_NUMREF(a), LNF_ELEM_DENREF(a));
82+
} else
83+
fmpz_one(LNF_ELEM_DENREF(a));
84+
} else if (nf->flag & NF_QUADRATIC)
85+
{
86+
fmpz_randtest(QNF_ELEM_NUMREF(a), state, bits);
87+
fmpz_randtest(QNF_ELEM_NUMREF(a) + 1, state, bits);
88+
89+
if (n_randint(state, 2))
90+
{
91+
fmpz_t d;
92+
93+
fmpz_randtest_not_zero(QNF_ELEM_DENREF(a), state, bits);
94+
fmpz_abs(QNF_ELEM_DENREF(a), QNF_ELEM_DENREF(a));
95+
96+
fmpz_init(d);
97+
fmpz_gcd(d, QNF_ELEM_NUMREF(a), QNF_ELEM_NUMREF(a) + 1);
98+
if (!fmpz_is_one(d))
99+
{
100+
fmpz_gcd(d, d, QNF_ELEM_DENREF(a));
101+
102+
if (!fmpz_is_one(d))
103+
{
104+
_fmpz_vec_scalar_divexact_fmpz(QNF_ELEM_NUMREF(a), QNF_ELEM_NUMREF(a), 2, d);
105+
fmpz_divexact(QNF_ELEM_DENREF(a), QNF_ELEM_DENREF(a), d);
106+
}
107+
}
108+
} else
109+
fmpz_one(QNF_ELEM_DENREF(a));
110+
}
111+
else
112+
{
113+
slong i, lenf = nf->pol->length;
114+
fmpz_t d;
115+
116+
for (i = 0; i < lenf - 1; i++)
117+
fmpz_randtest(NF_ELEM_NUMREF(a) + i, state, bits);
118+
119+
if (n_randint(state, 2)) {
120+
fmpz_init(d);
121+
122+
fmpz_randtest_not_zero(NF_ELEM_DENREF(a), state, bits);
123+
fmpz_abs(NF_ELEM_DENREF(a), NF_ELEM_DENREF(a));
124+
125+
_fmpz_vec_content(d, NF_ELEM_NUMREF(a), lenf - 1);
126+
127+
if (!fmpz_is_one(d))
128+
{
129+
fmpz_gcd(d, d, NF_ELEM_DENREF(a));
130+
131+
if (!fmpz_is_one(d))
132+
{
133+
_fmpz_vec_scalar_divexact_fmpz(NF_ELEM_NUMREF(a), NF_ELEM_NUMREF(a), lenf - 1, d);
134+
fmpz_divexact(NF_ELEM_DENREF(a), NF_ELEM_DENREF(a), d);
135+
}
136+
}
137+
138+
fmpz_clear(d);
139+
} else
140+
fmpz_one(NF_ELEM_DENREF(a));
141+
142+
_fmpq_poly_set_length(NF_ELEM(a), lenf - 1);
143+
_fmpq_poly_normalise(NF_ELEM(a));
144+
}
145+
}
146+
69147
void nf_elem_randtest_not_zero(nf_elem_t a, flint_rand_t state,
70148
mp_bitcnt_t bits, const nf_t nf)
71149
{

nf_elem/sqrt.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
* add termination bound for nonsquare case
2727
* Prove homomorphism to Z/pZ in all cases or exclude primes
2828
* Deal with lousy starting bounds (they are too optimistic if f is not monic)
29-
* Fix bug in antic norm function
3029
* Remove small squares from denominator before rationalising
3130
* Cache factorisation of f(n) on number field for future square roots
3231
* add is_square function

nf_elem/test/t-sqrt.c

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ main(void)
240240
fmpq_poly_clear(f);
241241
}
242242

243-
/* test sqrt(a^2) */
243+
/* test sqrt(a^2) monic defining poly */
244244
for (i = 0; i < 100 * antic_test_multiplier(); )
245245
{
246246
nf_t nf;
@@ -271,12 +271,78 @@ main(void)
271271
if (nf->flag & NF_MONIC && num_facs == 1)
272272
{
273273
i++;
274+
275+
nf_elem_init(a, nf);
276+
nf_elem_init(b, nf);
277+
nf_elem_init(c, nf);
278+
nf_elem_init(d, nf);
279+
280+
nf_elem_randtest_bounded(a, state, abits, nf);
281+
282+
nf_elem_mul(b, a, a, nf);
283+
284+
is_square = nf_elem_sqrt(c, b, nf);
285+
286+
nf_elem_mul(d, c, c, nf);
287+
288+
result = is_square && nf_elem_equal(d, b, nf);
289+
if (!result)
290+
{
291+
printf("FAIL:\n");
292+
printf("a = "); nf_elem_print_pretty(a, nf, "x"); printf("\n");
293+
printf("b = "); nf_elem_print_pretty(b, nf, "x"); printf("\n");
294+
printf("c = "); nf_elem_print_pretty(c, nf, "x"); printf("\n");
295+
printf("d = "); nf_elem_print_pretty(d, nf, "x"); printf("\n");
296+
abort();
297+
}
298+
299+
nf_elem_clear(a, nf);
300+
nf_elem_clear(b, nf);
301+
nf_elem_clear(c, nf);
302+
nf_elem_clear(d, nf);
303+
}
304+
305+
nf_clear(nf);
306+
}
307+
308+
/* test sqrt(a^2) non-monic defining poly */
309+
for (i = 0; i < 100 * antic_test_multiplier(); )
310+
{
311+
nf_t nf;
312+
nf_elem_t a, b, c, d;
313+
int is_square, num_facs;
314+
slong flen, fbits, abits;
315+
fmpz_poly_factor_t fac;
316+
fmpz_poly_t pol; /* do not clear */
317+
318+
flen = n_randint(state, 10) + 2;
319+
fbits = n_randint(state, 10) + 1;
320+
abits = n_randint(state, 10) + 1;
321+
322+
nf_init_randtest(nf, state, flen, fbits);
323+
324+
fmpz_poly_factor_init(fac);
325+
326+
pol->coeffs = nf->pol->coeffs;
327+
pol->length = nf->pol->length;
328+
pol->alloc = nf->pol->alloc;
329+
330+
fmpz_poly_factor(fac, pol);
331+
332+
num_facs = fac->num*fac->exp[0];
333+
334+
fmpz_poly_factor_clear(fac);
335+
336+
if (num_facs == 1)
337+
{
338+
i++;
339+
274340
nf_elem_init(a, nf);
275341
nf_elem_init(b, nf);
276342
nf_elem_init(c, nf);
277343
nf_elem_init(d, nf);
278344

279-
nf_elem_randtest(a, state, abits, nf);
345+
nf_elem_randtest_bounded(a, state, abits, nf);
280346

281347
nf_elem_mul(b, a, a, nf);
282348

0 commit comments

Comments
 (0)