1 /*
2     Copyright (C) 2020 Daniel Schultz
3 
4     This file is part of FLINT.
5 
6     FLINT is free software: you can redistribute it and/or modify it under
7     the terms of the GNU Lesser General Public License (LGPL) as published
8     by the Free Software Foundation; either version 2.1 of the License, or
9     (at your option) any later version.  See <https://www.gnu.org/licenses/>.
10 */
11 
12 #include "fmpq.h"
13 
_fmpq_gcd_cofactors(fmpz_t ng_,fmpz_t dg_,fmpz_t abar,fmpz_t bbar,const fmpz_t na,const fmpz_t da,const fmpz_t nb,const fmpz_t db)14 void _fmpq_gcd_cofactors(
15     fmpz_t ng_, fmpz_t dg_,
16     fmpz_t abar,
17     fmpz_t bbar,
18     const fmpz_t na, const fmpz_t da,
19     const fmpz_t nb, const fmpz_t db)
20 {
21     fmpz_t ng, dg, nabar, dabar, nbbar, dbbar;
22 #if FLINT_WANT_ASSERT
23     fmpq_t cqt_g;
24     int input_is_canonical = _fmpq_is_canonical(na, da) &&
25                              _fmpq_is_canonical(nb, db);
26 #endif
27 
28     fmpz_init(ng);
29 
30     fmpz_gcd(ng, na, nb);
31     if (fmpz_is_zero(ng))
32     {
33         fmpz_zero(ng_);
34         fmpz_one(dg_);
35         fmpz_zero(abar);
36         fmpz_zero(bbar);
37         fmpz_clear(ng);
38         return;
39     }
40 
41 #if FLINT_WANT_ASSERT
42     fmpq_init(cqt_g);
43     _fmpq_gcd(fmpq_numref(cqt_g), fmpq_denref(cqt_g), na, da, nb, db);
44 #endif
45 
46     fmpz_init(dg);
47     fmpz_init(nabar);
48     fmpz_init(dabar);
49     fmpz_init(nbbar);
50     fmpz_init(dbbar);
51 
52     fmpz_divexact(nabar, na, ng);
53     fmpz_divexact(nbbar, nb, ng);
54 
55     fmpz_gcd(dg, da, db);
56     fmpz_divexact(dabar, da, dg);
57     fmpz_divexact(dbbar, db, dg);
58 
59     fmpz_mul(abar, nabar, dbbar);
60     fmpz_mul(bbar, dabar, nbbar);
61     fmpz_mul(dg_, da, dbbar);
62     fmpz_swap(ng_, ng);
63 
64 #if FLINT_WANT_ASSERT
65     if (input_is_canonical)
66     {
67         FLINT_ASSERT(fmpz_equal(fmpq_numref(cqt_g), ng_));
68         FLINT_ASSERT(fmpz_equal(fmpq_denref(cqt_g), dg_));
69         fmpz_gcd(ng, abar, bbar);
70         FLINT_ASSERT(fmpz_is_one(ng));
71     }
72     fmpq_clear(cqt_g);
73 #endif
74 
75     fmpz_clear(ng);
76     fmpz_clear(dg);
77     fmpz_clear(nabar);
78     fmpz_clear(dabar);
79     fmpz_clear(nbbar);
80     fmpz_clear(dbbar);
81 }
82