1 /*=============================================================================
2 
3     This file is part of Antic.
4 
5     Antic is free software: you can redistribute it and/or modify it under
6     the terms of the GNU Lesser General Public License (LGPL) as published
7     by the Free Software Foundation; either version 2.1 of the License, or
8     (at your option) any later version. See <http://www.gnu.org/licenses/>.
9 
10 =============================================================================*/
11 /******************************************************************************
12 
13     Copyright (C) 2013 Fredrik Johansson
14     Copyright (C) 2013, 2014 William Hart
15 
16 ******************************************************************************/
17 
18 #include "nf_elem.h"
19 #include "flint/ulong_extras.h"
20 
nf_elem_randtest(nf_elem_t a,flint_rand_t state,mp_bitcnt_t bits,const nf_t nf)21 void nf_elem_randtest(nf_elem_t a, flint_rand_t state,
22                                                mp_bitcnt_t bits, const nf_t nf)
23 {
24     if (nf->flag & NF_LINEAR)
25     {
26         fmpz_randtest(LNF_ELEM_NUMREF(a), state, bits);
27 
28         if (n_randint(state, 2))
29         {
30            fmpz_randtest_not_zero(LNF_ELEM_DENREF(a), state, bits);
31            fmpz_abs(LNF_ELEM_DENREF(a), LNF_ELEM_DENREF(a));
32 
33            _fmpq_canonicalise(LNF_ELEM_NUMREF(a), LNF_ELEM_DENREF(a));
34         } else
35            fmpz_one(LNF_ELEM_DENREF(a));
36     } else if (nf->flag & NF_QUADRATIC)
37     {
38         fmpz_randtest(QNF_ELEM_NUMREF(a), state, bits);
39         fmpz_randtest(QNF_ELEM_NUMREF(a) + 1, state, bits);
40 
41         if (n_randint(state, 2))
42         {
43            fmpz_t d;
44 
45            fmpz_randtest_not_zero(QNF_ELEM_DENREF(a), state, bits);
46            fmpz_abs(QNF_ELEM_DENREF(a), QNF_ELEM_DENREF(a));
47 
48            fmpz_init(d);
49            fmpz_gcd(d, QNF_ELEM_NUMREF(a), QNF_ELEM_NUMREF(a) + 1);
50            if (!fmpz_is_one(d))
51            {
52               fmpz_gcd(d, d, QNF_ELEM_DENREF(a));
53 
54               if (!fmpz_is_one(d))
55               {
56                  _fmpz_vec_scalar_divexact_fmpz(QNF_ELEM_NUMREF(a), QNF_ELEM_NUMREF(a), 2, d);
57                  fmpz_divexact(QNF_ELEM_DENREF(a), QNF_ELEM_DENREF(a), d);
58               }
59            }
60         } else
61            fmpz_one(QNF_ELEM_DENREF(a));
62     }
63     else
64     {
65         fmpq_poly_randtest(NF_ELEM(a), state, nf->pol->length - 1, bits);
66     }
67 }
68 
nf_elem_randtest_not_zero(nf_elem_t a,flint_rand_t state,mp_bitcnt_t bits,const nf_t nf)69 void nf_elem_randtest_not_zero(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        do {
75           nf_elem_randtest(a, state, bits, nf);
76        } while (fmpz_is_zero(QNF_ELEM_NUMREF(a)));
77    } else if (nf->flag & NF_QUADRATIC)
78    {
79        do {
80           nf_elem_randtest(a, state, bits, nf);
81        } while (fmpz_is_zero(QNF_ELEM_NUMREF(a)) && fmpz_is_zero(QNF_ELEM_NUMREF(a) + 1));
82    } else
83    {
84       do {
85           nf_elem_randtest(a, state, bits, nf);
86        } while (fmpq_poly_is_zero(NF_ELEM(a)));
87    }
88 }
89