Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/libs/flint/fmpq_poly.h
4072 views
1
///////////////////////////////////////////////////////////////////////////////
2
// Copyright (C) 2010 Sebastian Pancratz //
3
// //
4
// Distributed under the terms of the GNU General Public License as //
5
// published by the Free Software Foundation; either version 2 of the //
6
// License, or (at your option) any later version. //
7
// //
8
// http://www.gnu.org/licenses/ //
9
///////////////////////////////////////////////////////////////////////////////
10
11
#ifndef _FMPQ_POLY_H_
12
#define _FMPQ_POLY_H_
13
14
#ifdef __cplusplus
15
extern "C" {
16
#endif
17
18
#include <stdio.h>
19
#include <gmp.h>
20
21
#include "fmpz.h"
22
#include "fmpz_poly.h"
23
24
/**
25
* \file fmpq_poly.h
26
* \brief Fast implementation of the rational polynomial ring
27
* \author Sebastian Pancratz
28
* \date Mar 2010 -- July 2010
29
* \version 0.1.8
30
*/
31
32
/**
33
* \ingroup Definitions
34
* \brief Data type for a rational polynomial.
35
* \details We represent a rational polynomial as the quotient of an integer
36
* polynomial of type <tt>fmpz_poly_t</tt> and a denominator of type
37
* <tt>fmpz_t</tt>, enforcing coprimality and that the denominator
38
* is positive. The zero polynomial is represented as \f$0/1\f$.
39
*/
40
typedef struct
41
{
42
fmpz_poly_t num; //!< Numerator
43
fmpz_t den; //!< Denominator
44
} fmpq_poly_struct;
45
46
/**
47
* \ingroup Definitions
48
* \brief Array of #fmpq_poly_struct of length one.
49
* \details This allows passing <em>by reference</em> without having to
50
* explicitly allocate memory for the structure, as one would have
51
* to when using pointers.
52
*/
53
typedef fmpq_poly_struct fmpq_poly_t[1];
54
55
/**
56
* \ingroup Definitions
57
* \brief Pointer to #fmpq_poly_struct.
58
*/
59
typedef fmpq_poly_struct * fmpq_poly_ptr;
60
61
void fmpq_poly_canonicalize(fmpq_poly_ptr f, fmpz_t temp);
62
63
///////////////////////////////////////////////////////////////////////////////
64
// fmpq_poly_* //
65
///////////////////////////////////////////////////////////////////////////////
66
67
///////////////////////////////////////////////////////////////////////////////
68
// Accessing numerator and denominator
69
70
/**
71
* \def fmpq_poly_numref(op)
72
* \brief Returns a reference to the numerator of \c op.
73
* \ingroup NumDen
74
* \details The <tt>fmpz_poly</tt> functions can be used on the result of
75
* this macro.
76
*/
77
#define fmpq_poly_numref(op) ((op)->num)
78
79
/**
80
* \def fmpq_poly_denref(op)
81
* \brief Returns a reference to the denominator of \c op.
82
* \ingroup NumDen
83
* \details The <tt>fmpz</tt> functions can be used on the result of
84
* this macro.
85
*/
86
#define fmpq_poly_denref(op) ((op)->den)
87
88
///////////////////////////////////////////////////////////////////////////////
89
// Memory management
90
91
/**
92
* \ingroup MemoryManagement
93
*
94
* Initializes the element \c rop to zero.
95
*
96
* This function should be called once for the #fmpq_poly_ptr \c rop, before
97
* using it with other <tt>fmpq_poly</tt> functions, or following a
98
* preceeding call to #fmpq_poly_clear().
99
*/
100
static inline
101
void fmpq_poly_init(fmpq_poly_ptr rop)
102
{
103
fmpz_poly_init(rop->num);
104
rop->den = fmpz_init(1ul);
105
fmpz_set_ui(rop->den, 1ul);
106
}
107
108
/**
109
* \ingroup MemoryManagement
110
*
111
* Clears the element \c rop.
112
*
113
* This function should only be called on an element which has been
114
* initialised.
115
*/
116
static inline
117
void fmpq_poly_clear(fmpq_poly_ptr rop)
118
{
119
fmpz_poly_clear(rop->num);
120
fmpz_clear(rop->den);
121
}
122
123
///////////////////////////////////////////////////////////////////////////////
124
// Assignment and basic manipulation
125
126
/**
127
* \ingroup Assignment
128
*
129
* Sets the element \c rop to the same value as the element \c op.
130
*/
131
static inline
132
void fmpq_poly_set(fmpq_poly_ptr rop, const fmpq_poly_ptr op)
133
{
134
if (rop != op)
135
{
136
fmpz_poly_set(rop->num, op->num);
137
138
rop->den = fmpz_realloc(rop->den, fmpz_size(op->den));
139
fmpz_set(rop->den, op->den);
140
}
141
}
142
143
/**
144
* \ingroup Assignment
145
*
146
* Sets the element \c rop to the same value as the element \c op.
147
*/
148
static inline
149
void fmpq_poly_set_fmpz_poly(fmpq_poly_ptr rop, const fmpz_poly_t op)
150
{
151
fmpz_poly_set(rop->num, op);
152
fmpz_set_ui(rop->den, 1);
153
}
154
155
/**
156
* \ingroup Assignment
157
*
158
* Sets the element \c rop to the value given by the \c int \c op.
159
*/
160
static inline
161
void fmpq_poly_set_si(fmpq_poly_ptr rop, long op)
162
{
163
fmpz_poly_zero(rop->num);
164
fmpz_poly_set_coeff_si(rop->num, 0, op);
165
fmpz_set_ui(rop->den, 1ul);
166
}
167
168
/**
169
* \ingroup Assignment
170
*
171
* Sets the element \c rop to the integer \c x.
172
*/
173
static inline
174
void fmpq_poly_set_fmpz(fmpq_poly_ptr rop, const fmpz_t x)
175
{
176
fmpz_poly_zero(rop->num);
177
fmpz_poly_set_coeff_fmpz(rop->num, 0, x);
178
fmpz_set_ui(rop->den, 1ul);
179
}
180
181
/**
182
* \ingroup Assignment
183
*
184
* Sets the element \c rop to the integer \c x.
185
*/
186
static inline
187
void fmpq_poly_set_mpz(fmpq_poly_ptr rop, const mpz_t x)
188
{
189
fmpz_poly_zero(rop->num);
190
fmpz_poly_set_coeff_mpz(rop->num, 0, x);
191
fmpz_set_ui(rop->den, 1ul);
192
}
193
194
/**
195
* \ingroup Assignment
196
*
197
* Sets the element \c rop to the rational \c x, assumed to be given
198
* in lowest terms.
199
*/
200
static inline
201
void fmpq_poly_set_mpq(fmpq_poly_ptr rop, const mpq_t x)
202
{
203
fmpz_poly_zero(rop->num);
204
fmpz_poly_set_coeff_mpz(rop->num, 0, mpq_numref(x));
205
rop->den = fmpz_realloc(rop->den, mpz_size(mpq_denref(x)));
206
mpz_to_fmpz(rop->den, mpq_denref(x));
207
}
208
209
/**
210
* \ingroup Assignment
211
*
212
* Swaps the elements \c op1 and \c op2.
213
*
214
* This is done efficiently by swapping pointers.
215
*/
216
static inline
217
void fmpq_poly_swap(fmpq_poly_ptr op1, fmpq_poly_ptr op2)
218
{
219
if (op1 != op2)
220
{
221
fmpz_t t;
222
fmpz_poly_swap(op1->num, op2->num);
223
t = op1->den;
224
op1->den = op2->den;
225
op2->den = t;
226
}
227
}
228
229
/**
230
* \ingroup Assignment
231
*
232
* Sets the element \c rop to zero.
233
*/
234
static inline
235
void fmpq_poly_zero(fmpq_poly_ptr rop)
236
{
237
fmpz_poly_zero(rop->num);
238
fmpz_set_ui(rop->den, 1ul);
239
}
240
241
/**
242
* \ingroup Assignment
243
*
244
* Sets the element \c rop to one.
245
*/
246
static inline
247
void fmpq_poly_one(fmpq_poly_ptr rop)
248
{
249
fmpz_poly_zero(rop->num);
250
fmpz_poly_set_coeff_si(rop->num, 0, 1);
251
fmpz_set_ui(rop->den, 1ul);
252
}
253
254
void fmpq_poly_neg(fmpq_poly_ptr rop, const fmpq_poly_ptr op);
255
void fmpq_poly_inv(fmpq_poly_ptr rop, const fmpq_poly_ptr op);
256
257
///////////////////////////////////////////////////////////////////////////////
258
// Setting/ retrieving individual coefficients
259
260
void fmpq_poly_get_coeff_mpq(mpq_t rop, const fmpq_poly_ptr op, ulong i);
261
262
void fmpq_poly_set_coeff_fmpz(fmpq_poly_ptr rop, ulong i, const fmpz_t x);
263
void fmpq_poly_set_coeff_mpz(fmpq_poly_ptr rop, ulong i, const mpz_t x);
264
void fmpq_poly_set_coeff_mpq(fmpq_poly_ptr rop, ulong i, const mpq_t x);
265
void fmpq_poly_set_coeff_si(fmpq_poly_ptr rop, ulong i, long x);
266
267
///////////////////////////////////////////////////////////////////////////////
268
// Comparison
269
270
/**
271
* \brief Returns whether \c op is zero.
272
* \ingroup Comparison
273
*
274
* Returns whether the element \c op is zero.
275
*/
276
static inline
277
int fmpq_poly_is_zero(const fmpq_poly_ptr op)
278
{
279
return op->num->length == 0ul;
280
}
281
282
/**
283
* \brief Returns whether \c op is equal to \f$1\f$.
284
* \ingroup Comparison
285
*
286
* Returns whether the element \c op is equal to the constant polynomial
287
* \f$1\f$.
288
*/
289
static inline
290
int fmpq_poly_is_one(const fmpq_poly_ptr op)
291
{
292
return (op->num->length == 1ul) && fmpz_is_one(op->num->coeffs)
293
&& fmpz_is_one(op->den);
294
}
295
296
int fmpq_poly_equal(const fmpq_poly_ptr op1, const fmpq_poly_ptr op2);
297
int fmpq_poly_cmp(const fmpq_poly_ptr left, const fmpq_poly_ptr right);
298
299
///////////////////////////////////////////////////////////////////////////////
300
// Polynomial parameters
301
302
/**
303
* \brief Returns the length of \c op.
304
* \ingroup PolyParameters
305
* \details Returns the length of the polynomial \c op, which is one greater
306
* than its degree.
307
*/
308
static inline
309
ulong fmpq_poly_length(const fmpq_poly_ptr op)
310
{
311
return op->num->length;
312
}
313
314
/**
315
* \brief Returns the degree of \c op.
316
* \ingroup Parameters
317
* \details Returns the degree of the polynomial \c op.
318
*/
319
static inline
320
long fmpq_poly_degree(const fmpq_poly_ptr op)
321
{
322
return (long) (op->num->length - 1ul);
323
}
324
325
///////////////////////////////////////////////////////////////////////////////
326
// Addition/ subtraction
327
328
void fmpq_poly_add(fmpq_poly_ptr rop, const fmpq_poly_ptr op1, const fmpq_poly_ptr op2);
329
void fmpq_poly_sub(fmpq_poly_ptr rop, const fmpq_poly_ptr op1, const fmpq_poly_ptr op2);
330
331
void fmpq_poly_addmul(fmpq_poly_ptr rop, const fmpq_poly_ptr op1, const fmpq_poly_ptr op2);
332
void fmpq_poly_submul(fmpq_poly_ptr rop, const fmpq_poly_ptr op1, const fmpq_poly_ptr op2);
333
334
///////////////////////////////////////////////////////////////////////////////
335
// Scalar multiplication and division
336
337
void fmpq_poly_scalar_mul_si(fmpq_poly_ptr rop, const fmpq_poly_ptr op, long x);
338
void fmpq_poly_scalar_mul_mpz(fmpq_poly_ptr rop, const fmpq_poly_ptr op, const mpz_t x);
339
void fmpq_poly_scalar_mul_mpq(fmpq_poly_ptr rop, const fmpq_poly_ptr op, const mpq_t x);
340
341
void fmpq_poly_scalar_div_si(fmpq_poly_ptr rop, const fmpq_poly_ptr op, long x);
342
void fmpq_poly_scalar_div_mpz(fmpq_poly_ptr rop, const fmpq_poly_ptr op, const mpz_t x);
343
void fmpq_poly_scalar_div_mpq(fmpq_poly_ptr rop, const fmpq_poly_ptr op, const mpq_t x);
344
345
///////////////////////////////////////////////////////////////////////////////
346
// Multiplication
347
348
void fmpq_poly_mul(fmpq_poly_ptr rop, const fmpq_poly_ptr op1, const fmpq_poly_ptr op2);
349
350
///////////////////////////////////////////////////////////////////////////////
351
// Division
352
353
void fmpq_poly_floordiv(fmpq_poly_ptr q, const fmpq_poly_ptr a, const fmpq_poly_ptr b);
354
void fmpq_poly_mod(fmpq_poly_ptr r, const fmpq_poly_ptr a, const fmpq_poly_ptr b);
355
void fmpq_poly_divrem(fmpq_poly_ptr q, fmpq_poly_ptr r, const fmpq_poly_ptr a, const fmpq_poly_ptr b);
356
357
///////////////////////////////////////////////////////////////////////////////
358
// Powering
359
360
void fmpq_poly_power(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong exp);
361
362
///////////////////////////////////////////////////////////////////////////////
363
// Greatest common divisor
364
365
void fmpq_poly_gcd(fmpq_poly_ptr rop, const fmpq_poly_ptr a, const fmpq_poly_ptr b);
366
void fmpq_poly_xgcd(fmpq_poly_ptr rop, fmpq_poly_ptr s, fmpq_poly_ptr t, const fmpq_poly_ptr a, const fmpq_poly_ptr b);
367
void fmpq_poly_lcm(fmpq_poly_ptr rop, const fmpq_poly_ptr a, const fmpq_poly_ptr b);
368
369
///////////////////////////////////////////////////////////////////////////////
370
// Derivative
371
372
void fmpq_poly_derivative(fmpq_poly_ptr rop, fmpq_poly_ptr op);
373
374
///////////////////////////////////////////////////////////////////////////////
375
// Evaluation
376
377
void fmpq_poly_evaluate_mpz(mpq_t rop, fmpq_poly_ptr f, const mpz_t a);
378
void fmpq_poly_evaluate_mpq(mpq_t rop, fmpq_poly_ptr f, const mpq_t a);
379
380
///////////////////////////////////////////////////////////////////////////////
381
// Gaussian content
382
383
void fmpq_poly_content(mpq_t rop, const fmpq_poly_ptr op);
384
void fmpq_poly_primitive_part(fmpq_poly_ptr rop, const fmpq_poly_ptr op);
385
int fmpq_poly_is_monic(const fmpq_poly_ptr op);
386
void fmpq_poly_monic(fmpq_poly_ptr rop, const fmpq_poly_ptr op);
387
388
///////////////////////////////////////////////////////////////////////////////
389
// Resultant
390
391
void fmpq_poly_resultant(mpq_t rop, const fmpq_poly_ptr a, const fmpq_poly_ptr b);
392
void fmpq_poly_discriminant(mpq_t disc, fmpq_poly_t a);
393
394
///////////////////////////////////////////////////////////////////////////////
395
// Composition
396
397
void fmpq_poly_compose(fmpq_poly_ptr rop, const fmpq_poly_ptr a, const fmpq_poly_ptr b);
398
void fmpq_poly_rescale(fmpq_poly_ptr rop, const fmpq_poly_ptr op, const mpq_t x);
399
400
///////////////////////////////////////////////////////////////////////////////
401
// Square-free
402
403
int fmpq_poly_is_squarefree(const fmpq_poly_ptr op);
404
405
///////////////////////////////////////////////////////////////////////////////
406
// Subpolynomials
407
408
void fmpq_poly_getslice(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong i, ulong j);
409
void fmpq_poly_left_shift(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong n);
410
void fmpq_poly_right_shift(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong n);
411
void fmpq_poly_truncate(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong n);
412
void fmpq_poly_reverse(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong n);
413
414
///////////////////////////////////////////////////////////////////////////////
415
// String conversion
416
417
void _fmpq_poly_from_list(fmpq_poly_ptr rop, mpq_t * a, ulong n);
418
int fmpq_poly_from_string(fmpq_poly_ptr rop, const char * s);
419
char * fmpq_poly_to_string(const fmpq_poly_ptr op);
420
char * fmpq_poly_to_string_pretty(const fmpq_poly_ptr op, const char * x);
421
422
#ifdef __cplusplus
423
}
424
#endif
425
426
#endif
427
428
429