1 /*
2     Copyright (C) 2011 Fredrik Johansson
3     Copyright (C) 2011 Sebastian Pancratz
4 
5     This file is part of FLINT.
6 
7     FLINT is free software: you can redistribute it and/or modify it under
8     the terms of the GNU Lesser General Public License (LGPL) as published
9     by the Free Software Foundation; either version 2.1 of the License, or
10     (at your option) any later version.  See <http://www.gnu.org/licenses/>.
11 */
12 
13 #ifndef FMPQ_H
14 #define FMPQ_H
15 
16 #ifdef FMPQ_INLINES_C
17 #define FMPQ_INLINE FLINT_DLL
18 #else
19 #define FMPQ_INLINE static __inline__
20 #endif
21 
22 #undef ulong
23 #define ulong ulongxx /* interferes with system includes */
24 #include <stdio.h>
25 #undef ulong
26 
27 #include <gmp.h>
28 #include <mpfr.h>
29 #define ulong mp_limb_t
30 #include "flint.h"
31 #include "fmpz.h"
32 #include "fmpz_vec.h"
33 
34 
35 #ifdef __cplusplus
36  extern "C" {
37 #endif
38 
39 typedef struct
40 {
41     fmpz num;
42     fmpz den;
43 }
44 fmpq;
45 
46 typedef fmpq fmpq_t[1];
47 
48 #define fmpq_numref(__x) (&(__x)->num)
49 #define fmpq_denref(__y) (&(__y)->den)
50 
fmpq_init(fmpq_t x)51 FMPQ_INLINE void fmpq_init(fmpq_t x)
52 {
53     x->num = WORD(0);
54     x->den = WORD(1);
55 }
56 
fmpq_clear(fmpq_t x)57 FMPQ_INLINE void fmpq_clear(fmpq_t x)
58 {
59     fmpz_clear(fmpq_numref(x));
60     fmpz_clear(fmpq_denref(x));
61 }
62 
fmpq_zero(fmpq_t res)63 FMPQ_INLINE void fmpq_zero(fmpq_t res)
64 {
65     fmpz_zero(fmpq_numref(res));
66     fmpz_one(fmpq_denref(res));
67 }
68 
fmpq_one(fmpq_t res)69 FMPQ_INLINE void fmpq_one(fmpq_t res)
70 {
71     fmpz_one(fmpq_numref(res));
72     fmpz_one(fmpq_denref(res));
73 }
74 
fmpq_equal(const fmpq_t x,const fmpq_t y)75 FMPQ_INLINE int fmpq_equal(const fmpq_t x, const fmpq_t y)
76 {
77     return fmpz_equal(fmpq_numref(x), fmpq_numref(y)) &&
78            fmpz_equal(fmpq_denref(x), fmpq_denref(y));
79 }
80 
fmpq_sgn(const fmpq_t x)81 FMPQ_INLINE int fmpq_sgn(const fmpq_t x)
82 {
83     return fmpz_sgn(fmpq_numref(x));
84 }
85 
fmpq_is_zero(const fmpq_t x)86 FMPQ_INLINE int fmpq_is_zero(const fmpq_t x)
87 {
88     return fmpz_is_zero(fmpq_numref(x));
89 }
90 
fmpq_is_one(const fmpq_t x)91 FMPQ_INLINE int fmpq_is_one(const fmpq_t x)
92 {
93     return fmpz_is_one(fmpq_numref(x)) && fmpz_is_one(fmpq_denref(x));
94 }
95 
fmpq_is_pm1(const fmpq_t x)96 FMPQ_INLINE int fmpq_is_pm1(const fmpq_t x)
97 {
98     return fmpz_is_pm1(fmpq_numref(x)) && fmpz_is_one(fmpq_denref(x));
99 }
100 
fmpq_set(fmpq_t dest,const fmpq_t src)101 FMPQ_INLINE void fmpq_set(fmpq_t dest, const fmpq_t src)
102 {
103     fmpz_set(fmpq_numref(dest), fmpq_numref(src));
104     fmpz_set(fmpq_denref(dest), fmpq_denref(src));
105 }
106 
fmpq_swap(fmpq_t op1,fmpq_t op2)107 FMPQ_INLINE void fmpq_swap(fmpq_t op1, fmpq_t op2)
108 {
109     fmpz_swap(fmpq_numref(op1), fmpq_numref(op2));
110     fmpz_swap(fmpq_denref(op1), fmpq_denref(op2));
111 }
112 
fmpq_neg(fmpq_t dest,const fmpq_t src)113 FMPQ_INLINE void fmpq_neg(fmpq_t dest, const fmpq_t src)
114 {
115     fmpz_neg(fmpq_numref(dest), fmpq_numref(src));
116     fmpz_set(fmpq_denref(dest), fmpq_denref(src));
117 }
118 
fmpq_abs(fmpq_t dest,const fmpq_t src)119 FMPQ_INLINE void fmpq_abs(fmpq_t dest, const fmpq_t src)
120 {
121     fmpz_abs(fmpq_numref(dest), fmpq_numref(src));
122     fmpz_set(fmpq_denref(dest), fmpq_denref(src));
123 }
124 
125 FLINT_DLL int _fmpq_cmp(const fmpz_t p, const fmpz_t q, const fmpz_t r, const fmpz_t s);
126 
127 FLINT_DLL int fmpq_cmp(const fmpq_t x, const fmpq_t y);
128 
129 FLINT_DLL int _fmpq_cmp_fmpz(const fmpz_t p, const fmpz_t q, const fmpz_t r);
130 
131 FLINT_DLL int fmpq_cmp_fmpz(const fmpq_t x, const fmpz_t y);
132 
133 FLINT_DLL int _fmpq_cmp_ui(const fmpz_t p, const fmpz_t q, ulong c);
134 
135 FLINT_DLL int fmpq_cmp_ui(const fmpq_t x, ulong c);
136 
137 FLINT_DLL int _fmpq_cmp_si(const fmpz_t p, const fmpz_t q, slong c);
138 
139 FLINT_DLL int fmpq_cmp_si(const fmpq_t x, slong c);
140 
141 FLINT_DLL void _fmpq_canonicalise(fmpz_t num, fmpz_t den);
142 
143 FLINT_DLL void fmpq_canonicalise(fmpq_t res);
144 
145 FLINT_DLL int _fmpq_is_canonical(const fmpz_t num, const fmpz_t den);
146 
147 FLINT_DLL int fmpq_is_canonical(const fmpq_t x);
148 
149 FLINT_DLL void _fmpq_set_ui(fmpz_t rnum, fmpz_t rden, ulong p, ulong q);
150 
151 FLINT_DLL void fmpq_set_ui(fmpq_t res, ulong p, ulong q);
152 
153 FLINT_DLL void _fmpq_set_si(fmpz_t rnum, fmpz_t rden, slong p, ulong q);
154 
155 FLINT_DLL void fmpq_set_si(fmpq_t res, slong p, ulong q);
156 
fmpq_equal_ui(fmpq_t q,slong n)157 FMPQ_INLINE int fmpq_equal_ui(fmpq_t q, slong n)
158 {
159     return fmpz_equal_ui(fmpq_numref(q), n) && q->den == WORD(1);
160 }
161 
fmpq_equal_si(fmpq_t q,slong n)162 FMPQ_INLINE int fmpq_equal_si(fmpq_t q, slong n)
163 {
164     return fmpz_equal_si(fmpq_numref(q), n) && q->den == WORD(1);
165 }
166 
167 FLINT_DLL void fmpq_set_fmpz_frac(fmpq_t res, const fmpz_t p, const fmpz_t q);
168 
169 FLINT_DLL int fmpq_set_str(fmpq_t res, const char * str, int base);
170 
fmpq_set_mpq(fmpq_t dest,const mpq_t src)171 FMPQ_INLINE void fmpq_set_mpq(fmpq_t dest, const mpq_t src)
172 {
173     fmpz_set_mpz(fmpq_numref(dest), mpq_numref(src));
174     fmpz_set_mpz(fmpq_denref(dest), mpq_denref(src));
175 }
176 
fmpq_get_mpq(mpq_t dest,const fmpq_t src)177 FMPQ_INLINE void fmpq_get_mpq(mpq_t dest, const fmpq_t src)
178 {
179     fmpz_get_mpz(mpq_numref(dest), fmpq_numref(src));
180     fmpz_get_mpz(mpq_denref(dest), fmpq_denref(src));
181 }
182 
183 FLINT_DLL double fmpq_get_d(const fmpq_t a);
184 
185 FLINT_DLL int fmpq_get_mpfr(mpfr_t r, const fmpq_t x, mpfr_rnd_t rnd);
186 
187 FLINT_DLL void fmpq_get_mpz_frac(mpz_t a, mpz_t b, fmpq_t c);
188 
189 FLINT_DLL void flint_mpq_init_set_readonly(mpq_t z, const fmpq_t f);
190 
191 FLINT_DLL void flint_mpq_clear_readonly(mpq_t z);
192 
193 FLINT_DLL void fmpq_init_set_readonly(fmpq_t f, const mpq_t z);
194 
195 FLINT_DLL void fmpq_clear_readonly(fmpq_t f);
196 
197 FLINT_DLL void fmpq_init_set_mpz_frac_readonly(fmpq_t z, const mpz_t num, const mpz_t den);
198 
199 FLINT_DLL char * _fmpq_get_str(char * str, int b, const fmpz_t num, const fmpz_t den);
200 
201 FLINT_DLL char * fmpq_get_str(char * str, int b, const fmpq_t x);
202 
203 FLINT_DLL int _fmpq_fprint(FILE * file, const fmpz_t num, const fmpz_t den);
204 
205 FLINT_DLL int fmpq_fprint(FILE * file, const fmpq_t x);
206 
_fmpq_print(const fmpz_t num,const fmpz_t den)207 FMPQ_INLINE int _fmpq_print(const fmpz_t num, const fmpz_t den)
208 {
209     return _fmpq_fprint(stdout, num, den);
210 }
211 
fmpq_print(const fmpq_t x)212 FMPQ_INLINE int fmpq_print(const fmpq_t x)
213 {
214     return fmpq_fprint(stdout, x);
215 }
216 
217 FLINT_DLL void _fmpq_randtest(fmpz_t num, fmpz_t den, flint_rand_t state, flint_bitcnt_t bits);
218 
219 FLINT_DLL void fmpq_randtest(fmpq_t res, flint_rand_t state, flint_bitcnt_t bits);
220 
221 FLINT_DLL void fmpq_randtest_not_zero(fmpq_t res, flint_rand_t state, flint_bitcnt_t bits);
222 
223 FLINT_DLL void _fmpq_randbits(fmpz_t num, fmpz_t den, flint_rand_t state, flint_bitcnt_t bits);
224 
225 FLINT_DLL void fmpq_randbits(fmpq_t res, flint_rand_t state, flint_bitcnt_t bits);
226 
227 FLINT_DLL void _fmpq_add_small(fmpz_t rnum, fmpz_t rden, slong p1, ulong q1, slong p2, ulong q2);
228 
229 FLINT_DLL void _fmpq_mul_small(fmpz_t rnum, fmpz_t rden, slong p1, ulong q1, slong p2, ulong q2);
230 
231 FLINT_DLL void _fmpq_add(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num,
232     const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den);
233 
234 FLINT_DLL void fmpq_add(fmpq_t res, const fmpq_t op1, const fmpq_t op2);
235 
236 FLINT_DLL void _fmpq_add_si(fmpz_t rnum, fmpz_t rden, const fmpz_t p,
237                                                       const fmpz_t q, slong r);
238 
239 FLINT_DLL void fmpq_add_si(fmpq_t res, const fmpq_t op1, slong c);
240 
241 FLINT_DLL void _fmpq_add_ui(fmpz_t rnum, fmpz_t rden, const fmpz_t p,
242 		                                      const fmpz_t q, ulong r);
243 
244 FLINT_DLL void fmpq_add_ui(fmpq_t res, const fmpq_t op1, ulong c);
245 
246 FLINT_DLL void _fmpq_add_fmpz(fmpz_t rnum, fmpz_t rden, const fmpz_t p,
247                                                const fmpz_t q, const fmpz_t r);
248 
249 FLINT_DLL void fmpq_add_fmpz(fmpq_t res, const fmpq_t op1, const fmpz_t c);
250 
251 FLINT_DLL void _fmpq_sub(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num,
252     const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den);
253 
254 FLINT_DLL void fmpq_sub(fmpq_t res, const fmpq_t op1, const fmpq_t op2);
255 
256 FLINT_DLL void _fmpq_sub_si(fmpz_t rnum, fmpz_t rden, const fmpz_t p,
257                                                       const fmpz_t q, slong r);
258 
259 FLINT_DLL void fmpq_sub_si(fmpq_t res, const fmpq_t op1, slong c);
260 
261 FLINT_DLL void _fmpq_sub_ui(fmpz_t rnum, fmpz_t rden, const fmpz_t p,
262 		                                      const fmpz_t q, ulong r);
263 
264 FLINT_DLL void fmpq_sub_ui(fmpq_t res, const fmpq_t op1, ulong c);
265 
266 FLINT_DLL void _fmpq_sub_fmpz(fmpz_t rnum, fmpz_t rden, const fmpz_t p,
267                                                const fmpz_t q, const fmpz_t r);
268 
269 FLINT_DLL void fmpq_sub_fmpz(fmpq_t res, const fmpq_t op1, const fmpz_t c);
270 
271 FLINT_DLL void _fmpq_mul_si(fmpz_t rnum, fmpz_t rden, const fmpz_t p,
272                                                       const fmpz_t q, slong r);
273 
274 FLINT_DLL void fmpq_mul_si(fmpq_t res, const fmpq_t op1, slong c);
275 
276 FLINT_DLL void _fmpq_mul_ui(fmpz_t rnum, fmpz_t rden, const fmpz_t p,
277                                                       const fmpz_t q, ulong r);
278 
279 FLINT_DLL void fmpq_mul_ui(fmpq_t res, const fmpq_t op1, ulong c);
280 
281 FLINT_DLL void _fmpq_mul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num,
282     const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den);
283 
284 FLINT_DLL void fmpq_mul(fmpq_t res, const fmpq_t op1, const fmpq_t op2);
285 
286 
287 FLINT_DLL void fmpq_mul_fmpz(fmpq_t res, const fmpq_t op, const fmpz_t x);
288 
289 FLINT_DLL void _fmpq_pow_si(fmpz_t rnum, fmpz_t rden,
290                   const fmpz_t opnum, const fmpz_t opden, slong e);
291 
292 FLINT_DLL void fmpq_pow_si(fmpq_t rop, const fmpq_t op, slong e);
293 
294 FLINT_DLL int fmpq_pow_fmpz(fmpq_t a, const fmpq_t b, const fmpz_t e);
295 
296 FLINT_DLL void _fmpq_addmul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num,
297     const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den);
298 
299 FLINT_DLL void fmpq_addmul(fmpq_t res, const fmpq_t op1, const fmpq_t op2);
300 
301 
302 FLINT_DLL void _fmpq_submul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num,
303     const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den);
304 
305 FLINT_DLL void fmpq_submul(fmpq_t res, const fmpq_t op1, const fmpq_t op2);
306 
307 
308 FLINT_DLL void fmpq_inv(fmpq_t dest, const fmpq_t src);
309 
310 FLINT_DLL void _fmpq_div(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num,
311                 const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den);
312 
313 FLINT_DLL void fmpq_div(fmpq_t res, const fmpq_t op1, const fmpq_t op2);
314 
315 FLINT_DLL void fmpq_div_fmpz(fmpq_t res, const fmpq_t op, const fmpz_t x);
316 
317 
318 FLINT_DLL void fmpq_mul_2exp(fmpq_t res, const fmpq_t x, flint_bitcnt_t exp);
319 
320 FLINT_DLL void fmpq_div_2exp(fmpq_t res, const fmpq_t x, flint_bitcnt_t exp);
321 
322 
323 FLINT_DLL int _fmpq_mod_fmpz(fmpz_t res, const fmpz_t num, const fmpz_t den, const fmpz_t mod);
324 
325 FLINT_DLL int fmpq_mod_fmpz(fmpz_t res, const fmpq_t x, const fmpz_t mod);
326 
327 FMPQ_INLINE void
_fmpq_gcd(fmpz_t rnum,fmpz_t rden,const fmpz_t p,const fmpz_t q,const fmpz_t r,const fmpz_t s)328 _fmpq_gcd(fmpz_t rnum, fmpz_t rden, const fmpz_t p, const fmpz_t q,
329             const fmpz_t r, const fmpz_t s)
330 {
331    fmpz_t a, b;
332    fmpz_init(a); fmpz_init(b);
333    fmpz_mul(a, p, s);
334    fmpz_mul(b, q, r);
335    fmpz_gcd(rnum, a, b);
336    fmpz_mul(rden, q, s);
337    _fmpq_canonicalise(rnum, rden);
338    fmpz_clear(a); fmpz_clear(b);
339 }
340 
341 FMPQ_INLINE void
fmpq_gcd(fmpq_t res,const fmpq_t op1,const fmpq_t op2)342 fmpq_gcd(fmpq_t res, const fmpq_t op1, const fmpq_t op2)
343 {
344     _fmpq_gcd(fmpq_numref(res), fmpq_denref(res), fmpq_numref(op1),
345               fmpq_denref(op1), fmpq_numref(op2), fmpq_denref(op2));
346 }
347 
348 FLINT_DLL int _fmpq_reconstruct_fmpz(fmpz_t num, fmpz_t den, const fmpz_t a, const fmpz_t m);
349 
350 FLINT_DLL int fmpq_reconstruct_fmpz(fmpq_t res, const fmpz_t a, const fmpz_t m);
351 
352 FLINT_DLL int _fmpq_reconstruct_fmpz_2_naive(fmpz_t n, fmpz_t d,
353                const fmpz_t a, const fmpz_t m, const fmpz_t N, const fmpz_t D);
354 
355 FLINT_DLL int _fmpq_reconstruct_fmpz_2(fmpz_t n, fmpz_t d,
356                const fmpz_t a, const fmpz_t m, const fmpz_t N, const fmpz_t D);
357 
358 FLINT_DLL int fmpq_reconstruct_fmpz_2(fmpq_t res,
359                const fmpz_t a, const fmpz_t m, const fmpz_t N, const fmpz_t D);
360 
361 FLINT_DLL flint_bitcnt_t fmpq_height_bits(const fmpq_t x);
362 
363 FLINT_DLL void fmpq_height(fmpz_t height, const fmpq_t x);
364 
365 FLINT_DLL void _fmpq_next_calkin_wilf(fmpz_t rnum, fmpz_t rden,
366     const fmpz_t num, const fmpz_t den);
367 
368 FLINT_DLL void fmpq_next_calkin_wilf(fmpq_t res, const fmpq_t x);
369 
370 FLINT_DLL void _fmpq_next_signed_calkin_wilf(fmpz_t rnum, fmpz_t rden,
371     const fmpz_t num, const fmpz_t den);
372 
373 FLINT_DLL void fmpq_next_signed_calkin_wilf(fmpq_t res, const fmpq_t x);
374 
375 FLINT_DLL void _fmpq_next_minimal(fmpz_t rnum, fmpz_t rden,
376     const fmpz_t num, const fmpz_t den);
377 
378 FLINT_DLL void fmpq_next_minimal(fmpq_t res, const fmpq_t x);
379 
380 FLINT_DLL void _fmpq_next_signed_minimal(fmpz_t rnum, fmpz_t rden,
381     const fmpz_t num, const fmpz_t den);
382 
383 FLINT_DLL void fmpq_next_signed_minimal(fmpq_t res, const fmpq_t x);
384 
385 FLINT_DLL void fmpq_farey_neighbors(fmpq_t left, fmpq_t right,
386                                              const fmpq_t mid, const fmpz_t Q);
387 
388 FLINT_DLL void fmpq_simplest_between(fmpq_t mid, const fmpq_t l, const fmpq_t r);
389 
390 FLINT_DLL void _fmpq_simplest_between(fmpz_t mid_num, fmpz_t mid_den,
391                                        const fmpz_t l_num, const fmpz_t l_den,
392                                        const fmpz_t r_num, const fmpz_t r_den);
393 
394 FLINT_DLL slong fmpq_get_cfrac_naive(fmpz * c, fmpq_t rem, const fmpq_t x, slong n);
395 
396 FLINT_DLL slong fmpq_get_cfrac(fmpz * c, fmpq_t rem, const fmpq_t x, slong n);
397 
398 FLINT_DLL void fmpq_set_cfrac(fmpq_t x, const fmpz * c, slong n);
399 
400 FLINT_DLL slong fmpq_cfrac_bound(const fmpq_t x);
401 
402 FLINT_DLL void fmpq_dedekind_sum_naive(fmpq_t s, const fmpz_t h, const fmpz_t k);
403 
404 FLINT_DLL void fmpq_dedekind_sum(fmpq_t s, const fmpz_t h, const fmpz_t k);
405 
406 FLINT_DLL void _fmpq_harmonic_ui(fmpz_t num, fmpz_t den, ulong n);
407 
408 FLINT_DLL void fmpq_harmonic_ui(fmpq_t x, ulong n);
409 
410 FLINT_DLL fmpq * _fmpq_vec_init(slong len);
411 
412 FMPQ_INLINE
_fmpq_vec_clear(fmpq * vec,slong len)413 void _fmpq_vec_clear(fmpq * vec, slong len)
414 {
415     _fmpz_vec_clear((fmpz *) vec, 2 * len);
416 }
417 
418 /*********************** 2x2 integer matrix **********************************/
419 
420 typedef struct {
421     fmpz_t _11, _12, _21, _22;
422     int det;    /* 0,1,or,-1: 0 -> don't know, 1 -> 1, -1 -> -1 */
423 } _fmpz_mat22_struct;
424 
425 typedef _fmpz_mat22_struct _fmpz_mat22_t[1];
426 
427 typedef struct {
428     mp_limb_t _11, _12, _21, _22;
429     int det;    /* ditto */
430 } _ui_mat22_struct;
431 
432 typedef _ui_mat22_struct _ui_mat22_t[1];
433 
434 FLINT_DLL void _fmpz_mat22_init(_fmpz_mat22_t M);
435 
436 FLINT_DLL void _fmpz_mat22_clear(_fmpz_mat22_t M);
437 
438 FLINT_DLL void _fmpz_mat22_one(_fmpz_mat22_t M);
439 
440 FLINT_DLL int _fmpz_mat22_is_one(_fmpz_mat22_t M);
441 
442 FLINT_DLL flint_bitcnt_t _fmpz_mat22_bits(const _fmpz_mat22_t N);
443 
444 FLINT_DLL void _fmpz_mat22_rmul(_fmpz_mat22_t M, const _fmpz_mat22_t N);
445 
446 FLINT_DLL void _fmpz_mat22_rmul_ui(_fmpz_mat22_t M, const _ui_mat22_t N);
447 
448 FLINT_DLL void _fmpz_mat22_rmul_inv_ui(_fmpz_mat22_t M, const _ui_mat22_t N);
449 
450 FLINT_DLL void _fmpz_mat22_rmul_elem(_fmpz_mat22_t M, const fmpz_t q);
451 
452 FLINT_DLL void _fmpz_mat22_rmul_inv_elem(_fmpz_mat22_t M, const fmpz_t q);
453 
454 FLINT_DLL void _fmpz_mat22_lmul_elem(_fmpz_mat22_t M, const fmpz_t q);
455 
456 /******** resizable integer vector specific to cfrac functionality ***********/
457 
458 typedef struct
459 {
460     fmpz * array;
461     slong length;
462     slong alloc;
463     slong limit;
464     fmpz_t alt_sum;
465     int want_alt_sum;
466 } _fmpq_cfrac_list_struct;
467 
468 typedef _fmpq_cfrac_list_struct _fmpq_cfrac_list_t[1];
469 
470 FLINT_DLL void _fmpq_cfrac_list_init(_fmpq_cfrac_list_t v);
471 
472 FLINT_DLL void _fmpq_cfrac_list_clear(_fmpq_cfrac_list_t v);
473 
474 FLINT_DLL void _fmpq_cfrac_list_fit_length(_fmpq_cfrac_list_t v, slong len);
475 
476 FLINT_DLL void _fmpq_cfrac_list_push_back(_fmpq_cfrac_list_t v, const fmpz_t a);
477 
478 FLINT_DLL void _fmpq_cfrac_list_push_back_zero(_fmpq_cfrac_list_t v);
479 
480 FLINT_DLL void _fmpq_cfrac_list_append_ui(_fmpq_cfrac_list_t v, const ulong * a, slong n);
481 
_fmpq_cfrac_list_swap(_fmpq_cfrac_list_t a,_fmpq_cfrac_list_t b)482 FMPQ_INLINE void _fmpq_cfrac_list_swap(_fmpq_cfrac_list_t a, _fmpq_cfrac_list_t b)
483 {
484     _fmpq_cfrac_list_struct t = *a;
485     *a = *b;
486     *b = t;
487 }
488 
489 /*************** ball for closed interval [left, right] **********************/
490 
491 typedef struct {
492     fmpz_t left_num, left_den, right_num, right_den;
493     int exact;
494 } _fmpq_ball_struct;
495 
496 typedef _fmpq_ball_struct _fmpq_ball_t[1];
497 
498 FLINT_DLL void _fmpq_ball_init(_fmpq_ball_t x);
499 
500 FLINT_DLL void _fmpq_ball_clear(_fmpq_ball_t x);
501 
_fmpq_ball_swap(_fmpq_ball_t x,_fmpq_ball_t y)502 FMPQ_INLINE void _fmpq_ball_swap(_fmpq_ball_t x, _fmpq_ball_t y)
503 {
504    _fmpq_ball_struct t = *x;
505    *x = *y;
506    *y = t;
507 }
508 
509 FLINT_DLL int _fmpq_ball_gt_one(const _fmpq_ball_t x);
510 
511 FLINT_DLL void _fmpq_hgcd(_fmpq_cfrac_list_t s, _fmpz_mat22_t M,
512                                                    fmpz_t x_num, fmpz_t x_den);
513 
514 FLINT_DLL void _fmpq_ball_get_cfrac(_fmpq_cfrac_list_t s, _fmpz_mat22_t M,
515                                                     int needM, _fmpq_ball_t x);
516 
517 /* Inlines *******************************************************************/
518 
519 FLINT_DLL void fmpq_numerator(fmpz_t n, const fmpq_t q);
520 FLINT_DLL void fmpq_denominator(fmpz_t n, const fmpq_t q);
521 FLINT_DLL fmpz * fmpq_numerator_ptr(fmpq_t q);
522 FLINT_DLL fmpz * fmpq_denominator_ptr(fmpq_t q);
523 FLINT_DLL int fmpq_equal_fmpz(fmpq_t q, fmpz_t n);
524 
525 #ifdef __cplusplus
526 }
527 #endif
528 
529 #endif
530