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