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) 2014 William Hart
14 
15 ******************************************************************************/
16 
17 #include "nf_elem.h"
18 
_nf_elem_inv(nf_elem_t a,const nf_elem_t b,const nf_t nf)19 void _nf_elem_inv(nf_elem_t a, const nf_elem_t b, const nf_t nf)
20 {
21    if (nf->flag & NF_LINEAR)
22    {
23       if (a == b)
24          fmpz_swap(LNF_ELEM_NUMREF(a), LNF_ELEM_DENREF(a));
25       else
26       {
27          fmpz_set(LNF_ELEM_NUMREF(a), LNF_ELEM_DENREF(b));
28          fmpz_set(LNF_ELEM_DENREF(a), LNF_ELEM_NUMREF(b));
29       }
30       _fmpq_canonicalise(LNF_ELEM_NUMREF(a), LNF_ELEM_DENREF(a));
31    } else if (nf->flag & NF_QUADRATIC)
32    {
33       fmpz * const anum = QNF_ELEM_NUMREF(a);
34       fmpz * const aden = QNF_ELEM_DENREF(a);
35       const fmpz * const bnum = QNF_ELEM_NUMREF(b);
36       const fmpz * const bden = QNF_ELEM_DENREF(b);
37       fmpz * t = _fmpz_vec_init(6);
38       slong len = 2;
39 
40       while (len > 0 && fmpz_is_zero(bnum + len - 1))
41          len--;
42 
43       _fmpq_poly_xgcd(t + 3, t + 5, t, t + 2, anum, aden,
44              fmpq_poly_numref(nf->pol), fmpq_poly_denref(nf->pol), 3, bnum, bden, len);
45 
46       _fmpz_vec_clear(t, 6);
47    } else
48    {
49       fmpq_poly_t g, t;
50 
51       fmpq_poly_init(g);
52       fmpq_poly_init(t);
53 
54       fmpq_poly_xgcd(g, NF_ELEM(a), t, NF_ELEM(b), nf->pol);
55 
56       fmpq_poly_clear(t);
57       fmpq_poly_clear(g);
58    }
59 }
60 
nf_elem_inv(nf_elem_t a,const nf_elem_t b,const nf_t nf)61 void nf_elem_inv(nf_elem_t a, const nf_elem_t b, const nf_t nf)
62 {
63    nf_elem_t t;
64 
65    if (a == b)
66    {
67       nf_elem_init(t, nf);
68 
69       _nf_elem_inv(t, b, nf);
70       nf_elem_swap(t, a, nf);
71 
72       nf_elem_clear(t, nf);
73    }
74    else
75       _nf_elem_inv(a, b, nf);
76 }
77