Ticket #12173: flint-2.3-sage-5.1.beta0.patch
File flint-2.3-sage-5.1.beta0.patch, 248.6 KB (added by , 10 years ago) |
---|
-
module_list.py
# HG changeset patch # User Jean-Pierre Flori <jean-pierre.flor@ssi.gouv.fr> # Date 1338366709 -7200 # Node ID 4f6a3b00730d86706f1f3fd75cab27d751eab8d6 # Parent 369df2b2966bb9053dddcf461c269f8da6b711b1 [mq]: flint-2.3-sage-5.0.diff diff --git a/module_list.py b/module_list.py
a b 1634 1634 include_dirs = ['sage/libs/ntl/']), 1635 1635 1636 1636 Extension('sage.rings.polynomial.polynomial_rational_flint', 1637 sources = ['sage/rings/polynomial/polynomial_rational_flint.pyx' , 'sage/libs/flint/fmpq_poly.c'],1637 sources = ['sage/rings/polynomial/polynomial_rational_flint.pyx'], 1638 1638 language = 'c++', 1639 1639 extra_compile_args=["-std=c99"] + uname_specific('SunOS', [], ['-D_XPG6']), 1640 1640 libraries = ["csage", "flint", "ntl", "gmpxx", "gmp"], -
sage/algebras/quatalg/quaternion_algebra_element.pyx
diff --git a/sage/algebras/quatalg/quaternion_algebra_element.pyx b/sage/algebras/quatalg/quaternion_algebra_element.pyx
a b 1613 1613 x, y, z, w = to_quaternion(parent._base, v) 1614 1614 cdef NumberFieldElement a = <NumberFieldElement>(parent._base(parent._a)) 1615 1615 cdef NumberFieldElement b = <NumberFieldElement>(parent._base(parent._b)) 1616 ZZX_to_fmpz_poly(self.x, (<NumberFieldElement>x).__numerator)1617 ZZX_to_fmpz_poly(self.y, (<NumberFieldElement>y).__numerator)1618 ZZX_to_fmpz_poly(self.z, (<NumberFieldElement>z).__numerator)1619 ZZX_to_fmpz_poly(self.w, (<NumberFieldElement>w).__numerator)1616 fmpz_poly_set_ZZX(self.x, (<NumberFieldElement>x).__numerator) 1617 fmpz_poly_set_ZZX(self.y, (<NumberFieldElement>y).__numerator) 1618 fmpz_poly_set_ZZX(self.z, (<NumberFieldElement>z).__numerator) 1619 fmpz_poly_set_ZZX(self.w, (<NumberFieldElement>w).__numerator) 1620 1620 1621 1621 ZZ_to_mpz(&T1, &(<NumberFieldElement>x).__denominator) 1622 1622 ZZ_to_mpz(&T2, &(<NumberFieldElement>y).__denominator) … … 1637 1637 fmpz_poly_scalar_mul_mpz(self.z, self.z, t3) 1638 1638 fmpz_poly_scalar_mul_mpz(self.w, self.w, t4) 1639 1639 1640 ZZX_to_fmpz_poly(self.a, a.__numerator) # we will assume that the denominator of a and b are 11641 ZZX_to_fmpz_poly(self.b, b.__numerator)1640 fmpz_poly_set_ZZX(self.a, a.__numerator) # we will assume that the denominator of a and b are 1 1641 fmpz_poly_set_ZZX(self.b, b.__numerator) 1642 1642 1643 ZZX_to_fmpz_poly(self.modulus, (<NumberFieldElement>x).__fld_numerator.x) # and same for the modulus1643 fmpz_poly_set_ZZX(self.modulus, (<NumberFieldElement>x).__fld_numerator.x) # and same for the modulus 1644 1644 1645 1645 def __getitem__(self, int i): 1646 1646 """ … … 1669 1669 cdef NumberFieldElement item = el._new() 1670 1670 1671 1671 if i == 0: 1672 fmpz_poly_ to_ZZX(item.__numerator, self.x)1672 fmpz_poly_get_ZZX(item.__numerator, self.x) 1673 1673 elif i == 1: 1674 fmpz_poly_ to_ZZX(item.__numerator, self.y)1674 fmpz_poly_get_ZZX(item.__numerator, self.y) 1675 1675 elif i == 2: 1676 fmpz_poly_ to_ZZX(item.__numerator, self.z)1676 fmpz_poly_get_ZZX(item.__numerator, self.z) 1677 1677 elif i == 3: 1678 fmpz_poly_ to_ZZX(item.__numerator, self.w)1678 fmpz_poly_get_ZZX(item.__numerator, self.w) 1679 1679 else: 1680 1680 raise IndexError, "quaternion element index out of range" 1681 1681 … … 1988 1988 # Implementation-wise, we compute the GCD's one at a time, 1989 1989 # and quit if it ever becomes one 1990 1990 1991 cdef fmpz_t content = fmpz_init(fmpz_poly_max_limbs(self.x)) # TODO: think about how big this should be (probably the size of d) 1992 # Note that we have to allocate this here, and not 1993 # as a global variable, because fmpz_t's do not 1994 # self allocate memory 1991 cdef fmpz_t content 1992 fmpz_init(content) 1995 1993 fmpz_poly_content(content, self.x) 1996 fmpz_ to_mpz(U1, content)1994 fmpz_get_mpz(U1, content) 1997 1995 mpz_gcd(U1, self.d, U1) 1998 1996 if mpz_cmp_ui(U1, 1) != 0: 1999 1997 fmpz_poly_content(content, self.y) 2000 fmpz_ to_mpz(U2, content)1998 fmpz_get_mpz(U2, content) 2001 1999 mpz_gcd(U1, U1, U2) 2002 2000 if mpz_cmp_ui(U1, 1) != 0: 2003 2001 fmpz_poly_content(content, self.z) 2004 fmpz_ to_mpz(U2, content)2002 fmpz_get_mpz(U2, content) 2005 2003 mpz_gcd(U1, U1, U2) 2006 2004 if mpz_cmp_ui(U1, 1) != 0: 2007 2005 fmpz_poly_content(content, self.w) 2008 fmpz_ to_mpz(U2, content)2006 fmpz_get_mpz(U2, content) 2009 2007 mpz_gcd(U1, U1, U2) 2010 2008 if mpz_cmp_ui(U1, 1) != 0: 2011 fmpz_poly_scalar_div _mpz(self.x, self.x, U1)2012 fmpz_poly_scalar_div _mpz(self.y, self.y, U1)2013 fmpz_poly_scalar_div _mpz(self.z, self.z, U1)2014 fmpz_poly_scalar_div _mpz(self.w, self.w, U1)2009 fmpz_poly_scalar_divexact_mpz(self.x, self.x, U1) 2010 fmpz_poly_scalar_divexact_mpz(self.y, self.y, U1) 2011 fmpz_poly_scalar_divexact_mpz(self.z, self.z, U1) 2012 fmpz_poly_scalar_divexact_mpz(self.w, self.w, U1) 2015 2013 mpz_divexact(self.d, self.d, U1) 2016 2014 2017 2015 fmpz_clear(content) -
sage/graphs/matchpoly.pyx
diff --git a/sage/graphs/matchpoly.pyx b/sage/graphs/matchpoly.pyx
a b 350 350 """ 351 351 cdef int i, j, k, edge1, edge2, new_edge1, new_edge2, new_nedges 352 352 cdef int *edges1, *edges2, *new_edges1, *new_edges2 353 cdef fmpz _tcoeff353 cdef fmpz * coeff 354 354 355 355 if nverts == 3: 356 356 coeff = fmpz_poly_get_coeff_ptr(pol, 3) 357 357 if coeff is NULL: 358 358 fmpz_poly_set_coeff_ui(pol, 3, 1) 359 359 else: 360 fmpz_add_ui _inplace(coeff, 1)360 fmpz_add_ui(coeff, coeff, 1) 361 361 coeff = fmpz_poly_get_coeff_ptr(pol, 1) 362 362 if coeff is NULL: 363 363 fmpz_poly_set_coeff_ui(pol, 1, nedges) 364 364 else: 365 fmpz_add_ui _inplace(coeff, nedges)365 fmpz_add_ui(coeff, coeff, nedges) 366 366 return 367 367 368 368 if nedges == 0: … … 370 370 if coeff is NULL: 371 371 fmpz_poly_set_coeff_ui(pol, nverts, 1) 372 372 else: 373 fmpz_add_ui _inplace(coeff, 1)373 fmpz_add_ui(coeff, coeff, 1) 374 374 return 375 375 376 376 edges1 = edges[2*depth] -
sage/groups/perm_gps/partn_ref/data_structures_pxd.pxi
diff --git a/sage/groups/perm_gps/partn_ref/data_structures_pxd.pxi b/sage/groups/perm_gps/partn_ref/data_structures_pxd.pxi
a b 13 13 cdef extern from "stdlib.h": 14 14 int rand() 15 15 16 cdef extern from "FLINT/ long_extras.h":17 int z_isprime(unsigned long n)16 cdef extern from "FLINT/ulong_extras.h": 17 int n_is_prime(unsigned long n) 18 18 19 19 cdef struct OrbitPartition: 20 20 # Disjoint set data structure for representing the orbits of the generators -
sage/groups/perm_gps/partn_ref/data_structures_pyx.pxi
diff --git a/sage/groups/perm_gps/partn_ref/data_structures_pyx.pxi b/sage/groups/perm_gps/partn_ref/data_structures_pyx.pxi
a b 1432 1432 if OP.parent[i] == i: 1433 1433 q = OP.size[i] 1434 1434 if m < 2*q and q < m-2: 1435 if z_isprime(q):1435 if n_is_prime(q): 1436 1436 sage_free(perm) 1437 1437 OP_dealloc(OP) 1438 1438 return True -
deleted file sage/libs/flint/fmpq_poly.c
diff --git a/sage/libs/flint/fmpq_poly.c b/sage/libs/flint/fmpq_poly.c deleted file mode 100644
+ - 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 #ifdef __cplusplus12 extern "C" {13 #endif14 15 #include "fmpq_poly.h"16 17 /**18 * \file fmpq_poly.c19 * \brief Fast implementation of the rational function field20 * \author Sebastian Pancratz21 * \date Mar 2010 -- July 201022 * \version 0.1.823 *24 * \mainpage25 *26 * <center>27 * A FLINT-based implementation of the rational polynomial ring.28 * </center>29 *30 * \section Overview31 *32 * The module <tt>fmpq_poly</tt> provides functions for performing33 * arithmetic on rational polynomials in \f$\mathbf{Q}[t]\f$, represented as34 * quotients of integer polynomials of type <tt>fmpz_poly_t</tt> and35 * denominators of type <tt>fmpz_t</tt>. These functions start with the36 * prefix <tt>fmpq_poly_</tt>.37 *38 * Rational polynomials are stored in objects of type #fmpq_poly_t,39 * which is an array of #fmpq_poly_struct's of length one. This40 * permits passing parameters of type #fmpq_poly_t by reference.41 * We also define the type #fmpq_poly_ptr to be a pointer to42 * #fmpq_poly_struct's.43 *44 * The representation of a rational polynomial as the quotient of an integer45 * polynomial and an integer denominator can be made canonical by demanding46 * the numerator and denominator to be coprime and the denominator to be47 * positive. As the only special case, we represent the zero function as48 * \f$0/1\f$. All arithmetic functions assume that the operands are in this49 * canonical form, and canonicalize their result. If the numerator or50 * denominator is modified individually, for example using the methods in the51 * group \ref NumDen, it is the user's responsibility to canonicalize the52 * rational function using the function #fmpq_poly_canonicalize() if necessary.53 *54 * All methods support aliasing of their inputs and outputs \e unless55 * explicitly stated otherwise, subject to the following caveat. If56 * different rational polynomials (as objects in memory, not necessarily in57 * the mathematical sense) share some of the underlying integer polynomials58 * or integers, the behaviour is undefined.59 *60 * \section Changelog Version history61 * - 0.1.862 * - Extra checks for <tt>NULL</tt> returns of <tt>malloc</tt> calls63 * - 0.1.764 * - Explicit casts for return values of <tt>malloc</tt>65 * - Changed a few calls to GMP and FLINT methods from <tt>_si</tt>66 * to <tt>_ui</tt>67 * - 0.1.668 * - Added tons of testing code in the subdirectory <tt>test</tt>69 * - Made a few changes throughout the code base indicated by the tests70 * - 0.1.571 * - Re-wrote the entire code to always initialise the denominator72 * - 0.1.473 * - Fixed a bug in #fmpq_poly_divrem()74 * - Swapped calls to #fmpq_poly_degree to calls to #fmpq_poly_length in75 * many places76 * - 0.1.377 * - Changed #fmpq_poly_inv()78 * - Another sign check to <tt>fmpz_abs</tt> in #fmpq_poly_content()79 * - 0.1.280 * - Introduce a function #fmpq_poly_monic() and use this to simplify the81 * code for the gcd and xgcd functions82 * - Make further use of #fmpq_poly_is_zero()83 * - 0.1.184 * - Replaced a few sign checks and negations by <tt>fmpz_abs</tt>85 * - Small changes to comments and the documentation86 * - Moved some function bodies from #fmpq_poly.h to #fmpq_poly.c87 * - 0.1.088 * - First draft, based on the author's Sage code89 */90 91 /**92 * \defgroup Definitions Type definitions93 * \defgroup MemoryManagement Memory management94 * \defgroup NumDen Accessing numerator and denominator95 * \defgroup Assignment Assignment and basic manipulation96 * \defgroup Coefficients Setting and retrieving individual coefficients97 * \defgroup PolyParameters Polynomial parameters98 * \defgroup Comparison Comparison99 * \defgroup Addition Addition and subtraction100 * \defgroup ScalarMul Scalar multiplication and division101 * \defgroup Multiplication Multiplication102 * \defgroup Division Euclidean division103 * \defgroup Powering Powering104 * \defgroup GCD Greatest common divisor105 * \defgroup Derivative Derivative106 * \defgroup Evaluation Evaluation107 * \defgroup Content Gaussian content108 * \defgroup Resultant Resultant109 * \defgroup Composition Composition110 * \defgroup Squarefree Square-free test111 * \defgroup Subpolynomials Subpolynomials112 * \defgroup StringConversions String conversions and I/O113 */114 115 ///////////////////////////////////////////////////////////////////////////////116 // Auxiliary functions //117 ///////////////////////////////////////////////////////////////////////////////118 119 /**120 * Returns the number of digits in the decimal representation of \c n.121 */122 unsigned int fmpq_poly_places(ulong n)123 {124 unsigned int count;125 if (n == 0)126 return 1u;127 count = 0;128 while (n > 0)129 {130 n /= 10ul;131 count++;132 }133 return count;134 }135 136 ///////////////////////////////////////////////////////////////////////////////137 // Implementation //138 ///////////////////////////////////////////////////////////////////////////////139 140 /**141 * \brief Puts <tt>f</tt> into canonical form.142 * \ingroup Definitions143 *144 * This method ensures that the denominator is coprime to the content145 * of the numerator polynomial, and that the denominator is positive.146 *147 * The optional parameter <tt>temp</tt> is the temporary variable that this148 * method would otherwise need to allocate. If <tt>temp</tt> is provided as149 * an initialized <tt>fmpz_t</tt>, it is assumed \e without further checks150 * that it is large enough. For example,151 * <tt>max(f-\>num-\>limbs, fmpz_size(f-\>den))</tt> limbs will certainly152 * suffice.153 */154 void fmpq_poly_canonicalize(fmpq_poly_ptr f, fmpz_t temp)155 {156 if (fmpz_is_one(f->den))157 return;158 159 if (fmpq_poly_is_zero(f))160 fmpz_set_ui(f->den, 1ul);161 162 else if (fmpz_is_m1(f->den))163 {164 fmpz_poly_neg(f->num, f->num);165 fmpz_set_ui(f->den, 1ul);166 }167 168 else169 {170 int tcheck; /* Whether temp == NULL */171 //if (temp == NULL)172 //{173 tcheck = 1;174 temp = fmpz_init(FLINT_MAX(f->num->limbs, fmpz_size(f->den)));175 //}176 //else177 // tcheck = 0;178 179 fmpz_poly_content(temp, f->num);180 fmpz_abs(temp, temp);181 182 if (fmpz_is_one(temp))183 {184 if (fmpz_sgn(f->den) < 0)185 {186 fmpz_poly_neg(f->num, f->num);187 fmpz_neg(f->den, f->den);188 }189 }190 else191 {192 fmpz_t tempgcd;193 tempgcd = fmpz_init(FLINT_MAX(f->num->limbs, fmpz_size(f->den)));194 195 fmpz_gcd(tempgcd, temp, f->den);196 fmpz_abs(tempgcd, tempgcd);197 198 if (fmpz_is_one(tempgcd))199 {200 if (fmpz_sgn(f->den) < 0)201 {202 fmpz_poly_neg(f->num, f->num);203 fmpz_neg(f->den, f->den);204 }205 }206 else207 {208 if (fmpz_sgn(f->den) < 0)209 fmpz_neg(tempgcd, tempgcd);210 fmpz_poly_scalar_div_fmpz(f->num, f->num, tempgcd);211 fmpz_tdiv(temp, f->den, tempgcd);212 fmpz_set(f->den, temp);213 }214 215 fmpz_clear(tempgcd);216 }217 if (tcheck)218 fmpz_clear(temp);219 }220 }221 222 ///////////////////////////////////////////////////////////////////////////////223 // Assignment and basic manipulation224 225 /**226 * \ingroup Assignment227 *228 * Sets the element \c rop to the additive inverse of \c op.229 */230 void fmpq_poly_neg(fmpq_poly_ptr rop, const fmpq_poly_ptr op)231 {232 if (rop == op)233 {234 fmpz_poly_neg(rop->num, op->num);235 }236 else237 {238 fmpz_poly_neg(rop->num, op->num);239 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den));240 fmpz_set(rop->den, op->den);241 }242 }243 244 /**245 * \ingroup Assignment246 *247 * Sets the element \c rop to the multiplicative inverse of \c op.248 *249 * Assumes that the element \c op is a unit. Otherwise, an exception250 * is raised in the form of an <tt>abort</tt> statement.251 */252 void fmpq_poly_inv(fmpq_poly_ptr rop, const fmpq_poly_ptr op)253 {254 /* Assertion! */255 if (fmpq_poly_length(op) != 1ul)256 {257 printf("ERROR (fmpq_poly_inv). Element is not a unit.\n");258 abort();259 }260 261 if (rop == op)262 {263 fmpz_t t;264 t = fmpz_init(rop->num->limbs);265 fmpz_set(t, rop->num->coeffs);266 fmpz_poly_zero(rop->num);267 if (fmpz_sgn(t) > 0)268 {269 fmpz_poly_set_coeff_fmpz(rop->num, 0, rop->den);270 rop->den = fmpz_realloc(rop->den, fmpz_size(t));271 fmpz_set(rop->den, t);272 }273 else274 {275 fmpz_neg(rop->den, rop->den);276 fmpz_poly_set_coeff_fmpz(rop->num, 0, rop->den);277 rop->den = fmpz_realloc(rop->den, fmpz_size(t));278 fmpz_neg(rop->den, t);279 }280 fmpz_clear(t);281 }282 else283 {284 fmpz_poly_zero(rop->num);285 fmpz_poly_set_coeff_fmpz(rop->num, 0, op->den);286 rop->den = fmpz_realloc(rop->den, fmpz_size(op->num->coeffs));287 fmpz_set(rop->den, op->num->coeffs);288 if (fmpz_sgn(rop->den) < 0)289 {290 fmpz_poly_neg(rop->num, rop->num);291 fmpz_neg(rop->den, rop->den);292 }293 }294 }295 296 ///////////////////////////////////////////////////////////////////////////////297 // Setting/ retrieving individual coefficients298 299 /**300 * \ingroup Coefficients301 *302 * Obtains the <tt>i</tt>th coefficient from the polynomial <tt>op</tt>.303 */304 void fmpq_poly_get_coeff_mpq(mpq_t rop, const fmpq_poly_ptr op, ulong i)305 {306 fmpz_poly_get_coeff_mpz(mpq_numref(rop), op->num, i);307 fmpz_to_mpz(mpq_denref(rop), op->den);308 mpq_canonicalize(rop);309 }310 311 /**312 * \ingroup Coefficients313 *314 * Sets the <tt>i</tt>th coefficient of the polynomial <tt>op</tt> to \c x.315 */316 void fmpq_poly_set_coeff_fmpz(fmpq_poly_ptr rop, ulong i, const fmpz_t x)317 {318 fmpz_t t;319 int canonicalize;320 321 /* Is the denominator 1? This includes the case when rop == 0. */322 if (fmpz_is_one(rop->den))323 {324 fmpz_poly_set_coeff_fmpz(rop->num, i, x);325 return;326 }327 328 t = fmpz_poly_get_coeff_ptr(rop->num, i);329 canonicalize = !(t == NULL || fmpz_is_zero(t));330 331 t = fmpz_init(fmpz_size(x) + fmpz_size(rop->den));332 fmpz_mul(t, x, rop->den);333 fmpz_poly_set_coeff_fmpz(rop->num, i, t);334 fmpz_clear(t);335 if (canonicalize)336 fmpq_poly_canonicalize(rop, NULL);337 }338 339 /**340 * \ingroup Coefficients341 *342 * Sets the <tt>i</tt>th coefficient of the polynomial <tt>op</tt> to \c x.343 */344 void fmpq_poly_set_coeff_mpz(fmpq_poly_ptr rop, ulong i, const mpz_t x)345 {346 mpz_t z;347 fmpz_t t;348 int canonicalize;349 350 /* Is the denominator 1? This includes the case when rop == 0. */351 if (fmpz_is_one(rop->den))352 {353 fmpz_poly_set_coeff_mpz(rop->num, i, x);354 return;355 }356 357 t = fmpz_poly_get_coeff_ptr(rop->num, i);358 canonicalize = !(t == NULL || fmpz_is_zero(t));359 360 mpz_init(z);361 fmpz_to_mpz(z, rop->den);362 mpz_mul(z, z, x);363 fmpz_poly_set_coeff_mpz(rop->num, i, z);364 if (canonicalize)365 fmpq_poly_canonicalize(rop, NULL);366 mpz_clear(z);367 }368 369 /**370 * \ingroup Coefficients371 *372 * Sets the <tt>i</tt>th coefficient of the polynomial <tt>op</tt> to \c x.373 */374 void fmpq_poly_set_coeff_mpq(fmpq_poly_ptr rop, ulong i, const mpq_t x)375 {376 fmpz_t oldc;377 mpz_t den, gcd;378 int canonicalize;379 380 mpz_init(den);381 mpz_init(gcd);382 383 fmpz_to_mpz(den, rop->den);384 mpz_gcd(gcd, den, mpq_denref(x));385 386 oldc = fmpz_poly_get_coeff_ptr(rop->num, i);387 canonicalize = !(oldc == NULL || fmpz_is_zero(oldc));388 389 if (mpz_cmp(mpq_denref(x), gcd) == 0)390 {391 mpz_divexact(den, den, gcd);392 mpz_mul(gcd, den, mpq_numref(x));393 fmpz_poly_set_coeff_mpz(rop->num, i, gcd);394 }395 else396 {397 mpz_t t;398 399 mpz_init(t);400 mpz_divexact(t, mpq_denref(x), gcd);401 fmpz_poly_scalar_mul_mpz(rop->num, rop->num, t);402 403 mpz_divexact(gcd, den, gcd);404 mpz_mul(gcd, gcd, mpq_numref(x));405 406 fmpz_poly_set_coeff_mpz(rop->num, i, gcd);407 408 mpz_mul(den, den, t);409 rop->den = fmpz_realloc(rop->den, mpz_size(den));410 mpz_to_fmpz(rop->den, den);411 412 mpz_clear(t);413 }414 415 if (canonicalize)416 fmpq_poly_canonicalize(rop, NULL);417 418 mpz_clear(den);419 mpz_clear(gcd);420 }421 422 /**423 * \ingroup Coefficients424 *425 * Sets the <tt>i</tt>th coefficient of the polynomial <tt>op</tt> to \c x.426 */427 void fmpq_poly_set_coeff_si(fmpq_poly_ptr rop, ulong i, long x)428 {429 mpz_t z;430 fmpz_t t;431 int canonicalize;432 433 /* Is the denominator 1? This includes the case when rop == 0. */434 if (fmpz_is_one(rop->den))435 {436 fmpz_poly_set_coeff_si(rop->num, i, x);437 return;438 }439 440 t = fmpz_poly_get_coeff_ptr(rop->num, i);441 canonicalize = !(t == NULL || fmpz_is_zero(t));442 443 mpz_init(z);444 fmpz_to_mpz(z, rop->den);445 mpz_mul_si(z, z, x);446 fmpz_poly_set_coeff_mpz(rop->num, i, z);447 if (canonicalize)448 fmpq_poly_canonicalize(rop, NULL);449 mpz_clear(z);450 }451 452 ///////////////////////////////////////////////////////////////////////////////453 // Comparison454 455 /**456 * \brief Returns whether \c op1 and \c op2 are equal.457 * \ingroup Comparison458 *459 * Returns whether the two elements \c op1 and \c op2 are equal.460 */461 int fmpq_poly_equal(const fmpq_poly_ptr op1, const fmpq_poly_ptr op2)462 {463 return (op1->num->length == op2->num->length)464 && (fmpz_equal(op1->den, op2->den))465 && (fmpz_poly_equal(op1->num, op2->num));466 }467 468 /**469 * \brief Compares the two polynomials <tt>left</tt> and <tt>right</tt>.470 * \ingroup Comparison471 *472 * Compares the two polnomials <tt>left</tt> and <tt>right</tt>, returning473 * <tt>-1</tt>, <tt>0</tt>, or <tt>1</tt> as <tt>left</tt> is less than,474 * equal to, or greater than <tt>right</tt>.475 *476 * The comparison is first done by degree and then, in case of a tie, by477 * the individual coefficients, beginning with the highest.478 */479 int fmpq_poly_cmp(const fmpq_poly_ptr left, const fmpq_poly_ptr right)480 {481 long degdiff, i;482 483 /* Quick check whether left and right are the same object. */484 if (left == right)485 return 0;486 487 i = fmpz_poly_degree(left->num);488 degdiff = i - fmpz_poly_degree(right->num);489 490 if (degdiff < 0)491 return -1;492 else if (degdiff > 0)493 return 1;494 else495 {496 int ans;497 ulong limbs;498 fmpz_t lcoeff, rcoeff;499 500 if (fmpz_equal(left->den, right->den))501 {502 if (i == -1) /* left and right are both zero */503 return 0;504 limbs = FLINT_MAX(left->num->limbs, right->num->limbs) + 1;505 lcoeff = fmpz_init(limbs);506 while (fmpz_equal(fmpz_poly_get_coeff_ptr(left->num, i),507 fmpz_poly_get_coeff_ptr(right->num, i)) && i > 0)508 i--;509 fmpz_sub(lcoeff, fmpz_poly_get_coeff_ptr(left->num, i),510 fmpz_poly_get_coeff_ptr(right->num, i));511 ans = fmpz_sgn(lcoeff);512 fmpz_clear(lcoeff);513 return ans;514 }515 else if (fmpz_is_one(left->den))516 {517 limbs = FLINT_MAX(left->num->limbs + fmpz_size(right->den),518 right->num->limbs) + 1;519 lcoeff = fmpz_init(limbs);520 fmpz_mul(lcoeff, fmpz_poly_get_coeff_ptr(left->num, i), right->den);521 while (fmpz_equal(lcoeff, fmpz_poly_get_coeff_ptr(right->num, i))522 && i > 0)523 {524 i--;525 fmpz_mul(lcoeff, fmpz_poly_get_coeff_ptr(left->num, i),526 right->den);527 }528 fmpz_sub(lcoeff, lcoeff, fmpz_poly_get_coeff_ptr(right->num, i));529 ans = fmpz_sgn(lcoeff);530 fmpz_clear(lcoeff);531 return ans;532 }533 else if (fmpz_is_one(right->den))534 {535 limbs = FLINT_MAX(left->num->limbs,536 right->num->limbs + fmpz_size(left->den)) + 1;537 rcoeff = fmpz_init(limbs);538 fmpz_mul(rcoeff, fmpz_poly_get_coeff_ptr(right->num, i), left->den);539 while (fmpz_equal(fmpz_poly_get_coeff_ptr(left->num, i), rcoeff)540 && i > 0)541 {542 i--;543 fmpz_mul(rcoeff, fmpz_poly_get_coeff_ptr(right->num, i),544 left->den);545 }546 fmpz_sub(rcoeff, fmpz_poly_get_coeff_ptr(left->num, i), rcoeff);547 ans = fmpz_sgn(rcoeff);548 fmpz_clear(rcoeff);549 return ans;550 }551 else552 {553 limbs = FLINT_MAX(left->num->limbs + fmpz_size(right->den),554 right->num->limbs + fmpz_size(left->den)) + 1;555 lcoeff = fmpz_init(limbs);556 rcoeff = fmpz_init(right->num->limbs + fmpz_size(left->den));557 fmpz_mul(lcoeff, fmpz_poly_get_coeff_ptr(left->num, i), right->den);558 fmpz_mul(rcoeff, fmpz_poly_get_coeff_ptr(right->num, i), left->den);559 while (fmpz_equal(lcoeff, rcoeff) && i > 0)560 {561 i--;562 fmpz_mul(lcoeff, fmpz_poly_get_coeff_ptr(left->num, i),563 right->den);564 fmpz_mul(rcoeff, fmpz_poly_get_coeff_ptr(right->num, i),565 left->den);566 }567 fmpz_sub(lcoeff, lcoeff, rcoeff);568 ans = fmpz_sgn(lcoeff);569 fmpz_clear(lcoeff);570 fmpz_clear(rcoeff);571 return ans;572 }573 }574 }575 576 ///////////////////////////////////////////////////////////////////////////////577 // Addition/ subtraction578 579 /**580 * \ingroup Addition581 *582 * Sets \c rop to the sum of \c rop and \c op.583 *584 * \todo This is currently implemented by creating a copy!585 */586 void _fmpq_poly_add_in_place(fmpq_poly_ptr rop, const fmpq_poly_ptr op)587 {588 if (rop == op)589 {590 fmpq_poly_scalar_mul_si(rop, rop, 2l);591 return;592 }593 594 if (fmpq_poly_is_zero(rop))595 {596 fmpq_poly_set(rop, op);597 return;598 }599 if (fmpq_poly_is_zero(op))600 {601 return;602 }603 604 /* Now we may assume that rop and op refer to distinct objects in */605 /* memory and that both polynomials are non-zero. */606 fmpq_poly_t t;607 fmpq_poly_init(t);608 fmpq_poly_add(t, rop, op);609 fmpq_poly_swap(rop, t);610 fmpq_poly_clear(t);611 }612 613 /**614 * \ingroup Addition615 *616 * Sets \c rop to the sum of \c op1 and \c op2.617 */618 void fmpq_poly_add(fmpq_poly_ptr rop, const fmpq_poly_ptr op1, const fmpq_poly_ptr op2)619 {620 if (op1 == op2)621 {622 fmpq_poly_scalar_mul_si(rop, op1, 2l);623 return;624 }625 626 if (rop == op1)627 {628 _fmpq_poly_add_in_place(rop, op2);629 return;630 }631 if (rop == op2)632 {633 _fmpq_poly_add_in_place(rop, op1);634 return;635 }636 637 /* From here on, we may assume that rop, op1 and op2 all refer to */638 /* distinct objects in memory, although they may still be equal. */639 640 if (fmpz_is_one(op1->den))641 {642 if (fmpz_is_one(op2->den))643 {644 fmpz_poly_add(rop->num, op1->num, op2->num);645 fmpz_set_ui(rop->den, 1ul);646 }647 else648 {649 fmpz_poly_scalar_mul_fmpz(rop->num, op1->num, op2->den);650 fmpz_poly_add(rop->num, rop->num, op2->num);651 rop->den = fmpz_realloc(rop->den, fmpz_size(op2->den));652 fmpz_set(rop->den, op2->den);653 }654 }655 else656 {657 if (fmpz_is_one(op2->den))658 {659 fmpz_poly_scalar_mul_fmpz(rop->num, op2->num, op1->den);660 fmpz_poly_add(rop->num, op1->num, rop->num);661 rop->den = fmpz_realloc(rop->den, fmpz_size(op1->den));662 fmpz_set(rop->den, op1->den);663 }664 else665 {666 fmpz_poly_t tpoly;667 fmpz_t tfmpz;668 ulong limbs;669 670 fmpz_poly_init(tpoly);671 672 limbs = fmpz_size(op1->den) + fmpz_size(op2->den);673 rop->den = fmpz_realloc(rop->den, limbs);674 675 limbs = FLINT_MAX(limbs, fmpz_size(op2->den) + op1->num->limbs);676 limbs = FLINT_MAX(limbs, fmpz_size(op1->den) + op2->num->limbs);677 tfmpz = fmpz_init(limbs);678 679 fmpz_gcd(rop->den, op1->den, op2->den);680 fmpz_tdiv(tfmpz, op2->den, rop->den);681 fmpz_poly_scalar_mul_fmpz(rop->num, op1->num, tfmpz);682 fmpz_tdiv(tfmpz, op1->den, rop->den);683 fmpz_poly_scalar_mul_fmpz(tpoly, op2->num, tfmpz);684 fmpz_poly_add(rop->num, rop->num, tpoly);685 fmpz_mul(rop->den, tfmpz, op2->den);686 687 fmpq_poly_canonicalize(rop, tfmpz);688 689 fmpz_poly_clear(tpoly);690 fmpz_clear(tfmpz);691 }692 }693 }694 695 /**696 * \ingroup Addition697 *698 * Sets \c rop to the difference of \c rop and \c op.699 *700 * \note This is implemented using the methods #fmpq_poly_neg() and701 * #_fmpq_poly_add_in_place().702 */703 void _fmpq_poly_sub_in_place(fmpq_poly_ptr rop, const fmpq_poly_ptr op)704 {705 if (rop == op)706 {707 fmpq_poly_zero(rop);708 return;709 }710 711 fmpq_poly_neg(rop, rop);712 _fmpq_poly_add_in_place(rop, op);713 fmpq_poly_neg(rop, rop);714 }715 716 /**717 * \ingroup Addition718 *719 * Sets \c rop to the difference of \c op1 and \c op2.720 */721 void fmpq_poly_sub(fmpq_poly_ptr rop, const fmpq_poly_ptr op1, const fmpq_poly_ptr op2)722 {723 if (op1 == op2)724 {725 fmpq_poly_zero(rop);726 return;727 }728 if (rop == op1)729 {730 _fmpq_poly_sub_in_place(rop, op2);731 return;732 }733 if (rop == op2)734 {735 _fmpq_poly_sub_in_place(rop, op1);736 fmpq_poly_neg(rop, rop);737 return;738 }739 740 /* From here on, we know that rop, op1 and op2 refer to distinct objects */741 /* in memory, although as rational functions they may still be equal */742 743 if (fmpz_is_one(op1->den))744 {745 if (fmpz_is_one(op2->den))746 {747 fmpz_poly_sub(rop->num, op1->num, op2->num);748 fmpz_set_ui(rop->den, 1ul);749 }750 else751 {752 fmpz_poly_scalar_mul_fmpz(rop->num, op1->num, op2->den);753 fmpz_poly_sub(rop->num, rop->num, op2->num);754 rop->den = fmpz_realloc(rop->den, fmpz_size(op2->den));755 fmpz_set(rop->den, op2->den);756 }757 }758 else759 {760 if (fmpz_is_one(op2->den))761 {762 fmpz_poly_scalar_mul_fmpz(rop->num, op2->num, op1->den);763 fmpz_poly_sub(rop->num, op1->num, rop->num);764 rop->den = fmpz_realloc(rop->den, fmpz_size(op1->den));765 fmpz_set(rop->den, op1->den);766 }767 else768 {769 fmpz_poly_t tpoly;770 fmpz_t tfmpz;771 ulong limbs;772 773 fmpz_poly_init(tpoly);774 775 limbs = fmpz_size(op1->den) + fmpz_size(op2->den);776 rop->den = fmpz_realloc(rop->den, limbs);777 778 limbs = FLINT_MAX(limbs, fmpz_size(op2->den) + op1->num->limbs);779 limbs = FLINT_MAX(limbs, fmpz_size(op1->den) + op2->num->limbs);780 tfmpz = fmpz_init(limbs);781 782 fmpz_gcd(rop->den, op1->den, op2->den);783 fmpz_tdiv(tfmpz, op2->den, rop->den);784 fmpz_poly_scalar_mul_fmpz(rop->num, op1->num, tfmpz);785 fmpz_tdiv(tfmpz, op1->den, rop->den);786 fmpz_poly_scalar_mul_fmpz(tpoly, op2->num, tfmpz);787 fmpz_poly_sub(rop->num, rop->num, tpoly);788 fmpz_mul(rop->den, tfmpz, op2->den);789 790 fmpq_poly_canonicalize(rop, tfmpz);791 792 fmpz_poly_clear(tpoly);793 fmpz_clear(tfmpz);794 }795 }796 }797 798 /**799 * \ingroup Addition800 *801 * Sets \c rop to <tt>rop + op1 * op2</tt>.802 *803 * Currently, this method refers to the methods #fmpq_poly_mul() and804 * #fmpq_poly_add() to form the result in the naive way.805 *806 * \todo Implement this method more efficiently.807 */808 void fmpq_poly_addmul(fmpq_poly_ptr rop, const fmpq_poly_ptr op1, const fmpq_poly_ptr op2)809 {810 fmpq_poly_t t;811 fmpq_poly_init(t);812 fmpq_poly_mul(t, op1, op2);813 fmpq_poly_add(rop, rop, t);814 fmpq_poly_clear(t);815 }816 817 /**818 * \ingroup Addition819 *820 * Sets \c rop to <tt>rop - op1 * op2</tt>.821 *822 * Currently, this method refers to the methods #fmpq_poly_mul() and823 * #fmpq_poly_sub() to form the result in the naive way.824 *825 * \todo Implement this method more efficiently.826 */827 void fmpq_poly_submul(fmpq_poly_ptr rop, const fmpq_poly_ptr op1, const fmpq_poly_ptr op2)828 {829 fmpq_poly_t t;830 fmpq_poly_init(t);831 fmpq_poly_mul(t, op1, op2);832 fmpq_poly_sub(rop, rop, t);833 fmpq_poly_clear(t);834 }835 836 ///////////////////////////////////////////////////////////////////////////////837 // Scalar multiplication and division838 839 /**840 * \ingroup ScalarMul841 *842 * Sets \c rop to the scalar product of \c op and the integer \c x.843 */844 void fmpq_poly_scalar_mul_si(fmpq_poly_ptr rop, const fmpq_poly_ptr op, long x)845 {846 if (fmpz_is_one(op->den))847 {848 fmpz_poly_scalar_mul_si(rop->num, op->num, x);849 fmpz_set_ui(rop->den, 1ul);850 }851 else852 {853 fmpz_t fx, g;854 855 g = fmpz_init(fmpz_size(op->den));856 fx = fmpz_init(1);857 fmpz_set_si(fx, x);858 fmpz_gcd(g, op->den, fx);859 fmpz_abs(g, g);860 if (fmpz_is_one(g))861 {862 fmpz_poly_scalar_mul_si(rop->num, op->num, x);863 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den));864 fmpz_set(rop->den, op->den);865 }866 else867 {868 if (rop == op)869 {870 fmpz_t t;871 t = fmpz_init(fmpz_size(op->den));872 fmpz_tdiv(t, fx, g);873 fmpz_poly_scalar_mul_fmpz(rop->num, op->num, t);874 fmpz_tdiv(t, op->den, g);875 fmpz_clear(rop->den); // FIXME Fixed876 rop->den = t;877 }878 else879 {880 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den));881 fmpz_tdiv(rop->den, fx, g);882 fmpz_poly_scalar_mul_fmpz(rop->num, op->num, rop->den);883 fmpz_tdiv(rop->den, op->den, g);884 }885 }886 fmpz_clear(g);887 fmpz_clear(fx);888 }889 }890 891 /**892 * \ingroup ScalarMul893 *894 * Sets \c rop to the scalar multiple of \c op with the \c mpz_t \c x.895 */896 void fmpq_poly_scalar_mul_mpz(fmpq_poly_ptr rop, const fmpq_poly_ptr op, const mpz_t x)897 {898 fmpz_t g, y;899 900 if (fmpz_is_one(op->den))901 {902 fmpz_poly_scalar_mul_mpz(rop->num, op->num, x);903 fmpz_set_ui(rop->den, 1UL);904 return;905 }906 907 if (mpz_cmpabs_ui(x, 1) == 0)908 {909 if (mpz_sgn(x) > 0)910 fmpq_poly_set(rop, op);911 else912 fmpq_poly_neg(rop, op);913 return;914 }915 if (mpz_sgn(x) == 0)916 {917 fmpq_poly_zero(rop);918 return;919 }920 921 g = fmpz_init(FLINT_MAX(fmpz_size(op->den), mpz_size(x)));922 y = fmpz_init(mpz_size(x));923 mpz_to_fmpz(y, x);924 925 fmpz_gcd(g, op->den, y);926 927 if (fmpz_is_one(g))928 {929 fmpz_poly_scalar_mul_fmpz(rop->num, op->num, y);930 if (rop != op)931 {932 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den));933 fmpz_set(rop->den, op->den);934 }935 }936 else937 {938 fmpz_t t;939 t = fmpz_init(FLINT_MAX(fmpz_size(y), fmpz_size(op->den)));940 fmpz_divides(t, y, g);941 fmpz_poly_scalar_mul_fmpz(rop->num, op->num, t);942 fmpz_divides(t, op->den, g);943 fmpz_clear(rop->den);944 rop->den = t;945 }946 947 fmpz_clear(g);948 fmpz_clear(y);949 }950 951 /**952 * \ingroup ScalarMul953 *954 * Sets \c rop to the scalar multiple of \c op with the \c mpq_t \c x.955 */956 void fmpq_poly_scalar_mul_mpq(fmpq_poly_ptr rop, const fmpq_poly_ptr op, const mpq_t x)957 {958 fmpz_poly_scalar_mul_mpz(rop->num, op->num, mpq_numref(x));959 if (fmpz_is_one(op->den))960 {961 rop->den = fmpz_realloc(rop->den, mpz_size(mpq_denref(x)));962 mpz_to_fmpz(rop->den, mpq_denref(x));963 }964 else965 {966 fmpz_t s, t;967 s = fmpz_init(mpz_size(mpq_denref(x)));968 t = fmpz_init(fmpz_size(op->den));969 mpz_to_fmpz(s, mpq_denref(x));970 fmpz_set(t, op->den);971 rop->den = fmpz_realloc(rop->den, fmpz_size(s) + fmpz_size(t));972 fmpz_mul(rop->den, s, t);973 fmpz_clear(s);974 fmpz_clear(t);975 }976 fmpq_poly_canonicalize(rop, NULL);977 }978 979 /**980 * /ingroup ScalarMul981 *982 * Divides \c rop by the integer \c x.983 *984 * Assumes that \c x is non-zero. Otherwise, an exception is raised in the985 * form of an <tt>abort</tt> statement.986 */987 void _fmpq_poly_scalar_div_si_in_place(fmpq_poly_ptr rop, long x)988 {989 fmpz_t cont, fx, gcd;990 991 /* Assertion! */992 if (x == 0l)993 {994 printf("ERROR (_fmpq_poly_scalar_div_si_in_place). Division by zero.\n");995 abort();996 }997 998 if (x == 1l)999 {1000 return;1001 }1002 1003 cont = fmpz_init(rop->num->limbs);1004 fmpz_poly_content(cont, rop->num);1005 fmpz_abs(cont, cont);1006 1007 if (fmpz_is_one(cont))1008 {1009 if (x > 0l)1010 {1011 if (fmpz_is_one(rop->den))1012 {1013 fmpz_set_si(rop->den, x);1014 }1015 else1016 {1017 fmpz_t t;1018 t = fmpz_init(fmpz_size(rop->den) + 1);1019 fmpz_mul_ui(t, rop->den, (ulong) x);1020 fmpz_clear(rop->den); // FIXME Fixed1021 rop->den = t;1022 }1023 }1024 else1025 {1026 fmpz_poly_neg(rop->num, rop->num);1027 if (fmpz_is_one(rop->den))1028 {1029 fmpz_set_si(rop->den, -x);1030 }1031 else1032 {1033 fmpz_t t;1034 t = fmpz_init(fmpz_size(rop->den) + 1);1035 fmpz_mul_ui(t, rop->den, (ulong) -x);1036 fmpz_clear(rop->den); // FIXME Fixed1037 rop->den = t;1038 }1039 }1040 fmpz_clear(cont);1041 return;1042 }1043 1044 fx = fmpz_init(1);1045 fmpz_set_si(fx, x);1046 1047 gcd = fmpz_init(FLINT_MAX(rop->num->limbs, fmpz_size(fx)));1048 fmpz_gcd(gcd, cont, fx);1049 fmpz_abs(gcd, gcd);1050 1051 if (fmpz_is_one(gcd))1052 {1053 if (x > 0l)1054 {1055 if (fmpz_is_one(rop->den))1056 {1057 fmpz_set_si(rop->den, x);1058 }1059 else1060 {1061 fmpz_t t;1062 t = fmpz_init(fmpz_size(rop->den) + 1);1063 fmpz_mul_ui(t, rop->den, (ulong) x);1064 fmpz_clear(rop->den); // FIXME Fixed1065 rop->den = t;1066 }1067 }1068 else1069 {1070 fmpz_poly_neg(rop->num, rop->num);1071 if (fmpz_is_one(rop->den))1072 {1073 fmpz_set_si(rop->den, -x);1074 }1075 else1076 {1077 fmpz_t t;1078 t = fmpz_init(fmpz_size(rop->den) + 1);1079 fmpz_mul_ui(t, rop->den, (ulong) -x);1080 fmpz_clear(rop->den); // FIXME Fixed1081 rop->den = t;1082 }1083 }1084 }1085 else1086 {1087 fmpz_poly_scalar_div_fmpz(rop->num, rop->num, gcd);1088 if (fmpz_is_one(rop->den))1089 {1090 fmpz_tdiv(rop->den, fx, gcd);1091 }1092 else1093 {1094 fmpz_tdiv(cont, fx, gcd);1095 fx = fmpz_realloc(fx, fmpz_size(rop->den));1096 fmpz_set(fx, rop->den);1097 rop->den = fmpz_realloc(rop->den, fmpz_size(rop->den) + 1);1098 fmpz_mul(rop->den, fx, cont);1099 }1100 if (x < 0l)1101 {1102 fmpz_poly_neg(rop->num, rop->num);1103 fmpz_neg(rop->den, rop->den);1104 }1105 }1106 1107 fmpz_clear(cont);1108 fmpz_clear(fx);1109 fmpz_clear(gcd);1110 }1111 1112 1113 /**1114 * \ingroup ScalarMul1115 *1116 * Sets \c rop to the scalar multiple of \c op with the multiplicative inverse1117 * of the integer \c x.1118 *1119 * Assumes that \c x is non-zero. Otherwise, an exception is raised in the1120 * form of an <tt>abort</tt> statement.1121 */1122 void fmpq_poly_scalar_div_si(fmpq_poly_ptr rop, const fmpq_poly_ptr op, long x)1123 {1124 fmpz_t cont, fx, gcd;1125 1126 /* Assertion! */1127 if (x == 0l)1128 {1129 printf("ERROR (fmpq_poly_scalar_div_si). Division by zero.\n");1130 abort();1131 }1132 1133 if (rop == op)1134 {1135 _fmpq_poly_scalar_div_si_in_place(rop, x);1136 return;1137 }1138 1139 /* From here on, we may assume that rop and op denote two different */1140 /* rational polynomials (as objects in memory). */1141 1142 if (x == 1l)1143 {1144 fmpq_poly_set(rop, op);1145 return;1146 }1147 1148 cont = fmpz_init(op->num->limbs);1149 fmpz_poly_content(cont, op->num);1150 fmpz_abs(cont, cont);1151 1152 if (fmpz_is_one(cont))1153 {1154 if (x > 0l)1155 {1156 fmpz_poly_set(rop->num, op->num);1157 if (fmpz_is_one(op->den))1158 {1159 fmpz_set_si(rop->den, x);1160 }1161 else1162 {1163 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den) + 1);1164 fmpz_mul_ui(rop->den, op->den, (ulong) x);1165 }1166 }1167 else1168 {1169 fmpz_poly_neg(rop->num, op->num);1170 if (fmpz_is_one(op->den))1171 {1172 fmpz_set_si(rop->den, -x);1173 }1174 else1175 {1176 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den) + 1);1177 fmpz_mul_ui(rop->den, op->den, (ulong) -x);1178 }1179 }1180 fmpz_clear(cont);1181 return;1182 }1183 1184 fx = fmpz_init(1);1185 fmpz_set_si(fx, x);1186 1187 gcd = fmpz_init(FLINT_MAX(op->num->limbs, fmpz_size(fx)));1188 fmpz_gcd(gcd, cont, fx);1189 fmpz_abs(gcd, gcd);1190 1191 if (fmpz_is_one(gcd))1192 {1193 if (x > 0l)1194 {1195 fmpz_poly_set(rop->num, op->num);1196 if (fmpz_is_one(op->den))1197 {1198 fmpz_set_si(rop->den, x);1199 }1200 else1201 {1202 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den) + 1);1203 fmpz_mul_ui(rop->den, op->den, (ulong) x);1204 }1205 }1206 else1207 {1208 fmpz_poly_neg(rop->num, op->num);1209 if (fmpz_is_one(op->den))1210 {1211 fmpz_set_si(rop->den, -x);1212 }1213 else1214 {1215 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den) + 1);1216 fmpz_mul_ui(rop->den, op->den, (ulong) -x);1217 }1218 }1219 }1220 else1221 {1222 fmpz_poly_scalar_div_fmpz(rop->num, op->num, gcd);1223 if (fmpz_is_one(op->den))1224 {1225 fmpz_tdiv(rop->den, fx, gcd);1226 }1227 else1228 {1229 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den) + 1);1230 fmpz_tdiv(cont, fx, gcd); /* fx and gcd are word-sized */1231 fmpz_mul(rop->den, op->den, cont);1232 }1233 if (x < 0l)1234 {1235 fmpz_poly_neg(rop->num, rop->num);1236 fmpz_neg(rop->den, rop->den);1237 }1238 }1239 1240 fmpz_clear(cont);1241 fmpz_clear(fx);1242 fmpz_clear(gcd);1243 }1244 1245 /**1246 * \ingroup ScalarMul1247 *1248 * Sets \c rop to the scalar multiple of \c op with the multiplicative inverse1249 * of the integer \c x.1250 *1251 * Assumes that \c x is non-zero. Otherwise, an exception is raised in the1252 * form of an <tt>abort</tt> statement.1253 */1254 void _fmpq_poly_scalar_div_mpz_in_place(fmpq_poly_ptr rop, const mpz_t x)1255 {1256 fmpz_t cont, fx, gcd;1257 1258 /* Assertion! */1259 if (mpz_sgn(x) == 0)1260 {1261 printf("ERROR (_fmpq_poly_scalar_div_mpz_in_place). Division by zero.\n");1262 abort();1263 }1264 1265 if (mpz_cmp_ui(x, 1) == 0)1266 return;1267 1268 cont = fmpz_init(rop->num->limbs);1269 fmpz_poly_content(cont, rop->num);1270 fmpz_abs(cont, cont);1271 1272 if (fmpz_is_one(cont))1273 {1274 if (fmpz_is_one(rop->den))1275 {1276 rop->den = fmpz_realloc(rop->den, mpz_size(x));1277 mpz_to_fmpz(rop->den, x);1278 }1279 else1280 {1281 fmpz_t t;1282 fx = fmpz_init(mpz_size(x));1283 mpz_to_fmpz(fx, x);1284 t = fmpz_init(fmpz_size(rop->den) + mpz_size(x));1285 fmpz_mul(t, rop->den, fx);1286 fmpz_clear(rop->den); // FIXME Fixed1287 rop->den = t;1288 fmpz_clear(fx);1289 }1290 if (mpz_sgn(x) < 0)1291 {1292 fmpz_poly_neg(rop->num, rop->num);1293 fmpz_neg(rop->den, rop->den);1294 }1295 fmpz_clear(cont);1296 return;1297 }1298 1299 fx = fmpz_init(mpz_size(x));1300 mpz_to_fmpz(fx, x);1301 1302 gcd = fmpz_init(FLINT_MAX(rop->num->limbs, fmpz_size(fx)));1303 fmpz_gcd(gcd, cont, fx);1304 fmpz_abs(gcd, gcd);1305 1306 if (fmpz_is_one(gcd))1307 {1308 if (fmpz_is_one(rop->den))1309 {1310 rop->den = fmpz_realloc(rop->den, mpz_size(x));1311 mpz_to_fmpz(rop->den, x);1312 }1313 else1314 {1315 fmpz_t t;1316 t = fmpz_init(fmpz_size(rop->den) + mpz_size(x));1317 fmpz_mul(t, rop->den, fx);1318 fmpz_clear(rop->den); // FIXME Fixed1319 rop->den = t;1320 }1321 if (mpz_sgn(x) < 0)1322 {1323 fmpz_poly_neg(rop->num, rop->num);1324 fmpz_neg(rop->den, rop->den);1325 }1326 }1327 else1328 {1329 fmpz_poly_scalar_div_fmpz(rop->num, rop->num, gcd);1330 if (fmpz_is_one(rop->den))1331 {1332 rop->den = fmpz_realloc(rop->den, fmpz_size(fx));1333 fmpz_tdiv(rop->den, fx, gcd);1334 }1335 else1336 {1337 cont = fmpz_realloc(cont, fmpz_size(fx));1338 fmpz_tdiv(cont, fx, gcd);1339 fx = fmpz_realloc(fx, fmpz_size(rop->den));1340 fmpz_set(fx, rop->den);1341 rop->den = fmpz_realloc(rop->den, fmpz_size(fx) + fmpz_size(cont));1342 fmpz_mul(rop->den, fx, cont);1343 }1344 if (mpz_sgn(x) < 0)1345 {1346 fmpz_poly_neg(rop->num, rop->num);1347 fmpz_neg(rop->den, rop->den);1348 }1349 }1350 1351 fmpz_clear(cont);1352 fmpz_clear(fx);1353 fmpz_clear(gcd);1354 }1355 1356 /**1357 * \ingroup ScalarMul1358 *1359 * Sets \c rop to the scalar multiple of \c op with the multiplicative inverse1360 * of the integer \c x.1361 *1362 * Assumes that \c x is non-zero. Otherwise, an exception is raised in the1363 * form of an <tt>abort</tt> statement.1364 */1365 void fmpq_poly_scalar_div_mpz(fmpq_poly_ptr rop, const fmpq_poly_ptr op, const mpz_t x)1366 {1367 fmpz_t cont, fx, gcd;1368 1369 /* Assertion! */1370 if (mpz_sgn(x) == 0)1371 {1372 printf("ERROR (fmpq_poly_scalar_div_mpz). Division by zero.\n");1373 abort();1374 }1375 1376 if (rop == op)1377 {1378 _fmpq_poly_scalar_div_mpz_in_place(rop, x);1379 return;1380 }1381 1382 /* From here on, we may assume that rop and op denote two different */1383 /* rational polynomials (as objects in memory). */1384 1385 if (mpz_cmp_ui(x, 1) == 0)1386 {1387 fmpq_poly_set(rop, op);1388 return;1389 }1390 1391 cont = fmpz_init(op->num->limbs);1392 fmpz_poly_content(cont, op->num);1393 fmpz_abs(cont, cont);1394 1395 if (fmpz_is_one(cont))1396 {1397 if (fmpz_is_one(op->den))1398 {1399 rop->den = fmpz_realloc(rop->den, mpz_size(x));1400 mpz_to_fmpz(rop->den, x);1401 }1402 else1403 {1404 fmpz_t t;1405 t = fmpz_init(mpz_size(x));1406 mpz_to_fmpz(t, x);1407 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den) + fmpz_size(t));1408 fmpz_mul(rop->den, op->den, t);1409 fmpz_clear(t);1410 }1411 if (mpz_sgn(x) > 0)1412 {1413 fmpz_poly_set(rop->num, op->num);1414 }1415 else1416 {1417 fmpz_poly_neg(rop->num, op->num);1418 fmpz_neg(rop->den, rop->den);1419 }1420 fmpz_clear(cont);1421 return;1422 }1423 1424 fx = fmpz_init(mpz_size(x));1425 mpz_to_fmpz(fx, x);1426 1427 gcd = fmpz_init(FLINT_MAX(op->num->limbs, fmpz_size(fx)));1428 fmpz_gcd(gcd, cont, fx);1429 fmpz_abs(gcd, gcd);1430 1431 if (fmpz_is_one(gcd))1432 {1433 if (fmpz_is_one(op->den))1434 {1435 rop->den = fmpz_realloc(rop->den, mpz_size(x));1436 mpz_to_fmpz(rop->den, x);1437 }1438 else1439 {1440 fmpz_t t;1441 t = fmpz_init(mpz_size(x));1442 mpz_to_fmpz(t, x);1443 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den) + fmpz_size(t));1444 fmpz_mul(rop->den, op->den, t);1445 fmpz_clear(t);1446 }1447 if (mpz_sgn(x) > 0)1448 {1449 fmpz_poly_set(rop->num, op->num);1450 }1451 else1452 {1453 fmpz_poly_neg(rop->num, op->num);1454 fmpz_neg(rop->den, rop->den);1455 }1456 }1457 else1458 {1459 fmpz_poly_scalar_div_fmpz(rop->num, op->num, gcd);1460 if (fmpz_is_one(op->den))1461 {1462 rop->den = fmpz_realloc(rop->den, fmpz_size(fx));1463 fmpz_tdiv(rop->den, fx, gcd);1464 }1465 else1466 {1467 cont = fmpz_realloc(cont, fmpz_size(fx));1468 fmpz_tdiv(cont, fx, gcd);1469 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den) + fmpz_size(cont));1470 fmpz_mul(rop->den, op->den, cont);1471 }1472 if (mpz_sgn(x) < 0)1473 {1474 fmpz_poly_neg(rop->num, rop->num);1475 fmpz_neg(rop->den, rop->den);1476 }1477 }1478 1479 fmpz_clear(cont);1480 fmpz_clear(fx);1481 fmpz_clear(gcd);1482 }1483 1484 /**1485 * \ingroup ScalarMul1486 *1487 * Sets \c rop to the scalar multiple of \c op with the multiplicative inverse1488 * of the rational \c x.1489 *1490 * Assumes that the rational \c x is in lowest terms and non-zero. If the1491 * rational is not in lowest terms, the resulting value of <tt>rop</tt> is1492 * undefined. If <tt>x</tt> is zero, an exception is raised in the form1493 * of an <tt>abort</tt> statement.1494 */1495 void fmpq_poly_scalar_div_mpq(fmpq_poly_ptr rop, const fmpq_poly_ptr op, const mpq_t x)1496 {1497 /* Assertion! */1498 if (mpz_sgn(mpq_numref(x)) == 0)1499 {1500 printf("ERROR (fmpq_poly_scalar_div_mpq). Division by zero.\n");1501 abort();1502 }1503 1504 fmpz_poly_scalar_mul_mpz(rop->num, op->num, mpq_denref(x));1505 if (fmpz_is_one(op->den))1506 {1507 rop->den = fmpz_realloc(rop->den, mpz_size(mpq_numref(x)));1508 mpz_to_fmpz(rop->den, mpq_numref(x));1509 }1510 else1511 {1512 fmpz_t s, t;1513 s = fmpz_init(mpz_size(mpq_numref(x)));1514 t = fmpz_init(fmpz_size(op->den));1515 mpz_to_fmpz(s, mpq_numref(x));1516 fmpz_set(t, op->den);1517 rop->den = fmpz_realloc(rop->den, fmpz_size(s) + fmpz_size(t));1518 fmpz_mul(rop->den, s, t);1519 fmpz_clear(s);1520 fmpz_clear(t);1521 }1522 fmpq_poly_canonicalize(rop, NULL);1523 }1524 1525 ///////////////////////////////////////////////////////////////////////////////1526 // Multiplication1527 1528 /**1529 * \ingroup Multiplication1530 *1531 * Multiplies <tt>rop</tt> by <tt>op</tt>.1532 */1533 void _fmpq_poly_mul_in_place(fmpq_poly_ptr rop, const fmpq_poly_ptr op)1534 {1535 fmpq_poly_t t;1536 1537 if (rop == op)1538 {1539 fmpz_poly_power(rop->num, op->num, 2ul);1540 if (!fmpz_is_one(rop->den))1541 {1542 rop->den = fmpz_realloc(rop->den, 2 * fmpz_size(rop->den));1543 fmpz_pow_ui(rop->den, op->den, 2ul);1544 }1545 return;1546 }1547 1548 if (fmpq_poly_is_zero(rop) || fmpq_poly_is_zero(op))1549 {1550 fmpq_poly_zero(rop);1551 return;1552 }1553 1554 /* From here on, rop and op point to two different objects in memory, */1555 /* and these are both non-zero rational polynomials. */1556 1557 fmpq_poly_init(t);1558 fmpq_poly_mul(t, rop, op);1559 fmpq_poly_swap(rop, t);1560 fmpq_poly_clear(t);1561 }1562 1563 /**1564 * \ingroup Multiplication1565 *1566 * Sets \c rop to the product of \c op1 and \c op2.1567 */1568 void fmpq_poly_mul(fmpq_poly_ptr rop, const fmpq_poly_ptr op1, const fmpq_poly_ptr op2)1569 {1570 fmpz_t gcd1, gcd2;1571 1572 if (op1 == op2)1573 {1574 fmpz_poly_power(rop->num, op1->num, 2ul);1575 if (fmpz_is_one(op1->den))1576 {1577 fmpz_set_ui(rop->den, 1);1578 }1579 else1580 {1581 if (rop == op1)1582 {1583 fmpz_t t;1584 t = fmpz_init(2 * fmpz_size(op1->den));1585 fmpz_pow_ui(t, op1->den, 2ul);1586 fmpz_clear(rop->den); // FIXME Fixed1587 rop->den = t;1588 }1589 else1590 {1591 rop->den = fmpz_realloc(rop->den, 2 * fmpz_size(op1->den));1592 fmpz_pow_ui(rop->den, op1->den, 2ul);1593 }1594 }1595 return;1596 }1597 1598 if (rop == op1)1599 {1600 _fmpq_poly_mul_in_place(rop, op2);1601 return;1602 }1603 if (rop == op2)1604 {1605 _fmpq_poly_mul_in_place(rop, op1);1606 return;1607 }1608 1609 /* From here on, we may assume that rop, op1 and op2 all refer to */1610 /* distinct objects in memory, although they may still be equal. */1611 1612 gcd1 = NULL;1613 gcd2 = NULL;1614 1615 if (!fmpz_is_one(op2->den))1616 {1617 gcd1 = fmpz_init(FLINT_MAX(op1->num->limbs, fmpz_size(op2->den)));1618 fmpz_poly_content(gcd1, op1->num);1619 if (!fmpz_is_one(gcd1))1620 {1621 fmpz_t t;1622 t = fmpz_init(FLINT_MAX(fmpz_size(gcd1), fmpz_size(op2->den)));1623 fmpz_gcd(t, gcd1, op2->den);1624 fmpz_clear(gcd1);1625 gcd1 = t;1626 }1627 }1628 if (!fmpz_is_one(op1->den))1629 {1630 gcd2 = fmpz_init(FLINT_MAX(op2->num->limbs, fmpz_size(op1->den)));1631 fmpz_poly_content(gcd2, op2->num);1632 if (!fmpz_is_one(gcd2))1633 {1634 fmpz_t t;1635 t = fmpz_init(FLINT_MAX(fmpz_size(gcd2), fmpz_size(op1->den)));1636 fmpz_gcd(t, gcd2, op1->den);1637 fmpz_clear(gcd2);1638 gcd2 = t;1639 }1640 }1641 1642 /* TODO: If gcd1 and gcd2 are very large compared to the degrees of */1643 /* poly1 and poly2, we might want to create copies of the polynomials */1644 /* and divide out the common factors *before* the multiplication. */1645 1646 fmpz_poly_mul(rop->num, op1->num, op2->num);1647 rop->den = fmpz_realloc(rop->den, fmpz_size(op1->den)1648 + fmpz_size(op2->den));1649 fmpz_mul(rop->den, op1->den, op2->den);1650 1651 if (gcd1 == NULL || fmpz_is_one(gcd1))1652 {1653 if (gcd2 != NULL && !fmpz_is_one(gcd2))1654 {1655 fmpz_t h;1656 h = fmpz_init(fmpz_size(rop->den));1657 fmpz_poly_scalar_div_fmpz(rop->num, rop->num, gcd2);1658 fmpz_divides(h, rop->den, gcd2);1659 fmpz_clear(rop->den);1660 rop->den = h;1661 }1662 }1663 else1664 {1665 if (gcd2 == NULL || fmpz_is_one(gcd2))1666 {1667 fmpz_t h;1668 h = fmpz_init(fmpz_size(rop->den));1669 fmpz_poly_scalar_div_fmpz(rop->num, rop->num, gcd1);1670 fmpz_divides(h, rop->den, gcd1);1671 fmpz_clear(rop->den);1672 rop->den = h;1673 }1674 else1675 {1676 fmpz_t g, h;1677 g = fmpz_init(fmpz_size(gcd1) + fmpz_size(gcd2));1678 h = fmpz_init(fmpz_size(rop->den));1679 fmpz_mul(g, gcd1, gcd2);1680 fmpz_poly_scalar_div_fmpz(rop->num, rop->num, g);1681 fmpz_divides(h, rop->den, g);1682 fmpz_clear(rop->den);1683 rop->den = h;1684 fmpz_clear(g);1685 }1686 }1687 1688 if (gcd1 != NULL) fmpz_clear(gcd1);1689 if (gcd2 != NULL) fmpz_clear(gcd2);1690 }1691 1692 ///////////////////////////////////////////////////////////////////////////////1693 // Division1694 1695 /**1696 * \ingroup Division1697 *1698 * Returns the quotient of the Euclidean division of \c a by \c b.1699 *1700 * Assumes that \c b is non-zero. Otherwise, an exception is raised in the1701 * form of an <tt>abort</tt> statement.1702 */1703 void fmpq_poly_floordiv(fmpq_poly_ptr q, const fmpq_poly_ptr a, const fmpq_poly_ptr b)1704 {1705 ulong m;1706 fmpz_t lead;1707 1708 /* Assertion! */1709 if (fmpq_poly_is_zero(b))1710 {1711 printf("ERROR (fmpq_poly_floordiv). Division by zero.\n");1712 abort();1713 }1714 1715 /* Catch the case when a and b are the same objects in memory. */1716 /* As of FLINT version 1.5.1, there is a bug in this case. */1717 if (a == b)1718 {1719 fmpq_poly_set_si(q, 1);1720 return;1721 }1722 1723 /* Deal with the various other cases of aliasing. */1724 if (q == a | q == b)1725 {1726 fmpq_poly_t tpoly;1727 fmpq_poly_init(tpoly);1728 fmpq_poly_floordiv(tpoly, a, b);1729 fmpq_poly_swap(q, tpoly);1730 fmpq_poly_clear(tpoly);1731 return;1732 }1733 1734 /* Deal separately with the case deg(b) = 0. */1735 if (fmpq_poly_length(b) == 1ul)1736 {1737 lead = fmpz_poly_get_coeff_ptr(b->num, 0);1738 if (fmpz_is_one(a->den))1739 {1740 if (fmpz_is_one(b->den)) /* a->den == b->den == 1 */1741 fmpz_poly_set(q->num, a->num);1742 else /* a->den == 1, b->den > 1 */1743 fmpz_poly_scalar_mul_fmpz(q->num, a->num, b->den);1744 1745 q->den = fmpz_realloc(q->den, fmpz_size(lead));1746 fmpz_set(q->den, lead);1747 fmpq_poly_canonicalize(q, NULL);1748 }1749 else1750 {1751 if (fmpz_is_one(b->den)) /* a->den > 1, b->den == 1 */1752 fmpz_poly_set(q->num, a->num);1753 else /* a->den, b->den > 1 */1754 fmpz_poly_scalar_mul_fmpz(q->num, a->num, b->den);1755 1756 q->den = fmpz_realloc(q->den, fmpz_size(a->den) + fmpz_size(lead));1757 fmpz_mul(q->den, a->den, lead);1758 fmpq_poly_canonicalize(q, NULL);1759 }1760 return;1761 }1762 1763 /* General case.. */1764 /* Set q to b->den q->num / (a->den lead^m). */1765 1766 /* Since the fmpz_poly_pseudo_div method is broken as of FLINT 1.5.0, we */1767 /* use the fmpz_poly_pseudo_divrem method instead. */1768 /* fmpz_poly_pseudo_div(q->num, &m, a->num, b->num); */1769 {1770 fmpz_poly_t r;1771 fmpz_poly_init(r);1772 fmpz_poly_pseudo_divrem(q->num, r, &m, a->num, b->num);1773 fmpz_poly_clear(r);1774 }1775 1776 lead = fmpz_poly_lead(b->num);1777 1778 if (!fmpz_is_one(b->den))1779 fmpz_poly_scalar_mul_fmpz(q->num, q->num, b->den);1780 1781 /* Case 1: lead^m is 1 */1782 if (fmpz_is_one(lead) || m == 0ul || (fmpz_is_m1(lead) & m % 2 == 0))1783 {1784 q->den = fmpz_realloc(q->den, fmpz_size(a->den));1785 fmpz_set(q->den, a->den);1786 fmpq_poly_canonicalize(q, NULL);1787 }1788 /* Case 2: lead^m is -1 */1789 else if (fmpz_is_m1(lead) & m % 2)1790 {1791 fmpz_poly_neg(q->num, q->num);1792 q->den = fmpz_realloc(q->den, fmpz_size(a->den));1793 fmpz_set(q->den, a->den);1794 fmpq_poly_canonicalize(q, NULL);1795 }1796 /* Case 3: lead^m is not +-1 */1797 else1798 {1799 ulong limbs;1800 limbs = m * fmpz_size(lead);1801 1802 if (fmpz_is_one(a->den))1803 {1804 q->den = fmpz_realloc(q->den, limbs);1805 fmpz_pow_ui(q->den, lead, m);1806 }1807 else1808 {1809 fmpz_t t;1810 t = fmpz_init(limbs);1811 q->den = fmpz_realloc(q->den, limbs + fmpz_size(a->den));1812 fmpz_pow_ui(t, lead, m);1813 fmpz_mul(q->den, t, a->den);1814 fmpz_clear(t);1815 }1816 fmpq_poly_canonicalize(q, NULL);1817 }1818 }1819 1820 /**1821 * \ingroup Division1822 *1823 * Sets \c r to the remainder of the Euclidean division of \c a by \c b.1824 *1825 * Assumes that \c b is non-zero. Otherwise, an exception is raised in the1826 * form of an <tt>abort</tt> statement.1827 */1828 void fmpq_poly_mod(fmpq_poly_ptr r, const fmpq_poly_ptr a, const fmpq_poly_ptr b)1829 {1830 ulong m;1831 fmpz_t lead;1832 1833 /* Assertion! */1834 if (fmpq_poly_is_zero(b))1835 {1836 printf("ERROR (fmpq_poly_mod). Division by zero.\n");1837 abort();1838 }1839 1840 /* Catch the case when a and b are the same objects in memory. */1841 /* As of FLINT version 1.5.1, there is a bug in this case. */1842 if (a == b)1843 {1844 fmpq_poly_set_si(r, 0);1845 return;1846 }1847 1848 /* Deal with the various other cases of aliasing. */1849 if (r == a | r == b)1850 {1851 fmpq_poly_t tpoly;1852 fmpq_poly_init(tpoly);1853 fmpq_poly_mod(tpoly, a, b);1854 fmpq_poly_swap(r, tpoly);1855 fmpq_poly_clear(tpoly);1856 return;1857 }1858 1859 /* Deal separately with the case deg(b) = 0. */1860 if (fmpq_poly_length(b) == 1ul)1861 {1862 fmpz_poly_zero(r->num);1863 fmpz_set_ui(r->den, 1);1864 return;1865 }1866 1867 /* General case.. */1868 /* Set r to r->num / (a->den lead^m). */1869 1870 1871 /* As of FLINT 1.5.0, the fmpz_poly_pseudo_mod method is not */1872 /* asymptotically fast and hence we swap to the fmpz_poly_pseudo_divrem */1873 /* method if one of the operands' lengths is at least 32. */1874 if (fmpq_poly_length(a) < 32 && fmpq_poly_length(b) < 32)1875 fmpz_poly_pseudo_rem(r->num, &m, a->num, b->num);1876 else1877 {1878 fmpz_poly_t q;1879 fmpz_poly_init(q);1880 fmpz_poly_pseudo_divrem(q, r->num, &m, a->num, b->num);1881 fmpz_poly_clear(q);1882 }1883 1884 lead = fmpz_poly_lead(b->num);1885 1886 /* Case 1: lead^m is 1 */1887 if (fmpz_is_one(lead) || m == 0ul || (fmpz_is_m1(lead) & m % 2 == 0))1888 {1889 r->den = fmpz_realloc(r->den, fmpz_size(a->den));1890 fmpz_set(r->den, a->den);1891 }1892 /* Case 2: lead^m is -1 */1893 else if (fmpz_is_m1(lead) & m % 2)1894 {1895 r->den = fmpz_realloc(r->den, fmpz_size(a->den));1896 fmpz_neg(r->den, a->den);1897 }1898 /* Case 3: lead^m is not +-1 */1899 else1900 {1901 ulong limbs;1902 limbs = m * fmpz_size(lead);1903 1904 if (fmpz_is_one(a->den))1905 {1906 r->den = fmpz_realloc(r->den, limbs);1907 fmpz_pow_ui(r->den, lead, m);1908 }1909 else1910 {1911 fmpz_t t;1912 t = fmpz_init(limbs);1913 r->den = fmpz_realloc(r->den, limbs + fmpz_size(a->den));1914 fmpz_pow_ui(t, lead, m);1915 fmpz_mul(r->den, t, a->den);1916 fmpz_clear(t);1917 }1918 }1919 fmpq_poly_canonicalize(r, NULL);1920 }1921 1922 /**1923 * \ingroup Division1924 *1925 * Sets \c q and \c r to the quotient and remainder of the Euclidean1926 * division of \c a by \c b.1927 *1928 * Assumes that \c b is non-zero, and that \c q and \c r refer to distinct1929 * objects in memory.1930 */1931 void fmpq_poly_divrem(fmpq_poly_ptr q, fmpq_poly_ptr r, const fmpq_poly_ptr a, const fmpq_poly_ptr b)1932 {1933 ulong m;1934 fmpz_t lead;1935 1936 /* Assertion! */1937 if (fmpq_poly_is_zero(b))1938 {1939 printf("ERROR (fmpq_poly_divrem). Division by zero.\n");1940 abort();1941 }1942 if (q == r)1943 {1944 printf("ERROR (fmpq_poly_divrem). Output arguments aliased.\n");1945 abort();1946 }1947 1948 /* Catch the case when a and b are the same objects in memory. */1949 /* As of FLINT version 1.5.1, there is a bug in this case. */1950 if (a == b)1951 {1952 fmpq_poly_set_si(q, 1);1953 fmpq_poly_set_si(r, 0);1954 return;1955 }1956 1957 /* Deal with the various other cases of aliasing. */1958 if (r == a | r == b)1959 {1960 if (q == a | q == b)1961 {1962 fmpq_poly_t tempq, tempr;1963 fmpq_poly_init(tempq);1964 fmpq_poly_init(tempr);1965 fmpq_poly_divrem(tempq, tempr, a, b);1966 fmpq_poly_swap(q, tempq);1967 fmpq_poly_swap(r, tempr);1968 fmpq_poly_clear(tempq);1969 fmpq_poly_clear(tempr);1970 return;1971 }1972 else1973 {1974 fmpq_poly_t tempr;1975 fmpq_poly_init(tempr);1976 fmpq_poly_divrem(q, tempr, a, b);1977 fmpq_poly_swap(r, tempr);1978 fmpq_poly_clear(tempr);1979 return;1980 }1981 }1982 else1983 {1984 if (q == a | q == b)1985 {1986 fmpq_poly_t tempq;1987 fmpq_poly_init(tempq);1988 fmpq_poly_divrem(tempq, r, a, b);1989 fmpq_poly_swap(q, tempq);1990 fmpq_poly_clear(tempq);1991 return;1992 }1993 }1994 1995 // TODO: Implement the case `\deg(b) = 0` more efficiently!1996 1997 /* General case.. */1998 /* Set q to b->den q->num / (a->den lead^m) */1999 /* and r to r->num / (a->den lead^m). */2000 2001 fmpz_poly_pseudo_divrem(q->num, r->num, &m, a->num, b->num);2002 2003 lead = fmpz_poly_lead(b->num);2004 2005 if (!fmpz_is_one(b->den))2006 fmpz_poly_scalar_mul_fmpz(q->num, q->num, b->den);2007 2008 /* Case 1. lead^m is 1 */2009 if (fmpz_is_one(lead) || m == 0ul || (fmpz_is_m1(lead) & m % 2 == 0))2010 {2011 q->den = fmpz_realloc(q->den, fmpz_size(a->den));2012 fmpz_set(q->den, a->den);2013 }2014 /* Case 2. lead^m is -1 */2015 else if (fmpz_is_m1(lead) & m % 2)2016 {2017 fmpz_poly_neg(q->num, q->num);2018 q->den = fmpz_realloc(q->den, fmpz_size(a->den));2019 fmpz_set(q->den, a->den);2020 2021 fmpz_poly_neg(r->num, r->num);2022 }2023 /* Case 3. lead^m is not +-1 */2024 else2025 {2026 ulong limbs;2027 limbs = m * fmpz_size(lead);2028 2029 if (fmpz_is_one(a->den))2030 {2031 q->den = fmpz_realloc(q->den, limbs);2032 fmpz_pow_ui(q->den, lead, m);2033 }2034 else2035 {2036 fmpz_t t;2037 t = fmpz_init(limbs);2038 q->den = fmpz_realloc(q->den, limbs + fmpz_size(a->den));2039 fmpz_pow_ui(t, lead, m);2040 fmpz_mul(q->den, t, a->den);2041 fmpz_clear(t);2042 }2043 }2044 r->den = fmpz_realloc(r->den, fmpz_size(q->den));2045 fmpz_set(r->den, q->den);2046 2047 fmpq_poly_canonicalize(q, NULL);2048 fmpq_poly_canonicalize(r, NULL);2049 }2050 2051 ///////////////////////////////////////////////////////////////////////////////2052 // Powering2053 2054 /**2055 * \ingroup Powering2056 *2057 * Sets \c rop to the <tt>exp</tt>th power of \c op.2058 *2059 * The corner case of <tt>exp == 0</tt> is handled by setting \c rop to the2060 * constant function \f$1\f$. Note that this includes the case \f$0^0 = 1\f$.2061 */2062 void fmpq_poly_power(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong exp)2063 {2064 if (exp == 0ul)2065 {2066 fmpq_poly_one(rop);2067 }2068 else2069 {2070 fmpz_poly_power(rop->num, op->num, exp);2071 if (fmpz_is_one(op->den))2072 {2073 fmpz_set_ui(rop->den, 1);2074 }2075 else2076 {2077 if (rop == op)2078 {2079 fmpz_t t;2080 t = fmpz_init(exp * fmpz_size(op->den));2081 fmpz_pow_ui(t, op->den, exp);2082 fmpz_clear(rop->den); // FIXME Fixed2083 rop->den = t;2084 }2085 else2086 {2087 rop->den = fmpz_realloc(rop->den, exp * fmpz_size(op->den));2088 fmpz_pow_ui(rop->den, op->den, exp);2089 }2090 }2091 }2092 }2093 2094 ///////////////////////////////////////////////////////////////////////////////2095 // Greatest common divisor2096 2097 /**2098 * \ingroup GCD2099 *2100 * Returns the (monic) greatest common divisor \c res of \c a and \c b.2101 *2102 * Corner cases: If \c a and \c b are both zero, returns zero. If only2103 * one of them is zero, returns the other polynomial, up to normalisation.2104 */2105 void fmpq_poly_gcd(fmpq_poly_ptr rop, const fmpq_poly_ptr a, const fmpq_poly_ptr b)2106 {2107 fmpz_t lead;2108 fmpz_poly_t num;2109 2110 /* Deal with aliasing */2111 if (rop == a | rop == b)2112 {2113 fmpq_poly_t tpoly;2114 fmpq_poly_init(tpoly);2115 fmpq_poly_gcd(tpoly, a, b);2116 fmpq_poly_swap(rop, tpoly);2117 fmpq_poly_clear(tpoly);2118 return;2119 }2120 2121 /* Deal with corner cases */2122 if (fmpq_poly_is_zero(a))2123 {2124 if (fmpq_poly_is_zero(b)) /* a == b == 0 */2125 fmpq_poly_zero(rop);2126 else /* a == 0, b != 0 */2127 fmpq_poly_monic(rop, b);2128 return;2129 }2130 else2131 {2132 if (fmpq_poly_is_zero(b)) /* a != 0, b == 0 */2133 {2134 fmpq_poly_monic(rop, a);2135 return;2136 }2137 }2138 2139 /* General case.. */2140 fmpz_poly_init(num);2141 fmpz_poly_primitive_part(rop->num, a->num);2142 fmpz_poly_primitive_part(num, b->num);2143 2144 /* Since rop.num is the greatest common divisor of the primitive parts */2145 /* of a.num and b.num, it is also primitive. But as of FLINT 1.4.0, the */2146 /* leading term *might* be negative. */2147 fmpz_poly_gcd(rop->num, rop->num, num);2148 2149 lead = fmpz_poly_lead(rop->num);2150 rop->den = fmpz_realloc(rop->den, fmpz_size(lead));2151 if (fmpz_sgn(lead) < 0)2152 {2153 fmpz_poly_neg(rop->num, rop->num);2154 fmpz_neg(rop->den, lead);2155 }2156 else2157 fmpz_set(rop->den, lead);2158 2159 fmpz_poly_clear(num);2160 }2161 2162 /**2163 * \ingroup GCD2164 *2165 * Returns polynomials \c s, \c t and \c rop such that \c rop is2166 * (monic) greatest common divisor of \c a and \c b, and such that2167 * <tt>rop = s a + t b</tt>.2168 *2169 * Corner cases: If \c a and \c b are zero, returns zero polynomials.2170 * Otherwise, if only \c a is zero, returns <tt>(res, s, t) = (b, 0, 1)</tt>2171 * up to normalisation, and similarly if only \c b is zero.2172 *2173 * Assumes that the output parameters \c rop, \c s, and \c t refer to2174 * distinct objects in memory. Otherwise, an exception is raised in the2175 * form of an <tt>abort</tt> statement.2176 */2177 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)2178 {2179 fmpz_t lead, temp;2180 ulong bound, limbs;2181 2182 /* Assertion! */2183 if (rop == s | rop == t | s == t)2184 {2185 printf("ERROR (fmpq_poly_xgcd). Output arguments aliased.\n");2186 abort();2187 }2188 2189 /* Deal with aliasing */2190 if (rop == a | rop == b)2191 {2192 if (s == a | s == b)2193 {2194 /* We know that t does not coincide with a or b, since otherwise */2195 /* two of rop, s, and t coincide, too. */2196 fmpq_poly_t tempg, temps;2197 fmpq_poly_init(tempg);2198 fmpq_poly_init(temps);2199 fmpq_poly_xgcd(tempg, temps, t, a, b);2200 fmpq_poly_swap(rop, tempg);2201 fmpq_poly_swap(s, temps);2202 fmpq_poly_clear(tempg);2203 fmpq_poly_clear(temps);2204 return;2205 }2206 else2207 {2208 if (t == a | t == b)2209 {2210 fmpq_poly_t tempg, tempt;2211 fmpq_poly_init(tempg);2212 fmpq_poly_init(tempt);2213 fmpq_poly_xgcd(tempg, s, tempt, a, b);2214 fmpq_poly_swap(rop, tempg);2215 fmpq_poly_swap(t, tempt);2216 fmpq_poly_clear(tempg);2217 fmpq_poly_clear(tempt);2218 return;2219 }2220 else2221 {2222 fmpq_poly_t tempg;2223 fmpq_poly_init(tempg);2224 fmpq_poly_xgcd(tempg, s, t, a, b);2225 fmpq_poly_swap(rop, tempg);2226 fmpq_poly_clear(tempg);2227 return;2228 }2229 }2230 }2231 else2232 {2233 if (s == a | s == b)2234 {2235 if (t == a | t == b)2236 {2237 fmpq_poly_t temps, tempt;2238 fmpq_poly_init(temps);2239 fmpq_poly_init(tempt);2240 fmpq_poly_xgcd(rop, temps, tempt, a, b);2241 fmpq_poly_swap(s, temps);2242 fmpq_poly_swap(t, tempt);2243 fmpq_poly_clear(temps);2244 fmpq_poly_clear(tempt);2245 return;2246 }2247 else2248 {2249 fmpq_poly_t temps;2250 fmpq_poly_init(temps);2251 fmpq_poly_xgcd(rop, temps, t, a, b);2252 fmpq_poly_swap(s, temps);2253 fmpq_poly_clear(temps);2254 return;2255 }2256 }2257 else2258 {2259 if (t == a | t == b)2260 {2261 fmpq_poly_t tempt;2262 fmpq_poly_init(tempt);2263 fmpq_poly_xgcd(rop, s, tempt, a, b);2264 fmpq_poly_swap(t, tempt);2265 fmpq_poly_clear(tempt);2266 return;2267 }2268 }2269 }2270 2271 /* From here on, we may assume that none of the output variables are */2272 /* aliases for the input variables. */2273 2274 /* Deal with the following three corner cases: */2275 /* a == 0, b == 0 */2276 /* a == 0, b =! 0 */2277 /* a != 0, b == 0 */2278 if (fmpq_poly_is_zero(a))2279 {2280 if (fmpq_poly_is_zero(b)) /* Case 1. a == b == 0 */2281 {2282 fmpq_poly_zero(rop);2283 fmpq_poly_zero(s);2284 fmpq_poly_zero(t);2285 return;2286 }2287 else /* Case 2. a == 0, b != 0 */2288 {2289 fmpz_t blead = fmpz_poly_lead(b->num);2290 2291 fmpq_poly_monic(rop, b);2292 fmpq_poly_zero(s);2293 2294 fmpz_poly_zero(t->num);2295 fmpz_poly_set_coeff_fmpz(t->num, 0, b->den);2296 if (fmpz_is_one(blead))2297 fmpz_set_ui(t->den, 1);2298 else2299 {2300 fmpz_t g;2301 g = fmpz_init(FLINT_MAX(b->num->limbs, fmpz_size(b->den)));2302 fmpz_gcd(g, blead, b->den);2303 if (fmpz_sgn(g) != fmpz_sgn(blead))2304 fmpz_neg(g, g);2305 fmpz_poly_scalar_div_fmpz(t->num, t->num, g);2306 t->den = fmpz_realloc(t->den, fmpz_size(blead));2307 fmpz_divides(t->den, blead, g);2308 fmpz_clear(g);2309 }2310 return;2311 }2312 }2313 else2314 {2315 if (fmpq_poly_is_zero(b)) /* Case 3. a != 0, b == 0 */2316 {2317 fmpq_poly_xgcd(rop, t, s, b, a);2318 return;2319 }2320 }2321 2322 /* We are now in the general case where a and b are non-zero. */2323 2324 s->den = fmpz_realloc(s->den, a->num->limbs);2325 t->den = fmpz_realloc(t->den, b->num->limbs);2326 fmpz_poly_content(s->den, a->num);2327 fmpz_poly_content(t->den, b->num);2328 fmpz_poly_scalar_div_fmpz(s->num, a->num, s->den);2329 fmpz_poly_scalar_div_fmpz(t->num, b->num, t->den);2330 2331 /* Note that, since s->num and t->num are primitive, rop->num is */2332 /* primitive, too. In fact, it is the rational greatest common divisor */2333 /* of a and b. As of FLINT 1.4.0, the leading coefficient of res.num */2334 /* *might* be negative. */2335 2336 fmpz_poly_gcd(rop->num, s->num, t->num);2337 if (fmpz_sgn(fmpz_poly_lead(rop->num)) < 0)2338 fmpz_poly_neg(rop->num, rop->num);2339 lead = fmpz_poly_lead(rop->num);2340 2341 /* Now rop->num is a (primitive) rational greatest common divisor of */2342 /* a and b. */2343 2344 if (fmpz_poly_degree(rop->num) > 0)2345 {2346 fmpz_poly_div(s->num, s->num, rop->num);2347 fmpz_poly_div(t->num, t->num, rop->num);2348 }2349 2350 bound = fmpz_poly_resultant_bound(s->num, t->num);2351 if (fmpz_is_one(lead))2352 bound = bound / FLINT_BITS + 2;2353 else2354 bound = FLINT_MAX(bound / FLINT_BITS + 2, fmpz_size(lead));2355 rop->den = fmpz_realloc(rop->den, bound);2356 2357 fmpz_poly_xgcd(rop->den, s->num, t->num, s->num, t->num);2358 2359 /* Now the following equation holds: */2360 /* rop->den rop->num == */2361 /* (s->num a->den / s->den) a + (t->num b->den / t->den) b. */2362 2363 limbs = FLINT_MAX(s->num->limbs, t->num->limbs);2364 limbs = FLINT_MAX(limbs, fmpz_size(s->den));2365 limbs = FLINT_MAX(limbs, fmpz_size(t->den) + fmpz_size(rop->den) + fmpz_size(lead));2366 temp = fmpz_init(limbs);2367 2368 s->den = fmpz_realloc(s->den, fmpz_size(s->den) + fmpz_size(rop->den)2369 + fmpz_size(lead));2370 if (!fmpz_is_one(a->den))2371 fmpz_poly_scalar_mul_fmpz(s->num, s->num, a->den);2372 fmpz_mul(temp, s->den, rop->den);2373 fmpz_mul(s->den, temp, lead);2374 2375 t->den = fmpz_realloc(t->den, fmpz_size(t->den) + fmpz_size(rop->den)2376 + fmpz_size(lead));2377 if (!fmpz_is_one(b->den))2378 fmpz_poly_scalar_mul_fmpz(t->num, t->num, b->den);2379 fmpz_mul(temp, t->den, rop->den);2380 fmpz_mul(t->den, temp, lead);2381 2382 fmpq_poly_canonicalize(s, temp);2383 fmpq_poly_canonicalize(t, temp);2384 2385 fmpz_set(rop->den, lead);2386 2387 fmpz_clear(temp);2388 }2389 2390 /**2391 * \ingroup GCD2392 *2393 * Computes the monic (or zero) least common multiple of \c a and \c b.2394 *2395 * If either of \c a and \c b is zero, returns zero. This behaviour ensures2396 * that the relation2397 * \f[2398 * \text{lcm}(a,b) \gcd(a,b) \sim a b2399 * \f]2400 * holds, where \f$\sim\f$ denotes equality up to units.2401 */2402 void fmpq_poly_lcm(fmpq_poly_ptr rop, const fmpq_poly_ptr a, const fmpq_poly_ptr b)2403 {2404 /* Handle aliasing */2405 if (rop == a | rop == b)2406 {2407 fmpq_poly_t tpoly;2408 fmpq_poly_init(tpoly);2409 fmpq_poly_lcm(tpoly, a, b);2410 fmpq_poly_swap(rop, tpoly);2411 fmpq_poly_clear(tpoly);2412 return;2413 }2414 2415 if (fmpq_poly_is_zero(a))2416 fmpq_poly_zero(rop);2417 else if (fmpq_poly_is_zero(b))2418 fmpq_poly_zero(rop);2419 else2420 {2421 fmpz_poly_t prod;2422 fmpz_t lead;2423 2424 fmpz_poly_init(prod);2425 fmpq_poly_gcd(rop, a, b);2426 fmpz_poly_mul(prod, a->num, b->num);2427 fmpz_poly_primitive_part(prod, prod);2428 fmpz_poly_div(rop->num, prod, rop->num);2429 2430 /* Note that GCD returns a monic rop and so a primitive rop.num. */2431 /* Dividing the primitive prod by this yields a primitive quotient */2432 /* rop->num. */2433 2434 lead = fmpz_poly_lead(rop->num);2435 rop->den = fmpz_realloc(rop->den, fmpz_size(lead));2436 if (fmpz_sgn(lead) < 0)2437 fmpz_poly_neg(rop->num, rop->num);2438 fmpz_set(rop->den, fmpz_poly_lead(rop->num));2439 2440 fmpz_poly_clear(prod);2441 }2442 }2443 2444 ///////////////////////////////////////////////////////////////////////////////2445 // Derivative2446 2447 /**2448 * \ingroup Derivative2449 *2450 * Sets \c rop to the derivative of \c op.2451 *2452 * \todo The second argument should be declared \c const, but as of2453 * FLINT 1.5.0 this generates a compile-time warning.2454 */2455 void fmpq_poly_derivative(fmpq_poly_ptr rop, fmpq_poly_ptr op)2456 {2457 if (fmpq_poly_length(op) < 2ul)2458 fmpq_poly_zero(rop);2459 else2460 {2461 fmpz_poly_derivative(rop->num, op->num);2462 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den));2463 fmpz_set(rop->den, op->den);2464 fmpq_poly_canonicalize(rop, NULL);2465 }2466 }2467 2468 ///////////////////////////////////////////////////////////////////////////////2469 // Evaluation2470 2471 /**2472 * \ingroup Evaluation2473 *2474 * Evaluates the integer polynomial \c f at the rational \c a using Horner's2475 * method.2476 */2477 void _fmpz_poly_evaluate_mpq_horner(mpq_t rop, const fmpz_poly_t f, const mpq_t a)2478 {2479 mpq_t temp;2480 ulong n;2481 2482 /* Handle aliasing */2483 if (rop == a)2484 {2485 mpq_t tempr;2486 mpq_init(tempr);2487 _fmpz_poly_evaluate_mpq_horner(tempr, f, a);2488 mpq_swap(rop, tempr);2489 mpq_clear(tempr);2490 return;2491 }2492 2493 n = fmpz_poly_length(f);2494 2495 if (n == 0ul)2496 {2497 mpq_set_ui(rop, 0, 1);2498 }2499 else if (n == 1ul)2500 {2501 fmpz_poly_get_coeff_mpz(mpq_numref(rop), f, 0);2502 mpz_set_ui(mpq_denref(rop), 1);2503 }2504 else2505 {2506 n--;2507 fmpz_poly_get_coeff_mpz(mpq_numref(rop), f, n);2508 mpz_set_ui(mpq_denref(rop), 1);2509 mpq_init(temp);2510 do {2511 n--;2512 mpq_mul(temp, rop, a);2513 fmpz_poly_get_coeff_mpz(mpq_numref(rop), f, n);2514 mpz_set_ui(mpq_denref(rop), 1);2515 mpq_add(rop, rop, temp);2516 } while (n);2517 mpq_clear(temp);2518 }2519 }2520 2521 /**2522 * \ingroup Evaluation2523 *2524 * Evaluates the rational polynomial \c f at the integer \c a.2525 *2526 * Assumes that the numerator and denominator of the <tt>mpq_t</tt>2527 * \c rop are distinct (as objects in memory) from the <tt>mpz_t</tt>2528 * \c a.2529 */2530 void fmpq_poly_evaluate_mpz(mpq_t rop, fmpq_poly_ptr f, const mpz_t a)2531 {2532 fmpz_t num, t;2533 ulong limbs, max;2534 2535 if (fmpq_poly_is_zero(f))2536 {2537 mpq_set_ui(rop, 0, 1);2538 return;2539 }2540 2541 /* Establish a bound on the size of f->num evaluated at a */2542 max = (f->num->length) * (f->num->limbs + f->num->length * mpz_size(a));2543 2544 /* Compute the result */2545 num = fmpz_init(max);2546 t = fmpz_init(mpz_size(a));2547 mpz_to_fmpz(t, a);2548 fmpz_poly_evaluate(num, f->num, t);2549 fmpz_to_mpz(mpq_numref(rop), num);2550 if (fmpz_is_one(f->den))2551 {2552 mpz_set_ui(mpq_denref(rop), 1);2553 }2554 else2555 {2556 fmpz_to_mpz(mpq_denref(rop), f->den);2557 mpq_canonicalize(rop);2558 }2559 2560 fmpz_clear(num);2561 fmpz_clear(t);2562 }2563 2564 /**2565 * \ingroup Evaluation2566 *2567 * Evaluates the rational polynomial \c f at the rational \c a.2568 */2569 void fmpq_poly_evaluate_mpq(mpq_t rop, fmpq_poly_ptr f, const mpq_t a)2570 {2571 if (rop == a)2572 {2573 mpq_t tempr;2574 mpq_init(tempr);2575 fmpq_poly_evaluate_mpq(tempr, f, a);2576 mpq_swap(rop, tempr);2577 mpq_clear(tempr);2578 return;2579 }2580 2581 _fmpz_poly_evaluate_mpq_horner(rop, f->num, a);2582 if (!fmpz_is_one(f->den))2583 {2584 mpz_t den;2585 mpz_init(den);2586 fmpz_to_mpz(den, f->den);2587 mpz_mul(mpq_denref(rop), mpq_denref(rop), den);2588 mpq_canonicalize(rop);2589 mpz_clear(den);2590 }2591 }2592 2593 ///////////////////////////////////////////////////////////////////////////////2594 // Gaussian content2595 2596 /**2597 * \ingroup Content2598 *2599 * Returns the non-negative content of \c op.2600 *2601 * The content of \f$0\f$ is defined to be \f$0\f$.2602 */2603 void fmpq_poly_content(mpq_t rop, const fmpq_poly_ptr op)2604 {2605 fmpz_t numc;2606 2607 numc = fmpz_init(op->num->limbs);2608 fmpz_poly_content(numc, op->num);2609 fmpz_abs(numc, numc);2610 fmpz_to_mpz(mpq_numref(rop), numc);2611 if (fmpz_is_one(op->den))2612 mpz_set_ui(mpq_denref(rop), 1);2613 else2614 fmpz_to_mpz(mpq_denref(rop), op->den);2615 fmpz_clear(numc);2616 }2617 2618 /**2619 * \ingroup Content2620 *2621 * Returns the primitive part (with non-negative leading coefficient) of2622 * \c op as an element of type #fmpq_poly_t.2623 */2624 void fmpq_poly_primitive_part(fmpq_poly_ptr rop, const fmpq_poly_ptr op)2625 {2626 if (fmpq_poly_is_zero(op))2627 fmpq_poly_zero(rop);2628 else2629 {2630 fmpz_poly_primitive_part(rop->num, op->num);2631 if (fmpz_sgn(fmpz_poly_lead(rop->num)) < 0)2632 fmpz_poly_neg(rop->num, rop->num);2633 fmpz_set_ui(rop->den, 1);2634 }2635 }2636 2637 /**2638 * \brief Returns whether \c op is monic.2639 * \ingroup Content2640 *2641 * Returns whether \c op is monic.2642 *2643 * By definition, the zero polynomial is \e not monic.2644 */2645 int fmpq_poly_is_monic(const fmpq_poly_ptr op)2646 {2647 fmpz_t lead;2648 2649 if (fmpq_poly_is_zero(op))2650 return 0;2651 else2652 {2653 lead = fmpz_poly_lead(op->num);2654 if (fmpz_is_one(op->den))2655 return fmpz_is_one(lead);2656 else2657 return (fmpz_sgn(lead) > 0) && (fmpz_cmpabs(lead, op->den) == 0);2658 }2659 }2660 2661 /**2662 * Sets \c rop to the unique monic scalar multiple of \c op.2663 *2664 * As the only special case, if \c op is the zero polynomial, \c rop is set2665 * to zero, too.2666 */2667 void fmpq_poly_monic(fmpq_poly_ptr rop, const fmpq_poly_ptr op)2668 {2669 fmpz_t lead;2670 2671 if (fmpq_poly_is_zero(op))2672 {2673 fmpq_poly_zero(rop);2674 return;2675 }2676 2677 fmpz_poly_primitive_part(rop->num, op->num);2678 lead = fmpz_poly_lead(rop->num);2679 rop->den = fmpz_realloc(rop->den, fmpz_size(lead));2680 if (fmpz_sgn(lead) < 0)2681 fmpz_poly_neg(rop->num, rop->num);2682 fmpz_set(rop->den, fmpz_poly_lead(rop->num));2683 }2684 2685 ///////////////////////////////////////////////////////////////////////////////2686 // Resultant2687 2688 /**2689 * \brief Returns the resultant of \c a and \c b.2690 * \ingroup Resultant2691 *2692 * Returns the resultant of \c a and \c b.2693 *2694 * Enumerating the roots of \c a and \c b over \f$\bar{\mathbf{Q}}\f$ as2695 * \f$r_1, \dotsc, r_m\f$ and \f$s_1, \dotsc, s_n\f$, respectively, and2696 * letting \f$x\f$ and \f$y\f$ denote the leading coefficients, the resultant2697 * is defined as2698 * \f[2699 * x^{\deg(b)} y^{\deg(a)} \prod_{1 \leq i, j \leq n} (r_i - s_j).2700 * \f]2701 *2702 * We handle special cases as follows: if one of the polynomials is zero,2703 * the resultant is zero. Note that otherwise if one of the polynomials is2704 * constant, the last term in the above expression is the empty product.2705 */2706 void fmpq_poly_resultant(mpq_t rop, const fmpq_poly_ptr a, const fmpq_poly_ptr b)2707 {2708 fmpz_t rest, t1, t2;2709 fmpz_poly_t anum, bnum;2710 fmpz_t acont, bcont;2711 long d1, d2;2712 ulong bound, denbound, numbound;2713 fmpz_poly_t g;2714 2715 d1 = fmpq_poly_degree(a);2716 d2 = fmpq_poly_degree(b);2717 2718 /* We first handle special cases. */2719 if (d1 < 0l | d2 < 0l)2720 {2721 mpq_set_ui(rop, 0, 1);2722 return;2723 }2724 if (d1 == 0l)2725 {2726 if (d2 == 0l)2727 mpq_set_ui(rop, 1, 1);2728 else if (d2 == 1l)2729 {2730 fmpz_to_mpz(mpq_numref(rop), fmpz_poly_lead(a->num));2731 fmpz_to_mpz(mpq_denref(rop), a->den);2732 }2733 else2734 {2735 if (fmpz_is_one(a->den))2736 bound = a->num->limbs;2737 else2738 bound = FLINT_MAX(a->num->limbs, fmpz_size(a->den));2739 t1 = fmpz_init(d2 * bound);2740 fmpz_pow_ui(t1, fmpz_poly_lead(a->num), d2);2741 fmpz_to_mpz(mpq_numref(rop), t1);2742 if (fmpz_is_one(a->den))2743 mpz_set_ui(mpq_denref(rop), 1);2744 else2745 {2746 fmpz_pow_ui(t1, a->den, d2);2747 fmpz_to_mpz(mpq_denref(rop), t1);2748 }2749 fmpz_clear(t1);2750 }2751 return;2752 }2753 if (d2 == 0l)2754 {2755 fmpq_poly_resultant(rop, b, a);2756 return;2757 }2758 2759 /* We are now in the general case, with both polynomials of degree at */2760 /* least 1. */2761 2762 /* We set a->num =: acont anum with acont > 0 and anum primitive. */2763 acont = fmpz_init(a->num->limbs);2764 fmpz_poly_content(acont, a->num);2765 fmpz_abs(acont, acont);2766 fmpz_poly_init(anum);2767 fmpz_poly_scalar_div_fmpz(anum, a->num, acont);2768 2769 /* We set b->num =: bcont bnum with bcont > 0 and bnum primitive. */2770 bcont = fmpz_init(b->num->limbs);2771 fmpz_poly_content(bcont, b->num);2772 fmpz_abs(bcont, bcont);2773 fmpz_poly_init(bnum);2774 fmpz_poly_scalar_div_fmpz(bnum, b->num, bcont);2775 2776 fmpz_poly_init(g);2777 fmpz_poly_gcd(g, anum, bnum);2778 2779 /* If the gcd has positive degree, the resultant is zero. */2780 if (fmpz_poly_degree(g) > 0)2781 {2782 mpq_set_ui(rop, 0, 1);2783 2784 /* Clean up */2785 fmpz_clear(acont);2786 fmpz_clear(bcont);2787 fmpz_poly_clear(anum);2788 fmpz_poly_clear(bnum);2789 fmpz_poly_clear(g);2790 return;2791 }2792 2793 /* Set some bounds */2794 if (fmpz_is_one(a->den))2795 {2796 if (fmpz_is_one(b->den))2797 {2798 numbound = FLINT_MAX(d2 * fmpz_size(acont), d1 * fmpz_size(bcont));2799 denbound = 1;2800 }2801 else2802 {2803 numbound = FLINT_MAX(d2 * fmpz_size(acont), d1 * fmpz_size(bcont));2804 denbound = d1 * fmpz_size(b->den);2805 }2806 }2807 else2808 {2809 if (fmpz_is_one(b->den))2810 {2811 numbound = FLINT_MAX(d2 * fmpz_size(acont), d1 * fmpz_size(bcont));2812 denbound = d2 * fmpz_size(a->den);2813 }2814 else2815 {2816 numbound = FLINT_MAX(d2 * fmpz_size(acont), d1 * fmpz_size(bcont));2817 denbound = FLINT_MAX(d2 * fmpz_size(a->den), d1 * fmpz_size(b->den));2818 }2819 }2820 2821 /* Now anum and bnum are coprime and we compute their resultant using */2822 /* the method from the fmpz_poly module. */2823 bound = fmpz_poly_resultant_bound(anum, bnum);2824 bound = bound/FLINT_BITS + 2 + d2 * fmpz_size(acont)2825 + d1 * fmpz_size(bcont);2826 rest = fmpz_init(FLINT_MAX(bound, denbound));2827 fmpz_poly_resultant(rest, anum, bnum);2828 2829 /* Finally, w take into account the factors acont/a.den and bcont/b.den. */2830 t1 = fmpz_init(FLINT_MAX(bound, denbound));2831 t2 = fmpz_init(FLINT_MAX(numbound, denbound));2832 2833 if (!fmpz_is_one(acont))2834 {2835 fmpz_pow_ui(t2, acont, d2);2836 fmpz_set(t1, rest);2837 fmpz_mul(rest, t1, t2);2838 }2839 if (!fmpz_is_one(bcont))2840 {2841 fmpz_pow_ui(t2, bcont, d1);2842 fmpz_set(t1, rest);2843 fmpz_mul(rest, t1, t2);2844 }2845 2846 fmpz_to_mpz(mpq_numref(rop), rest);2847 2848 if (fmpz_is_one(a->den))2849 {2850 if (fmpz_is_one(b->den))2851 fmpz_set_ui(rest, 1);2852 else2853 fmpz_pow_ui(rest, b->den, d1);2854 }2855 else2856 {2857 if (fmpz_is_one(b->den))2858 fmpz_pow_ui(rest, a->den, d2);2859 else2860 {2861 fmpz_pow_ui(t1, a->den, d2);2862 fmpz_pow_ui(t2, b->den, d1);2863 fmpz_mul(rest, t1, t2);2864 }2865 }2866 2867 fmpz_to_mpz(mpq_denref(rop), rest);2868 mpq_canonicalize(rop);2869 2870 /* Clean up */2871 fmpz_clear(rest);2872 fmpz_clear(t1);2873 fmpz_clear(t2);2874 fmpz_poly_clear(anum);2875 fmpz_poly_clear(bnum);2876 fmpz_clear(acont);2877 fmpz_clear(bcont);2878 fmpz_poly_clear(g);2879 }2880 2881 /**2882 * \brief Computes the discriminant of \c a.2883 * \ingroup Discriminant2884 *2885 * Computes the discriminant of the polynomial \f$a\f$.2886 *2887 * The discriminant \f$R_n\f$ is defined as2888 * \f[2889 * R_n = a_n^{2 n-2} \prod_{1 \le i < j \le n} (r_i - r_j)^2,2890 * \f]2891 * where \f$n\f$ is the degree of this polynomial, \f$a_n\f$ is the leading2892 * coefficient and \f$r_1, \ldots, r_n\f$ are the roots over2893 * \f$\bar{\mathbf{Q}}\f$ are.2894 *2895 * The discriminant of constant polynomials is defined to be \f$0\f$.2896 *2897 * This implementation uses the identity2898 * \f[2899 * R_n(f) := (-1)^(n (n-1)/2) R(f,f') / a_n,2900 * \f]2901 * where \f$n\f$ is the degree of this polynomial, \f$a_n\f$ is the leading2902 * coefficient and \f$f'\f$ is the derivative of \f$f\f$.2903 *2904 * \see #fmpq_poly_resultant()2905 */2906 void fmpq_poly_discriminant(mpq_t disc, fmpq_poly_t a)2907 {2908 fmpq_poly_t der;2909 mpq_t t;2910 long n;2911 2912 n = fmpq_poly_degree(a);2913 if (n < 1L)2914 {2915 mpq_set_ui(disc, 0, 1);2916 return;2917 }2918 2919 fmpq_poly_init(der);2920 fmpq_poly_derivative(der, a);2921 fmpq_poly_resultant(disc, a, der);2922 mpq_init(t);2923 2924 fmpz_to_mpz(mpq_numref(t), a->den);2925 fmpz_to_mpz(mpq_denref(t), fmpz_poly_lead(a->num));2926 mpq_canonicalize(t);2927 mpq_mul(disc, disc, t);2928 2929 if (n % 4 > 1)2930 mpz_neg(mpq_numref(disc), mpq_numref(disc));2931 2932 fmpq_poly_clear(der);2933 mpq_clear(t);2934 }2935 2936 ///////////////////////////////////////////////////////////////////////////////2937 // Composition2938 2939 /**2940 * \brief Returns the composition of \c a and \c b.2941 * \ingroup Composition2942 *2943 * Returns the composition of \c a and \c b.2944 *2945 * To be clear about the order of the composition, denoting the polynomials2946 * \f$a(T)\f$ and \f$b(T)\f$, returns the polynomial \f$a(b(T))\f$.2947 */2948 void fmpq_poly_compose(fmpq_poly_ptr rop, const fmpq_poly_ptr a, const fmpq_poly_ptr b)2949 {2950 mpq_t x; /* Rational to hold the inverse of b->den */2951 2952 if (fmpz_is_one(b->den))2953 {2954 fmpz_poly_compose(rop->num, a->num, b->num);2955 rop->den = fmpz_realloc(rop->den, fmpz_size(a->den));2956 fmpz_set(rop->den, a->den);2957 fmpq_poly_canonicalize(rop, NULL);2958 return;2959 }2960 2961 /* Aliasing. */2962 /* */2963 /* Note that rop and a, as well as a and b may be aliased, but rop and */2964 /* b may not be aliased. */2965 if (rop == b)2966 {2967 fmpq_poly_t tempr;2968 fmpq_poly_init(tempr);2969 fmpq_poly_compose(tempr, a, b);2970 fmpq_poly_swap(rop, tempr);2971 fmpq_poly_clear(tempr);2972 return;2973 }2974 2975 /* Set x = 1/b.den, and note this is already in canonical form. */2976 mpq_init(x);2977 mpz_set_ui(mpq_numref(x), 1);2978 fmpz_to_mpz(mpq_denref(x), b->den);2979 2980 /* First set rop = a(T / b.den) and then use FLINT's composition to */2981 /* set rop->num = rop->num(b->num). */2982 fmpq_poly_rescale(rop, a, x);2983 fmpz_poly_compose(rop->num, rop->num, b->num);2984 fmpq_poly_canonicalize(rop, NULL);2985 2986 mpq_clear(x);2987 }2988 2989 /**2990 * \brief Rescales the co-ordinate.2991 * \ingroup Composition2992 *2993 * Denoting this polynomial \f$a(T)\f$, computes the polynomial \f$a(x T)\f$.2994 */2995 void fmpq_poly_rescale(fmpq_poly_ptr rop, const fmpq_poly_ptr op, const mpq_t x)2996 {2997 ulong numsize, densize;2998 ulong limbs;2999 fmpz_t num, den;3000 fmpz_t coeff, power, t;3001 long i, n;3002 3003 fmpq_poly_set(rop, op);3004 3005 if (fmpq_poly_length(rop) < 2ul)3006 return;3007 3008 num = fmpz_init(mpz_size(mpq_numref(x)));3009 den = fmpz_init(mpz_size(mpq_denref(x)));3010 mpz_to_fmpz(num, mpq_numref(x));3011 mpz_to_fmpz(den, mpq_denref(x));3012 numsize = fmpz_size(num);3013 densize = fmpz_size(den);3014 3015 n = fmpz_poly_degree(rop->num);3016 3017 if (fmpz_is_one(den))3018 {3019 coeff = fmpz_init(rop->num->limbs + n * numsize);3020 power = fmpz_init(n * numsize);3021 t = fmpz_init(rop->num->limbs + n * numsize);3022 3023 fmpz_set(power, num);3024 3025 fmpz_poly_get_coeff_fmpz(t, rop->num, 1);3026 fmpz_mul(coeff, t, power);3027 fmpz_poly_set_coeff_fmpz(rop->num, 1, coeff);3028 3029 for (i = 2; i <= n; i++)3030 {3031 fmpz_set(t, power);3032 fmpz_mul(power, t, num);3033 fmpz_poly_get_coeff_fmpz(t, rop->num, i);3034 fmpz_mul(coeff, t, power);3035 fmpz_poly_set_coeff_fmpz(rop->num, i, coeff);3036 }3037 }3038 else3039 {3040 coeff = fmpz_init(rop->num->limbs + n * (numsize + densize));3041 power = fmpz_init(n * (numsize + densize));3042 limbs = rop->num->limbs + n * (numsize + densize);3043 limbs = FLINT_MAX(limbs, fmpz_size(rop->den));3044 t = fmpz_init(limbs);3045 3046 fmpz_pow_ui(power, den, n);3047 3048 if (fmpz_is_one(rop->den))3049 {3050 rop->den = fmpz_realloc(rop->den, n * densize);3051 fmpz_set(rop->den, power);3052 }3053 else3054 {3055 fmpz_set(t, rop->den);3056 limbs = n * densize + fmpz_size(rop->den);3057 rop->den = fmpz_realloc(rop->den, limbs);3058 fmpz_mul(rop->den, power, t);3059 }3060 3061 fmpz_set_ui(power, 1);3062 for (i = n - 1; i >= 0; i--)3063 {3064 fmpz_set(t, power);3065 fmpz_mul(power, t, den);3066 fmpz_poly_get_coeff_fmpz(t, rop->num, i);3067 fmpz_mul(coeff, t, power);3068 fmpz_poly_set_coeff_fmpz(rop->num, i, coeff);3069 }3070 3071 fmpz_set_ui(power, 1);3072 for (i = 1; i <= n; i++)3073 {3074 fmpz_set(t, power);3075 fmpz_mul(power, t, num);3076 fmpz_poly_get_coeff_fmpz(t, rop->num, i);3077 fmpz_mul(coeff, t, power);3078 fmpz_poly_set_coeff_fmpz(rop->num, i, coeff);3079 }3080 }3081 fmpq_poly_canonicalize(rop, NULL);3082 fmpz_clear(num);3083 fmpz_clear(den);3084 fmpz_clear(coeff);3085 fmpz_clear(power);3086 fmpz_clear(t);3087 }3088 3089 ///////////////////////////////////////////////////////////////////////////////3090 // Square-free3091 3092 /**3093 * \brief Returns whether \c op is squarefree.3094 * \ingroup Squarefree3095 *3096 * Returns whether \c op is squarefree.3097 *3098 * By definition, a polynomial is square-free if it is not a multiple of a3099 * non-unit factor. In particular, polynomials up to degree 1 (including)3100 * are square-free.3101 */3102 int fmpq_poly_is_squarefree(const fmpq_poly_ptr op)3103 {3104 if (fmpq_poly_length(op) < 3ul)3105 return 1;3106 else3107 {3108 int ans;3109 fmpz_poly_t prim;3110 3111 fmpz_poly_init(prim);3112 fmpz_poly_primitive_part(prim, op->num);3113 ans = fmpz_poly_is_squarefree(prim);3114 fmpz_poly_clear(prim);3115 return ans;3116 }3117 }3118 3119 ///////////////////////////////////////////////////////////////////////////////3120 // Subpolynomials3121 3122 /**3123 * \brief Returns a contiguous subpolynomial.3124 * \ingroup Subpolynomials3125 *3126 * Returns the slice with coefficients from \f$x^i\f$ (including) to3127 * \f$x^j\f$ (excluding).3128 */3129 void fmpq_poly_getslice(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong i, ulong j)3130 {3131 ulong k;3132 3133 j = FLINT_MIN(fmpq_poly_length(op), j);3134 3135 /* Aliasing */3136 if (rop == op)3137 {3138 for (k = 0; k < i; k++)3139 fmpz_poly_set_coeff_ui(rop->num, k, 0);3140 for (k = j; k < fmpz_poly_length(rop->num); k++)3141 fmpz_poly_set_coeff_ui(rop->num, k, 0);3142 fmpq_poly_canonicalize(rop, NULL);3143 return;3144 }3145 3146 fmpz_poly_zero(rop->num);3147 if (i < j)3148 {3149 for (k = j; k != i; )3150 {3151 k--;3152 fmpz_poly_set_coeff_fmpz(rop->num, k,3153 fmpz_poly_get_coeff_ptr(op->num, k));3154 }3155 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den));3156 fmpz_set(rop->den, op->den);3157 fmpq_poly_canonicalize(rop, NULL);3158 }3159 else3160 {3161 fmpz_set_ui(rop->den, 1);3162 }3163 }3164 3165 /**3166 * \brief Shifts this polynomial to the left by \f$n\f$ coefficients.3167 * \ingroup Subpolynomials3168 *3169 * Notionally multiplies \c op by \f$t^n\f$ and stores the result in \c rop.3170 */3171 void fmpq_poly_left_shift(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong n)3172 {3173 /* XXX: As a workaround for a bug in FLINT 1.5.1, we need to handle */3174 /* the zero polynomial separately. */3175 if (fmpq_poly_is_zero(op))3176 {3177 fmpq_poly_zero(rop);3178 return;3179 }3180 3181 if (n == 0ul)3182 {3183 fmpq_poly_set(rop, op);3184 return;3185 }3186 3187 fmpz_poly_left_shift(rop->num, op->num, n);3188 if (rop != op)3189 {3190 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den));3191 fmpz_set(rop->den, op->den);3192 }3193 }3194 3195 /**3196 * \brief Shifts this polynomial to the right by \f$n\f$ coefficients.3197 * \ingroup Subpolynomials3198 *3199 * Notationally returns the quotient of floor division of \c rop by \c op.3200 */3201 void fmpq_poly_right_shift(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong n)3202 {3203 /* XXX: As a workaround for a bug in FLINT 1.5.1, we need to handle */3204 /* the zero polynomial separately. */3205 if (fmpq_poly_is_zero(op))3206 {3207 fmpq_poly_zero(rop);3208 return;3209 }3210 3211 if (n == 0ul)3212 {3213 fmpq_poly_set(rop, op);3214 return;3215 }3216 3217 fmpz_poly_right_shift(rop->num, op->num, n);3218 if (rop != op)3219 {3220 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den));3221 fmpz_set(rop->den, op->den);3222 }3223 fmpq_poly_canonicalize(rop, NULL);3224 }3225 3226 /**3227 * \brief Truncates this polynomials.3228 * \ingroup Subpolynomials3229 *3230 * Truncates <tt>op</tt> modulo \f$x^n\f$ whenever \f$n\f$ is positive.3231 * Returns zero otherwise.3232 */3233 void fmpq_poly_truncate(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong n)3234 {3235 fmpq_poly_set(rop, op);3236 if (fmpq_poly_length(rop) > n)3237 {3238 fmpz_poly_truncate(rop->num, n);3239 fmpq_poly_canonicalize(rop, NULL);3240 }3241 }3242 3243 /**3244 * \brief Reverses this polynomial.3245 * \ingroup Subpolynomials3246 *3247 * Reverses the coefficients of \c op - thought of as a polynomial of3248 * length \c n - and places the result in <tt>rop</tt>.3249 */3250 void fmpq_poly_reverse(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong n)3251 {3252 ulong len;3253 len = fmpq_poly_length(op);3254 3255 if (n == 0ul || len == 0ul)3256 {3257 fmpq_poly_zero(rop);3258 return;3259 }3260 3261 fmpz_poly_reverse(rop->num, op->num, n);3262 if (rop != op)3263 {3264 rop->den = fmpz_realloc(rop->den, fmpz_size(op->den));3265 fmpz_set(rop->den, op->den);3266 }3267 3268 if (n < len)3269 fmpq_poly_canonicalize(rop, NULL);3270 }3271 3272 ///////////////////////////////////////////////////////////////////////////////3273 // String conversion3274 3275 /**3276 * \addtogroup StringConversions3277 *3278 * The following three methods enable users to construct elements of type3279 * \c fmpq_poly_ptr from strings or to obtain string representations of such3280 * elements.3281 *3282 * The format used is based on the FLINT format for integer polynomials of3283 * type <tt>fmpz_poly_t</tt>, which we recall first:3284 *3285 * A non-zero polynomial \f$a_0 + a_1 X + \dotsb + a_n X^n\f$ of length3286 * \f$n + 1\f$ is represented by the string <tt>n+1 a_0 a_1 ... a_n</tt>,3287 * where there are two space characters following the length and single space3288 * characters separating the individual coefficients. There is no leading or3289 * trailing white-space. In contrast, the zero polynomial is represented by3290 * <tt>0</tt>.3291 *3292 * We adapt this notation for rational polynomials by using the <tt>mpq_t</tt>3293 * notation for the coefficients without any additional white-space.3294 *3295 * There is also a <tt>_pretty</tt> variant available.3296 *3297 * Note that currently these functions are not optimized for performance and3298 * are intended to be used only for debugging purposes or one-off input and3299 * output, rather than as a low-level parser.3300 */3301 3302 /**3303 * \ingroup StringConversions3304 * \brief Constructs a polynomial from a list of rationals.3305 *3306 * Given a list of length <tt>n</tt> containing rationals of type3307 * <tt>mpq_t</tt>, this method constructs a polynomial with these3308 * coefficients, beginning with the constant term.3309 */3310 void _fmpq_poly_from_list(fmpq_poly_ptr rop, mpq_t * a, ulong n)3311 {3312 mpz_t den, t;3313 ulong i;3314 3315 mpz_init(t);3316 mpz_init_set_ui(den, 1);3317 for (i = 0; i < n; i++)3318 mpz_lcm(den, den, mpq_denref(a[i]));3319 3320 for (i = 0; i < n; i++)3321 {3322 mpz_divexact(t, den, mpq_denref(a[i]));3323 mpz_mul(mpq_numref(a[i]), mpq_numref(a[i]), t);3324 }3325 3326 fmpz_poly_realloc(rop->num, n);3327 for (i = n - 1ul; i != -1ul; i--)3328 fmpz_poly_set_coeff_mpz(rop->num, i, mpq_numref(a[i]));3329 3330 if (mpz_cmp_ui(den, 1) == 0)3331 fmpz_set_ui(rop->den, 1);3332 else3333 {3334 rop->den = fmpz_realloc(rop->den, mpz_size(den));3335 mpz_to_fmpz(rop->den, den);3336 }3337 mpz_clear(den);3338 mpz_clear(t);3339 }3340 3341 /**3342 * \ingroup StringConversions3343 *3344 * Sets the rational polynomial \c rop to the value specified by the3345 * null-terminated string \c str.3346 *3347 * The behaviour is undefined if the format of the string \c str does not3348 * conform to the specification.3349 *3350 * \todo In a future version, it would be nice to have this function return3351 * <tt>0</tt> or <tt>1</tt> depending on whether the input format3352 * was correct. Currently, the method always returns <tt>1</tt>.3353 */3354 int fmpq_poly_from_string(fmpq_poly_ptr rop, const char * str)3355 {3356 mpq_t * a;3357 char * strcopy;3358 ulong strcopy_len;3359 ulong i, j, k, n;3360 3361 n = atoi(str);3362 3363 /* Handle the case of the zero polynomial */3364 if (n == 0ul)3365 {3366 fmpq_poly_zero(rop);3367 return 1;3368 }3369 3370 /* Compute the maximum length that the copy buffer has to be */3371 strcopy_len = 0;3372 for (j = 0; str[j] != ' '; j++);3373 j += 2;3374 for (i = 0; i < n; i++)3375 {3376 for (k = j; !(str[k] == ' ' || str[k] == '\0'); k++);3377 strcopy_len = FLINT_MAX(strcopy_len, k - j + 1);3378 j = k + 1;3379 }3380 3381 strcopy = (char *) malloc(strcopy_len * sizeof(char));3382 if (!strcopy)3383 {3384 printf("ERROR (fmpq_poly_from_string). Memory allocation failed.\n");3385 abort();3386 }3387 3388 /* Read the data into the array a of mpq_t's */3389 a = (mpq_t *) malloc(n * sizeof(mpq_t));3390 for (j = 0; str[j] != ' '; j++);3391 j += 2;3392 for (i = 0; i < n; i++)3393 {3394 for (k = j; !(str[k] == ' ' || str[k] == '\0'); k++);3395 memcpy(strcopy, str + j, k - j + 1);3396 strcopy[k - j] = '\0';3397 3398 mpq_init(a[i]);3399 mpq_set_str(a[i], strcopy, 10);3400 mpq_canonicalize(a[i]);3401 j = k + 1;3402 }3403 3404 _fmpq_poly_from_list(rop, a, n);3405 3406 /* Clean-up */3407 free(strcopy);3408 for (i = 0; i < n; i++)3409 mpq_clear(a[i]);3410 free(a);3411 3412 return 1;3413 }3414 3415 /**3416 * \ingroup StringConversions3417 *3418 * Returns the string representation of the rational polynomial \c op.3419 */3420 char * fmpq_poly_to_string(const fmpq_poly_ptr op)3421 {3422 ulong i, j;3423 ulong len; /* Upper bound on the length */3424 ulong denlen; /* Size of the denominator in base 10 */3425 mpz_t z;3426 mpq_t q;3427 3428 char * str;3429 3430 if (fmpq_poly_is_zero(op))3431 {3432 str = (char *) malloc(2 * sizeof(char));3433 if (!str)3434 {3435 printf("ERROR (fmpq_poly_to_string). Memory allocation failed.\n");3436 abort();3437 }3438 str[0] = '0';3439 str[1] = '\0';3440 return str;3441 }3442 3443 mpz_init(z);3444 if (fmpz_is_one(op->den))3445 {3446 denlen = 0;3447 }3448 else3449 {3450 fmpz_to_mpz(z, op->den);3451 denlen = mpz_sizeinbase(z, 10);3452 }3453 len = fmpq_poly_places(fmpq_poly_length(op)) + 2;3454 for (i = 0; i < fmpq_poly_length(op); i++)3455 {3456 fmpz_poly_get_coeff_mpz(z, op->num, i);3457 len += mpz_sizeinbase(z, 10) + 1;3458 if (mpz_sgn(z) != 0)3459 len += 2 + denlen;3460 }3461 3462 mpq_init(q);3463 str = (char *) malloc(len * sizeof(char));3464 if (!str)3465 {3466 printf("ERROR (fmpq_poly_to_string). Memory allocation failed.\n");3467 abort();3468 }3469 sprintf(str, "%lu", fmpq_poly_length(op));3470 for (j = 0; str[j] != '\0'; j++);3471 str[j++] = ' ';3472 for (i = 0; i < fmpq_poly_length(op); i++)3473 {3474 str[j++] = ' ';3475 fmpz_poly_get_coeff_mpz(mpq_numref(q), op->num, i);3476 if (op->den == NULL)3477 mpz_set_ui(mpq_denref(q), 1);3478 else3479 fmpz_to_mpz(mpq_denref(q), op->den);3480 mpq_canonicalize(q);3481 mpq_get_str(str + j, 10, q);3482 for ( ; str[j] != '\0'; j++);3483 }3484 3485 mpq_clear(q);3486 mpz_clear(z);3487 3488 return str;3489 }3490 3491 /**3492 * \ingroup StringConversions3493 *3494 * Returns the pretty string representation of \c op.3495 *3496 * Returns the pretty string representation of the rational polynomial \c op,3497 * using the string \c var as the variable name.3498 */3499 char * fmpq_poly_to_string_pretty(const fmpq_poly_ptr op, const char * var)3500 {3501 long i;3502 ulong j;3503 ulong len; /* Upper bound on the length */3504 ulong denlen; /* Size of the denominator in base 10 */3505 ulong varlen; /* Length of the variable name */3506 mpz_t z; /* op->den (if this is not 1) */3507 mpq_t q;3508 char * str;3509 3510 if (fmpq_poly_is_zero(op))3511 {3512 str = (char *) malloc(2 * sizeof(char));3513 if (!str)3514 {3515 printf("ERROR (fmpq_poly_to_string_pretty). Memory allocation failed.\n");3516 abort();3517 }3518 str[0] = '0';3519 str[1] = '\0';3520 return str;3521 }3522 3523 if (fmpq_poly_length(op) == 1ul)3524 {3525 mpq_init(q);3526 fmpz_to_mpz(mpq_numref(q), fmpz_poly_lead(op->num));3527 if (fmpz_is_one(op->den))3528 mpz_set_ui(mpq_denref(q), 1);3529 else3530 {3531 fmpz_to_mpz(mpq_denref(q), op->den);3532 mpq_canonicalize(q);3533 }3534 str = mpq_get_str(NULL, 10, q);3535 mpq_clear(q);3536 return str;3537 }3538 3539 varlen = strlen(var);3540 3541 /* Copy the denominator into an mpz_t */3542 mpz_init(z);3543 if (fmpz_is_one(op->den))3544 {3545 denlen = 0;3546 }3547 else3548 {3549 fmpz_to_mpz(z, op->den);3550 denlen = mpz_sizeinbase(z, 10);3551 }3552 3553 /* Estimate the length */3554 len = 0;3555 for (i = 0; i < fmpq_poly_length(op); i++)3556 {3557 fmpz_poly_get_coeff_mpz(z, op->num, i);3558 len += mpz_sizeinbase(z, 10); /* Numerator */3559 if (mpz_sgn(z) != 0)3560 len += 1 + denlen; /* Denominator and / */3561 len += 3; /* Operator and whitespace */3562 len += 1 + varlen + 1; /* *, x and ^ */3563 len += fmpq_poly_places(i); /* Exponent */3564 }3565 3566 mpq_init(q);3567 str = (char *) malloc(len * sizeof(char));3568 if (!str)3569 {3570 printf("ERROR (fmpq_poly_to_string_pretty). Memory allocation failed.\n");3571 abort();3572 }3573 j = 0;3574 3575 /* Print the leading term */3576 fmpz_to_mpz(mpq_numref(q), fmpz_poly_lead(op->num));3577 fmpz_to_mpz(mpq_denref(q), op->den);3578 mpq_canonicalize(q);3579 3580 if (mpq_cmp_ui(q, 1, 1) != 0)3581 {3582 if (mpq_cmp_si(q, -1, 1) == 0)3583 str[j++] = '-';3584 else3585 {3586 mpq_get_str(str, 10, q);3587 for ( ; str[j] != '\0'; j++);3588 str[j++] = '*';3589 }3590 }3591 sprintf(str + j, "%s", var);3592 j += varlen;3593 if (fmpz_poly_degree(op->num) > 1)3594 {3595 str[j++] = '^';3596 sprintf(str + j, "%li", fmpz_poly_degree(op->num));3597 for ( ; str[j] != '\0'; j++);3598 }3599 3600 for (i = fmpq_poly_degree(op) - 1; i >= 0; i--)3601 {3602 if (fmpz_is_zero(fmpz_poly_get_coeff_ptr(op->num, i)))3603 continue;3604 3605 fmpz_poly_get_coeff_mpz(mpq_numref(q), op->num, i);3606 fmpz_to_mpz(mpq_denref(q), op->den);3607 mpq_canonicalize(q);3608 3609 str[j++] = ' ';3610 if (mpq_sgn(q) < 0)3611 {3612 mpq_abs(q, q);3613 str[j++] = '-';3614 }3615 else3616 str[j++] = '+';3617 str[j++] = ' ';3618 3619 mpq_get_str(str + j, 10, q);3620 for ( ; str[j] != '\0'; j++);3621 3622 if (i > 0)3623 {3624 str[j++] = '*';3625 sprintf(str + j, "%s", var);3626 j += varlen;3627 if (i > 1)3628 {3629 str[j++] = '^';3630 sprintf(str + j, "%li", i);3631 for ( ; str[j] != '\0'; j++);3632 }3633 }3634 }3635 3636 mpq_clear(q);3637 mpz_clear(z);3638 return str;3639 }3640 3641 #ifdef __cplusplus3642 }3643 #endif3644 -
deleted file sage/libs/flint/fmpq_poly.h
diff --git a/sage/libs/flint/fmpq_poly.h b/sage/libs/flint/fmpq_poly.h deleted file mode 100644
+ - 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 __cplusplus15 extern "C" {16 #endif17 18 #include <stdio.h>19 #include <gmp.h>20 21 #include "fmpz.h"22 #include "fmpz_poly.h"23 24 /**25 * \file fmpq_poly.h26 * \brief Fast implementation of the rational polynomial ring27 * \author Sebastian Pancratz28 * \date Mar 2010 -- July 201029 * \version 0.1.830 */31 32 /**33 * \ingroup Definitions34 * \brief Data type for a rational polynomial.35 * \details We represent a rational polynomial as the quotient of an integer36 * polynomial of type <tt>fmpz_poly_t</tt> and a denominator of type37 * <tt>fmpz_t</tt>, enforcing coprimality and that the denominator38 * is positive. The zero polynomial is represented as \f$0/1\f$.39 */40 typedef struct41 {42 fmpz_poly_t num; //!< Numerator43 fmpz_t den; //!< Denominator44 } fmpq_poly_struct;45 46 /**47 * \ingroup Definitions48 * \brief Array of #fmpq_poly_struct of length one.49 * \details This allows passing <em>by reference</em> without having to50 * explicitly allocate memory for the structure, as one would have51 * to when using pointers.52 */53 typedef fmpq_poly_struct fmpq_poly_t[1];54 55 /**56 * \ingroup Definitions57 * \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 denominator69 70 /**71 * \def fmpq_poly_numref(op)72 * \brief Returns a reference to the numerator of \c op.73 * \ingroup NumDen74 * \details The <tt>fmpz_poly</tt> functions can be used on the result of75 * 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 NumDen83 * \details The <tt>fmpz</tt> functions can be used on the result of84 * this macro.85 */86 #define fmpq_poly_denref(op) ((op)->den)87 88 ///////////////////////////////////////////////////////////////////////////////89 // Memory management90 91 /**92 * \ingroup MemoryManagement93 *94 * Initializes the element \c rop to zero.95 *96 * This function should be called once for the #fmpq_poly_ptr \c rop, before97 * using it with other <tt>fmpq_poly</tt> functions, or following a98 * preceeding call to #fmpq_poly_clear().99 */100 static inline101 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 MemoryManagement110 *111 * Clears the element \c rop.112 *113 * This function should only be called on an element which has been114 * initialised.115 */116 static inline117 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 manipulation125 126 /**127 * \ingroup Assignment128 *129 * Sets the element \c rop to the same value as the element \c op.130 */131 static inline132 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 Assignment145 *146 * Sets the element \c rop to the same value as the element \c op.147 */148 static inline149 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 Assignment157 *158 * Sets the element \c rop to the value given by the \c int \c op.159 */160 static inline161 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 Assignment170 *171 * Sets the element \c rop to the integer \c x.172 */173 static inline174 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 Assignment183 *184 * Sets the element \c rop to the integer \c x.185 */186 static inline187 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 Assignment196 *197 * Sets the element \c rop to the rational \c x, assumed to be given198 * in lowest terms.199 */200 static inline201 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 Assignment211 *212 * Swaps the elements \c op1 and \c op2.213 *214 * This is done efficiently by swapping pointers.215 */216 static inline217 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 Assignment231 *232 * Sets the element \c rop to zero.233 */234 static inline235 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 Assignment243 *244 * Sets the element \c rop to one.245 */246 static inline247 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 coefficients259 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 // Comparison269 270 /**271 * \brief Returns whether \c op is zero.272 * \ingroup Comparison273 *274 * Returns whether the element \c op is zero.275 */276 static inline277 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 Comparison285 *286 * Returns whether the element \c op is equal to the constant polynomial287 * \f$1\f$.288 */289 static inline290 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 parameters301 302 /**303 * \brief Returns the length of \c op.304 * \ingroup PolyParameters305 * \details Returns the length of the polynomial \c op, which is one greater306 * than its degree.307 */308 static inline309 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 Parameters317 * \details Returns the degree of the polynomial \c op.318 */319 static inline320 long fmpq_poly_degree(const fmpq_poly_ptr op)321 {322 return (long) (op->num->length - 1ul);323 }324 325 ///////////////////////////////////////////////////////////////////////////////326 // Addition/ subtraction327 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 division336 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 // Multiplication347 348 void fmpq_poly_mul(fmpq_poly_ptr rop, const fmpq_poly_ptr op1, const fmpq_poly_ptr op2);349 350 ///////////////////////////////////////////////////////////////////////////////351 // Division352 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 // Powering359 360 void fmpq_poly_power(fmpq_poly_ptr rop, const fmpq_poly_ptr op, ulong exp);361 362 ///////////////////////////////////////////////////////////////////////////////363 // Greatest common divisor364 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 // Derivative371 372 void fmpq_poly_derivative(fmpq_poly_ptr rop, fmpq_poly_ptr op);373 374 ///////////////////////////////////////////////////////////////////////////////375 // Evaluation376 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 content382 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 // Resultant390 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 // Composition396 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-free402 403 int fmpq_poly_is_squarefree(const fmpq_poly_ptr op);404 405 ///////////////////////////////////////////////////////////////////////////////406 // Subpolynomials407 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 conversion416 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 __cplusplus423 }424 #endif425 426 #endif427 -
sage/libs/flint/fmpq_poly.pxd
diff --git a/sage/libs/flint/fmpq_poly.pxd b/sage/libs/flint/fmpq_poly.pxd
a b 1 ############################################################################### 2 # Copyright (C) 2010 Sebastian Pancratz <sfp@pancratz.org> # 3 # # 4 # Distributed under the terms of the GNU General Public License (GPL) # 5 # # 6 # http://www.gnu.org/licenses/ # 7 ############################################################################### 8 9 #include "fmpz_poly.pxi" 10 #include "fmpz.pxi" 11 12 cdef extern from "gmp.h": 13 ctypedef void * mpz_t 14 ctypedef void * mpq_t 15 16 cdef extern from "fmpq_poly.h": 17 ctypedef void * fmpz_t 18 ctypedef void * fmpz_poly_p 19 struct fmpq_poly: 20 fmpz_poly_p num 21 fmpz_t den 22 23 ctypedef fmpq_poly fmpq_poly_struct 24 ctypedef fmpq_poly_struct fmpq_poly_t[1] 25 26 void * fmpq_poly_canonicalize(fmpq_poly_t, fmpz_t) 27 28 void * fmpq_poly_numref(fmpq_poly_t) 29 void * fmpq_poly_denref(fmpq_poly_t) 30 31 void fmpq_poly_init(fmpq_poly_t) 32 void fmpq_poly_clear(fmpq_poly_t) 33 34 void fmpq_poly_set(fmpq_poly_t, fmpq_poly_t) 35 void fmpq_poly_set_fmpz_poly(fmpq_poly_t, fmpz_poly_t) 36 void fmpq_poly_set_si(fmpq_poly_t, long) 37 void fmpq_poly_set_mpz(fmpq_poly_t, mpz_t) 38 void fmpq_poly_set_mpq(fmpq_poly_t, mpq_t) 39 void fmpq_poly_swap(fmpq_poly_t, fmpq_poly_t) 40 void fmpq_poly_zero(fmpq_poly_t) 41 void fmpq_poly_neg(fmpq_poly_t, fmpq_poly_t) 42 43 void fmpq_poly_get_coeff_mpq(mpq_t, fmpq_poly_t, unsigned long) 44 void fmpq_poly_set_coeff_si(fmpq_poly_t, unsigned long, long) 45 void fmpq_poly_set_coeff_mpq(fmpq_poly_t, unsigned long, mpq_t) 46 void fmpq_poly_set_coeff_mpz(fmpq_poly_t, unsigned long, mpz_t) 47 48 int fmpq_poly_equal(fmpq_poly_t, fmpq_poly_t) 49 int fmpq_poly_cmp(fmpq_poly_t, fmpq_poly_t) 50 int fmpq_poly_is_zero(fmpq_poly_t) 51 52 long fmpq_poly_degree(fmpq_poly_t) 53 unsigned long fmpq_poly_length(fmpq_poly_t) 54 55 void fmpq_poly_add(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 56 void fmpq_poly_sub(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 57 58 void fmpq_poly_scalar_mul_mpq(fmpq_poly_t, fmpq_poly_t, mpq_t) 59 void fmpq_poly_scalar_div_mpq(fmpq_poly_t, fmpq_poly_t, mpq_t) 60 61 void fmpq_poly_mul(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 62 63 void fmpq_poly_divrem(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 64 void fmpq_poly_floordiv(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 65 void fmpq_poly_mod(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 66 67 void fmpq_poly_power(fmpq_poly_t, fmpq_poly_t, unsigned long) 68 69 void fmpq_poly_left_shift(fmpq_poly_t, fmpq_poly_t, unsigned long) 70 void fmpq_poly_right_shift(fmpq_poly_t, fmpq_poly_t, unsigned long) 71 72 void fmpq_poly_gcd(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 73 void fmpq_poly_xgcd(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 74 void fmpq_poly_lcm(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 75 76 void fmpq_poly_derivative(fmpq_poly_t, fmpq_poly_t) 77 78 void fmpq_poly_evaluate_mpz(mpq_t, fmpq_poly_t, mpz_t) 79 void fmpq_poly_evaluate_mpq(mpq_t, fmpq_poly_t, mpq_t) 80 81 void fmpq_poly_content(mpq_t, fmpq_poly_t) 82 void fmpq_poly_primitive_part(fmpq_poly_t, fmpq_poly_t) 83 84 void fmpq_poly_resultant(mpq_t, fmpq_poly_t, fmpq_poly_t) 85 86 void fmpq_poly_compose(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 87 88 void fmpq_poly_getslice(fmpq_poly_t, fmpq_poly_t, unsigned long, unsigned long) 89 void fmpq_poly_truncate(fmpq_poly_t, fmpq_poly_t, unsigned long) 90 void fmpq_poly_reverse(fmpq_poly_t, fmpq_poly_t, unsigned long) 91 92 void _fmpq_poly_from_list(fmpq_poly_t, mpq_t *, unsigned long) 93 void fmpq_poly_from_string(fmpq_poly_t, char *) 94 char * fmpq_poly_to_string(fmpq_poly_t, char *) 95 char * fmpq_poly_to_string_pretty(fmpq_poly_t, char *) 96 1 ############################################################################### 2 # Copyright (C) 2010 Sebastian Pancratz <sfp@pancratz.org> # 3 # # 4 # Distributed under the terms of the GNU General Public License (GPL) # 5 # # 6 # http://www.gnu.org/licenses/ # 7 ############################################################################### 8 9 #include "fmpz_poly.pxi" 10 #include "fmpz.pxi" 11 12 cdef extern from "gmp.h": 13 ctypedef void * mpz_t 14 ctypedef void * mpq_t 15 16 cdef extern from "fmpq.h": 17 ctypedef void * fmpq_t 18 void fmpq_init(fmpq_t) 19 void fmpq_clear(fmpq_t) 20 void fmpq_get_mpq(mpq_t, fmpq_t) 21 void fmpq_set_mpq(fmpq_t, mpq_t) 22 23 cdef extern from "fmpz_vec.h": 24 long _fmpz_vec_max_limbs(void * c, long n) 25 26 cdef extern from "fmpq_poly.h": 27 ctypedef void * fmpz_t 28 ctypedef void * fmpq_poly_t 29 30 void fmpq_poly_canonicalise(fmpq_poly_t) 31 32 void * fmpq_poly_numref(fmpq_poly_t) 33 void * fmpq_poly_denref(fmpq_poly_t) 34 35 void fmpq_poly_init(fmpq_poly_t) 36 void fmpq_poly_clear(fmpq_poly_t) 37 38 void fmpq_poly_set(fmpq_poly_t, fmpq_poly_t) 39 void fmpq_poly_set_fmpz_poly(fmpq_poly_t, fmpz_poly_t) 40 void fmpq_poly_set_si(fmpq_poly_t, long) 41 void fmpq_poly_set_mpz(fmpq_poly_t, mpz_t) 42 void fmpq_poly_set_mpq(fmpq_poly_t, mpq_t) 43 void fmpq_poly_swap(fmpq_poly_t, fmpq_poly_t) 44 void fmpq_poly_zero(fmpq_poly_t) 45 void fmpq_poly_neg(fmpq_poly_t, fmpq_poly_t) 46 47 void fmpq_poly_get_numerator(fmpz_poly_t, fmpq_poly_t) 48 49 void fmpq_poly_get_coeff_mpq(mpq_t, fmpq_poly_t, unsigned long) 50 void fmpq_poly_set_coeff_si(fmpq_poly_t, unsigned long, long) 51 void fmpq_poly_set_coeff_mpq(fmpq_poly_t, unsigned long, mpq_t) 52 void fmpq_poly_set_coeff_mpz(fmpq_poly_t, unsigned long, mpz_t) 53 54 int fmpq_poly_equal(fmpq_poly_t, fmpq_poly_t) 55 int fmpq_poly_cmp(fmpq_poly_t, fmpq_poly_t) 56 int fmpq_poly_is_zero(fmpq_poly_t) 57 58 long fmpq_poly_degree(fmpq_poly_t) 59 unsigned long fmpq_poly_length(fmpq_poly_t) 60 61 void fmpq_poly_add(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 62 void fmpq_poly_sub(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 63 64 void fmpq_poly_scalar_mul_mpq(fmpq_poly_t, fmpq_poly_t, mpq_t) 65 void fmpq_poly_scalar_div_mpq(fmpq_poly_t, fmpq_poly_t, mpq_t) 66 67 void fmpq_poly_mul(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 68 69 void fmpq_poly_divrem(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 70 void fmpq_poly_div(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 71 void fmpq_poly_rem(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 72 73 void fmpq_poly_pow(fmpq_poly_t, fmpq_poly_t, unsigned long) 74 75 void fmpq_poly_shift_left(fmpq_poly_t, fmpq_poly_t, unsigned long) 76 void fmpq_poly_shift_right(fmpq_poly_t, fmpq_poly_t, unsigned long) 77 78 void fmpq_poly_gcd(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 79 void fmpq_poly_xgcd(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 80 void fmpq_poly_lcm(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 81 82 void fmpq_poly_derivative(fmpq_poly_t, fmpq_poly_t) 83 84 void fmpq_poly_evaluate_mpz(mpq_t, fmpq_poly_t, mpz_t) 85 void fmpq_poly_evaluate_mpq(mpq_t, fmpq_poly_t, mpq_t) 86 87 void fmpq_poly_content(fmpq_t, fmpq_poly_t) 88 void fmpq_poly_primitive_part(fmpq_poly_t, fmpq_poly_t) 89 90 void fmpq_poly_resultant(fmpq_t, fmpq_poly_t, fmpq_poly_t) 91 92 void fmpq_poly_compose(fmpq_poly_t, fmpq_poly_t, fmpq_poly_t) 93 94 void fmpq_poly_get_slice(fmpq_poly_t, fmpq_poly_t, long, long) 95 void fmpq_poly_truncate(fmpq_poly_t, unsigned long) 96 void fmpq_poly_reverse(fmpq_poly_t, fmpq_poly_t, unsigned long) 97 98 void fmpq_poly_set_array_mpq(fmpq_poly_t, mpq_t *, unsigned long) 99 void fmpq_poly_from_string(fmpq_poly_t, char *) 100 char * fmpq_poly_to_string(fmpq_poly_t, char *) 101 char * fmpq_poly_to_string_pretty(fmpq_poly_t, char *) 102 -
sage/libs/flint/fmpz.pxi
diff --git a/sage/libs/flint/fmpz.pxi b/sage/libs/flint/fmpz.pxi
a b 1 1 include "../ntl/decl.pxi" 2 2 3 3 cdef extern from "FLINT/fmpz.h": 4 5 ctypedef void * fmpz_t 4 5 ctypedef long fmpz 6 ctypedef long * fmpz_t 6 7 ctypedef void * mpz_t 7 8 8 fmpz_t fmpz_init(unsigned long limbs)9 void fmpz_init(fmpz_t x) 9 10 10 11 void fmpz_set_ui(fmpz_t res, unsigned long x) 11 12 void fmpz_set_si(fmpz_t res, long x) … … 13 14 void fmpz_clear(fmpz_t f) 14 15 void fmpz_print(fmpz_t f) 15 16 int fmpz_is_one(fmpz_t f) 17 18 void fmpz_get_mpz(mpz_t rop, fmpz_t op) 19 void fmpz_set_mpz(fmpz_t rop, mpz_t op) 16 20 17 void fmpz_add_ui_inplace(fmpz_t output, unsigned long x) 18 void fmpz_sub_ui_inplace(fmpz_t output, unsigned long x) 19 20 void fmpz_to_mpz(mpz_t rop, fmpz_t op) 21 void fmpz_add_ui(fmpz_t f, fmpz_t g, unsigned long c) 22 -
sage/libs/flint/fmpz_poly.pxi
diff --git a/sage/libs/flint/fmpz_poly.pxi b/sage/libs/flint/fmpz_poly.pxi
a b 6 6 ctypedef void* fmpz_poly_t 7 7 8 8 void fmpz_poly_init(fmpz_poly_t poly) 9 void fmpz_poly_init2(fmpz_poly_t poly, unsigned long alloc, \ 10 unsigned long limbs) 9 void fmpz_poly_init2(fmpz_poly_t poly, unsigned long alloc) 11 10 void fmpz_poly_realloc(fmpz_poly_t poly, unsigned long alloc) 12 11 13 12 void fmpz_poly_fit_length(fmpz_poly_t poly, unsigned long alloc) 14 void fmpz_poly_resize_limbs(fmpz_poly_t poly, unsigned long limbs)15 void fmpz_poly_fit_limbs(fmpz_poly_t poly, unsigned long limbs)16 unsigned long fmpz_poly_limbs(fmpz_poly_t poly)17 13 18 14 void fmpz_poly_clear(fmpz_poly_t poly) 19 15 … … 54 50 unsigned long x) 55 51 void fmpz_poly_scalar_mul_si(fmpz_poly_t output, fmpz_poly_t input, long x) 56 52 57 void fmpz_poly_scalar_mul_mpz(fmpz_poly_t output, fmpz_poly_t poly, 58 mpz_t x) 53 void fmpz_poly_scalar_mul_fmpz(fmpz_poly_t output, fmpz_poly_t poly, 54 fmpz_t x) 55 void fmpz_poly_scalar_mul_mpz(fmpz_poly_t output, fmpz_poly_t poly, mpz_t x) 59 56 60 void fmpz_poly_scalar_div _exact_ui(fmpz_poly_t output, fmpz_poly_t poly, \57 void fmpz_poly_scalar_divexact_ui(fmpz_poly_t output, fmpz_poly_t poly, \ 61 58 unsigned long x) 62 void fmpz_poly_scalar_div _exact_si(fmpz_poly_t output, fmpz_poly_t poly, \59 void fmpz_poly_scalar_divexact_si(fmpz_poly_t output, fmpz_poly_t poly, \ 63 60 long x) 64 void fmpz_poly_scalar_div _exact_fmpz(fmpz_poly_t output, fmpz_poly_t poly, \61 void fmpz_poly_scalar_divexact_fmpz(fmpz_poly_t output, fmpz_poly_t poly, \ 65 62 fmpz_t x) 66 63 67 void fmpz_poly_scalar_div_mpz( fmpz_poly_t output, fmpz_poly_t poly, mpz_t x) 64 void fmpz_poly_scalar_divexact_mpz( fmpz_poly_t output, fmpz_poly_t poly, mpz_t x) 65 66 void fmpz_poly_scalar_fdiv_ui(fmpz_poly_t output, fmpz_poly_t poly, unsigned long x) 67 void fmpz_poly_scalar_fdiv_mpz(fmpz_poly_t output, fmpz_poly_t poly, mpz_t x) 68 68 69 69 void fmpz_poly_div(fmpz_poly_t Q, fmpz_poly_t A, fmpz_poly_t B) 70 70 void fmpz_poly_divrem(fmpz_poly_t Q, fmpz_poly_t R, fmpz_poly_t A, \ … … 77 77 78 78 int fmpz_poly_equal(fmpz_poly_t poly1, fmpz_poly_t poly2) 79 79 80 bint fmpz_poly_from_string(fmpz_poly_t poly, char* s)81 char* fmpz_poly_ to_string(fmpz_poly_t poly)80 int fmpz_poly_set_str(fmpz_poly_t poly, char* s) 81 char* fmpz_poly_get_str(fmpz_poly_t poly) 82 82 void fmpz_poly_print(fmpz_poly_t poly) 83 83 bint fmpz_poly_read(fmpz_poly_t poly) 84 84 85 void fmpz_poly_pow er(fmpz_poly_t output, fmpz_poly_t poly, \85 void fmpz_poly_pow(fmpz_poly_t output, fmpz_poly_t poly, \ 86 86 unsigned long exp) 87 void fmpz_poly_pow er_trunc_n(fmpz_poly_t output, fmpz_poly_t poly, \87 void fmpz_poly_pow_trunc(fmpz_poly_t output, fmpz_poly_t poly, \ 88 88 unsigned long exp, unsigned long n) 89 89 90 void fmpz_poly_ left_shift ( fmpz_poly_t output ,90 void fmpz_poly_shift_left ( fmpz_poly_t output , 91 91 fmpz_poly_t poly , unsigned long n ) 92 void fmpz_poly_ right_shift ( fmpz_poly_t output ,92 void fmpz_poly_shift_right ( fmpz_poly_t output , 93 93 fmpz_poly_t poly , unsigned long n ) 94 94 95 95 void fmpz_poly_derivative ( fmpz_poly_t der , fmpz_poly_t poly ) -
sage/libs/flint/fmpz_poly.pyx
diff --git a/sage/libs/flint/fmpz_poly.pyx b/sage/libs/flint/fmpz_poly.pyx
a b 53 53 cdef long c 54 54 cdef Integer w 55 55 if PY_TYPE_CHECK(v, str): 56 if fmpz_poly_from_string(self.poly, v):56 if not fmpz_poly_set_str(self.poly, v): 57 57 return 58 58 else: 59 59 raise ValueError, "Unable to create Fmpz_poly from that string." … … 115 115 sage: f = Fmpz_poly([0,1]); f^7 116 116 8 0 0 0 0 0 0 0 1 117 117 """ 118 cdef char* ss = fmpz_poly_ to_string(self.poly)118 cdef char* ss = fmpz_poly_get_str(self.poly) 119 119 cdef object s = ss 120 120 sage_free(ss) 121 121 return s … … 246 246 if not PY_TYPE_CHECK(self, Fmpz_poly): 247 247 raise TypeError 248 248 cdef Fmpz_poly res = <Fmpz_poly>PY_NEW(Fmpz_poly) 249 fmpz_poly_pow er(res.poly, (<Fmpz_poly>self).poly, nn)249 fmpz_poly_pow(res.poly, (<Fmpz_poly>self).poly, nn) 250 250 return res 251 251 252 252 def pow_truncate(self, exp, n): … … 267 267 raise ValueError, "Exponent must be at least 0" 268 268 cdef long exp_c = exp, nn = n 269 269 cdef Fmpz_poly res = <Fmpz_poly>PY_NEW(Fmpz_poly) 270 fmpz_poly_pow er_trunc_n(res.poly, (<Fmpz_poly>self).poly, exp_c, nn)270 fmpz_poly_pow_trunc(res.poly, (<Fmpz_poly>self).poly, exp_c, nn) 271 271 return res 272 272 273 273 def __floordiv__(left, right): … … 329 329 """ 330 330 cdef Fmpz_poly res = <Fmpz_poly>PY_NEW(Fmpz_poly) 331 331 332 fmpz_poly_ left_shift(res.poly, self.poly, n)332 fmpz_poly_shift_left(res.poly, self.poly, n) 333 333 334 334 return res 335 335 … … 345 345 """ 346 346 cdef Fmpz_poly res = <Fmpz_poly>PY_NEW(Fmpz_poly) 347 347 348 fmpz_poly_ right_shift(res.poly, self.poly, n)348 fmpz_poly_shift_right(res.poly, self.poly, n) 349 349 350 350 return res 351 351 -
deleted file sage/libs/flint/long_extras.pxd
diff --git a/sage/libs/flint/long_extras.pxd b/sage/libs/flint/long_extras.pxd deleted file mode 100644
+ - 1 include "../../ext/stdsage.pxi"2 include "../../ext/cdefs.pxi"3 4 from sage.libs.flint.flint cimport *5 6 7 cdef extern from "FLINT/long_extras.h":8 9 ctypedef struct factor_t:10 int num11 unsigned long p[15]12 unsigned long exp[15]13 14 cdef unsigned long z_randint(unsigned long limit)15 16 cdef unsigned long z_randbits(unsigned long bits)17 18 cdef unsigned long z_randprime(unsigned long bits, int proved)19 20 cdef double z_precompute_inverse(unsigned long n)21 22 cdef double z_precompute_inverse2(unsigned long n)23 24 cdef double z_ll_precompute_inverse(unsigned long n)25 26 cdef unsigned long z_addmod(unsigned long a, unsigned long b, unsigned long p)27 28 cdef unsigned long z_submod(unsigned long a, unsigned long b, unsigned long p)29 30 cdef unsigned long z_negmod(unsigned long a, unsigned long p)31 32 cdef unsigned long z_mod_precomp(unsigned long a, unsigned long n, double ninv)33 34 cdef unsigned long z_div2_precomp(unsigned long a, unsigned long n, double ninv)35 36 cdef unsigned long z_mod2_precomp(unsigned long a, unsigned long n, double ninv)37 38 cdef unsigned long z_ll_mod_precomp(unsigned long a_hi, unsigned long a_lo, unsigned long n, double ninv)39 40 cdef unsigned long z_mulmod_precomp(unsigned long a, unsigned long b, unsigned long n, double ninv)41 42 cdef unsigned long z_mulmod2_precomp(unsigned long a, unsigned long b, unsigned long n, double ninv)43 44 cdef unsigned long z_powmod(unsigned long a, long exp, unsigned long n)45 46 cdef unsigned long z_powmod2(unsigned long a, long exp, unsigned long n)47 48 cdef unsigned long z_powmod_precomp(unsigned long a, long exp, unsigned long n, double ninv)49 50 cdef unsigned long z_powmod2_precomp(unsigned long a, long exp, unsigned long n, double ninv)51 52 cdef int z_legendre_precomp(unsigned long a, unsigned long p, double pinv)53 54 cdef int z_jacobi(long x, unsigned long y)55 56 cdef int z_ispseudoprime_fermat(unsigned long n, unsigned long i)57 58 cdef int z_isprime(unsigned long n)59 60 cdef int z_isprime_precomp(unsigned long n, double ninv)61 62 cdef unsigned long z_nextprime(unsigned long n, int proved)63 64 cdef int z_isprime_pocklington(unsigned long n, unsigned long iterations)65 66 cdef int z_ispseudoprime_lucas_ab(unsigned long n, int a, int b)67 68 cdef int z_ispseudoprime_lucas(unsigned long n)69 70 cdef unsigned long z_pow(unsigned long a, unsigned long exp)71 72 cdef unsigned long z_sqrtmod(unsigned long a, unsigned long p)73 74 cdef unsigned long z_cuberootmod(unsigned long * cuberoot1, unsigned long a, unsigned long p)75 76 cdef unsigned long z_invert(unsigned long a, unsigned long p)77 78 cdef long z_gcd_invert(long* a, long x, long y)79 80 cdef long z_extgcd(long* a, long* b, long x, long y)81 82 cdef unsigned long z_gcd(long x, long y)83 84 cdef unsigned long z_intsqrt(unsigned long r)85 86 cdef int z_issquare(unsigned long x)87 88 cdef unsigned long z_CRT(unsigned long x1, unsigned long n1, unsigned long x2, unsigned long n2)89 90 cdef int z_issquarefree(unsigned long n, int proved)91 92 cdef int z_remove_precomp(unsigned long * n, unsigned long p, double pinv)93 94 cdef int z_remove(unsigned long * n, unsigned long p)95 96 cdef unsigned long z_factor_SQUFOF(unsigned long n)97 98 cdef unsigned long z_primitive_root(unsigned long p)99 100 cdef unsigned long z_primitive_root_precomp(unsigned long p, double p_inv)101 102 cdef void z_factor(factor_t * factors, unsigned long n, int proved)103 104 -
sage/libs/flint/ntl_interface.pxd
diff --git a/sage/libs/flint/ntl_interface.pxd b/sage/libs/flint/ntl_interface.pxd
a b 6 6 from sage.libs.ntl.ntl_ZZX_decl cimport ZZX_c 7 7 8 8 cdef extern from "FLINT/NTL-interface.h": 9 unsigned long ZZ_limbs(ZZ_c z)10 9 11 void fmpz_poly_ to_ZZX(ZZX_c output, fmpz_poly_t poly)12 void ZZX_to_fmpz_poly(fmpz_poly_t output, ZZX_c poly)10 void fmpz_poly_get_ZZX(ZZX_c output, fmpz_poly_t poly) 11 void fmpz_poly_set_ZZX(fmpz_poly_t output, ZZX_c poly) 13 12 14 void fmpz_ to_mpz(mpz_t res, fmpz_t f)15 void ZZ_to_fmpz(fmpz_t output, ZZ_c z)16 13 void fmpz_get_ZZ(ZZ_c output, fmpz_t f) 14 void fmpz_set_ZZ(fmpz_t output, ZZ_c z) 15 -
new file sage/libs/flint/ulong_extras.pxd
diff --git a/sage/libs/flint/ulong_extras.pxd b/sage/libs/flint/ulong_extras.pxd new file mode 100644
- + 1 include "../../ext/stdsage.pxi" 2 include "../../ext/cdefs.pxi" 3 4 from sage.libs.flint.flint cimport * 5 6 7 cdef extern from "FLINT/ulong_extras.h": 8 9 ctypedef struct n_factor_t: 10 int num 11 unsigned long p[15] 12 unsigned long exp[15] 13 14 cdef int n_jacobi(long x, unsigned long y) 15 16 cdef int n_is_prime(unsigned long n) 17 18 cdef unsigned long n_gcd(long x, long y) 19 20 cdef void n_factor(n_factor_t * factors, unsigned long n, int proved) -
sage/libs/flint/zmod_poly.pxd
diff --git a/sage/libs/flint/zmod_poly.pxd b/sage/libs/flint/zmod_poly.pxd
a b 5 5 6 6 from flint import * 7 7 8 cdef extern from "FLINT/zmod_poly.h": 9 ctypedef struct zmod_poly_struct: 10 unsigned long *coeffs 11 unsigned long alloc 12 unsigned long length 13 unsigned long p 14 double p_inv 8 cdef extern from "FLINT/nmod_poly.h": 15 9 16 ctypedef zmod_poly_struct* zmod_poly_t 10 ctypedef unsigned long mp_bitcnt_t 11 ctypedef void * mp_srcptr 17 12 18 ctypedef struct zmod_poly_factor_struct: 19 zmod_poly_t *factors 20 unsigned long *exponents 21 unsigned long alloc 22 unsigned long num_factors 13 ctypedef struct nmod_t: 14 mp_limb_t n 15 mp_limb_t ninv 16 mp_bitcnt_t norm 23 17 24 ctypedef zmod_poly_factor_struct* zmod_poly_factor_t 18 ctypedef struct nmod_poly_struct: 19 mp_limb_t *coeffs 20 long alloc 21 long length 22 nmod_t mod 25 23 26 cdef void zmod_poly_init(zmod_poly_t poly, unsigned long p) 27 cdef void zmod_poly_init_precomp(zmod_poly_t poly, unsigned long p, double p_inv) 28 cdef void zmod_poly_init2(zmod_poly_t poly, unsigned long p, unsigned long alloc) 29 cdef void zmod_poly_init2_precomp(zmod_poly_t poly, unsigned long p, double p_inv, unsigned long alloc) 30 cdef void zmod_poly_clear(zmod_poly_t poly) 24 ctypedef nmod_poly_struct* nmod_poly_t 31 25 32 cdef void zmod_poly_realloc(zmod_poly_t poly, unsigned long alloc) 33 # _bits_ only applies to newly allocated coefficients, not existing ones... 26 ctypedef struct nmod_poly_factor_struct: 27 nmod_poly_struct *p 28 long *exp 29 long num 30 long alloc 34 31 35 # this non-inlined version REQUIRES that alloc > poly->alloc 36 void __zmod_poly_fit_length(zmod_poly_t poly, unsigned long alloc) 32 ctypedef nmod_poly_factor_struct* nmod_poly_factor_t 37 33 38 # this is arranged so that the initial comparison (very frequent) is inlined, 39 # but the actual allocation (infrequent) is not 40 cdef void zmod_poly_fit_length(zmod_poly_t poly, unsigned long alloc) 34 # Memory management 41 35 42 # ------------------------------------------------------ 43 # Setting/retrieving coefficients 36 cdef void nmod_poly_init(nmod_poly_t poly, mp_limb_t n) 37 cdef void nmod_poly_init_preinv(nmod_poly_t poly, mp_limb_t n, mp_limb_t ninv) 38 cdef void nmod_poly_init2(nmod_poly_t poly, mp_limb_t n, long alloc) 39 cdef void nmod_poly_init2_preinv(nmod_poly_t poly, mp_limb_t n, mp_limb_t ninv, long alloc) 40 cdef void nmod_poly_realloc(nmod_poly_t poly, long alloc) 41 cdef void nmod_poly_clear(nmod_poly_t poly) 42 cdef void nmod_poly_fit_length(nmod_poly_t poly, long alloc) 43 cdef void _nmod_poly_normalise(nmod_poly_t poly) 44 44 45 cdef unsigned long zmod_poly_get_coeff_ui(zmod_poly_t poly, unsigned long n)45 # Polynomial parameters 46 46 47 cdef unsigned long _zmod_poly_get_coeff_ui(zmod_poly_t poly, unsigned long n) 47 cdef long nmod_poly_length(nmod_poly_t poly) 48 cdef long nmod_poly_degree(nmod_poly_t poly) 49 cdef mp_limb_t nmod_poly_modulus(nmod_poly_t poly) 50 cdef mp_bitcnt_t nmod_poly_max_bits(nmod_poly_t poly) 48 51 49 cdef void zmod_poly_set_coeff_ui(zmod_poly_t poly, unsigned long n, unsigned long c)52 # Assignment and basic manipulation 50 53 51 cdef void _zmod_poly_set_coeff_ui(zmod_poly_t poly, unsigned long n, unsigned long c) 54 cdef void nmod_poly_set(nmod_poly_t a, nmod_poly_t b) 55 cdef void nmod_poly_swap(nmod_poly_t poly1, nmod_poly_t poly2) 56 cdef void nmod_poly_zero(nmod_poly_t res) 57 cdef void nmod_poly_one(nmod_poly_t res) 58 cdef void nmod_poly_truncate(nmod_poly_t poly, long len) 59 cdef void nmod_poly_reverse(nmod_poly_t output, nmod_poly_t input, long m) 52 60 53 # ------------------------------------------------------ 54 # String conversions and I/O 61 # Comparison 55 62 56 cdef int zmod_poly_from_string(zmod_poly_t poly, char* s) 57 cdef char* zmod_poly_to_string(zmod_poly_t poly) 58 cdef void zmod_poly_print(zmod_poly_t poly) 59 cdef void zmod_poly_fprint(zmod_poly_t poly, FILE* f) 60 cdef int zmod_poly_read(zmod_poly_t poly) 61 cdef int zmod_poly_fread(zmod_poly_t poly, FILE* f) 63 cdef int nmod_poly_equal(nmod_poly_t a, nmod_poly_t b) 64 cdef int nmod_poly_is_zero(nmod_poly_t poly) 65 cdef int nmod_poly_is_one(nmod_poly_t poly) 62 66 63 # ------------------------------------------------------ 64 # Length and degree 67 # Getting and setting coefficients 65 68 66 cdef void __zmod_poly_normalise(zmod_poly_t poly) 67 cdef int __zmod_poly_normalised(zmod_poly_t poly) 68 cdef void zmod_poly_truncate(zmod_poly_t poly, unsigned long length) 69 cdef unsigned long nmod_poly_get_coeff_ui(nmod_poly_t poly, unsigned long j) 70 cdef void nmod_poly_set_coeff_ui(nmod_poly_t poly, unsigned long j, unsigned long c) 69 71 70 cdef unsigned long zmod_poly_length(zmod_poly_t poly)72 # Input and output 71 73 72 cdef long zmod_poly_degree(zmod_poly_t poly) 74 cdef char * nmod_poly_get_str(nmod_poly_t poly) 75 cdef int nmod_poly_set_str(char * s, nmod_poly_t poly) 76 cdef int nmod_poly_print(nmod_poly_t a) 77 cdef int nmod_poly_fread(FILE * f, nmod_poly_t poly) 78 cdef int nmod_poly_fprint(FILE * f, nmod_poly_t poly) 79 cdef int nmod_poly_read(nmod_poly_t poly) 73 80 74 cdef unsigned long zmod_poly_modulus(zmod_poly_t poly)81 # Shifting 75 82 76 cdef double zmod_poly_precomputed_inverse(zmod_poly_t poly) 83 cdef void nmod_poly_shift_left(nmod_poly_t res, nmod_poly_t poly, long k) 84 cdef void nmod_poly_shift_right(nmod_poly_t res, nmod_poly_t poly, long k) 77 85 78 # ------------------------------------------------------ 79 # Assignment 86 # Addition and subtraction 80 87 81 cdef void _zmod_poly_set(zmod_poly_t res, zmod_poly_t poly) 82 cdef void zmod_poly_set(zmod_poly_t res, zmod_poly_t poly) 88 cdef void nmod_poly_add(nmod_poly_t res, nmod_poly_t poly1, nmod_poly_t poly2) 89 cdef void nmod_poly_sub(nmod_poly_t res, nmod_poly_t poly1, nmod_poly_t poly2) 90 cdef void nmod_poly_neg(nmod_poly_t res, nmod_poly_t poly1) 83 91 84 cdef void zmod_poly_zero(zmod_poly_t poly)92 # Scalar multiplication and division 85 93 86 cdef void zmod_poly_swap(zmod_poly_t poly1, zmod_poly_t poly2) 94 cdef void nmod_poly_scalar_mul_nmod(nmod_poly_t res, nmod_poly_t poly1, mp_limb_t c) 95 cdef void nmod_poly_make_monic(nmod_poly_t output, nmod_poly_t input) 87 96 88 # 89 # Subpolynomials 90 # 97 # Multiplication 91 98 92 cdef void _zmod_poly_attach(zmod_poly_t output, zmod_poly_t input) 99 cdef void nmod_poly_mul(nmod_poly_t res, nmod_poly_t poly1, nmod_poly_t poly2) 100 cdef void nmod_poly_mullow(nmod_poly_t res, nmod_poly_t poly1, nmod_poly_t poly2, long trunc) 101 cdef void nmod_poly_mulhigh(nmod_poly_t res, nmod_poly_t poly1, nmod_poly_t poly2, long n) 102 cdef void nmod_poly_mulmod(nmod_poly_t res, nmod_poly_t poly1, nmod_poly_t poly2, nmod_poly_t f) 93 103 94 cdef void zmod_poly_attach(zmod_poly_t output, zmod_poly_t input)104 # Powering 95 105 96 # 97 # Attach input shifted right by n to output 98 # 106 cdef void nmod_poly_pow(nmod_poly_t res, nmod_poly_t poly, unsigned long e) 107 cdef void nmod_poly_pow_trunc(nmod_poly_t res, nmod_poly_t poly, unsigned long e, long trunc) 99 108 100 cdef void _zmod_poly_attach_shift(zmod_poly_t output, zmod_poly_t input, unsigned long n)109 # Division 101 110 102 cdef void zmod_poly_attach_shift(zmod_poly_t output, zmod_poly_t input, unsigned long n) 111 cdef void nmod_poly_divrem(nmod_poly_t Q, nmod_poly_t R, nmod_poly_t A, nmod_poly_t B) 112 cdef void nmod_poly_div(nmod_poly_t Q, nmod_poly_t A, nmod_poly_t B) 113 cdef void nmod_poly_inv_series(nmod_poly_t Qinv, nmod_poly_t Q, long n) 114 cdef void nmod_poly_div_series(nmod_poly_t Q, nmod_poly_t A, nmod_poly_t B, long n) 103 115 104 # 105 # Attach input to first n coefficients of input 106 # 116 # Derivative 107 117 108 cdef void _zmod_poly_attach_truncate(zmod_poly_t output, zmod_poly_t input, unsigned long n) 118 cdef void nmod_poly_derivative(nmod_poly_t x_prime, nmod_poly_t x) 119 cdef void nmod_poly_integral(nmod_poly_t x_int, nmod_poly_t x) 109 120 110 cdef void zmod_poly_attach_truncate(zmod_poly_t output, zmod_poly_t input, unsigned long n)121 # Evaluation 111 122 112 # 113 # Comparison functions 114 # 123 cdef mp_limb_t nmod_poly_evaluate_nmod(nmod_poly_t poly, mp_limb_t c) 124 cdef void nmod_poly_evaluate_nmod_vec(mp_ptr ys, nmod_poly_t poly, mp_srcptr xs, long n) 115 125 116 cdef int zmod_poly_equal(zmod_poly_t poly1, zmod_poly_t poly2)126 # Interpolation 117 127 118 cdef int zmod_poly_is_one(zmod_poly_t poly1)128 cdef void nmod_poly_interpolate_nmod_vec(nmod_poly_t poly, mp_srcptr xs, mp_srcptr ys, long n) 119 129 120 # 121 # Reversal 122 # 130 # Composition 123 131 124 cdef void _zmod_poly_reverse(zmod_poly_t output, zmod_poly_t input, unsigned long length) 125 cdef void zmod_poly_reverse(zmod_poly_t output, zmod_poly_t input, unsigned long length) 132 cdef void nmod_poly_compose(nmod_poly_t res, nmod_poly_t poly1, nmod_poly_t poly2) 126 133 127 # 128 # Monic polys 129 # 134 # Power series composition and reversion 130 135 131 cdef void zmod_poly_make_monic(zmod_poly_t output, zmod_poly_t pol) 136 cdef void nmod_poly_compose_series(nmod_poly_t res, nmod_poly_t poly1, nmod_poly_t poly2, long n) 137 cdef void nmod_poly_reverse_series(nmod_poly_t Qinv, nmod_poly_t Q, long n) 132 138 133 # 134 # Addition and subtraction 135 # 139 # GCD 136 140 137 cdef void zmod_poly_add(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2) 138 cdef void zmod_poly_add_without_mod(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2) 139 cdef void zmod_poly_sub(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2) 140 cdef void _zmod_poly_sub(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2) 141 cdef void zmod_poly_neg(zmod_poly_t res, zmod_poly_t poly) 141 cdef void nmod_poly_gcd(nmod_poly_t G, nmod_poly_t A, nmod_poly_t B) 142 cdef void nmod_poly_xgcd(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T, nmod_poly_t A, nmod_poly_t B) 143 mp_limb_t nmod_poly_resultant(nmod_poly_t f, nmod_poly_t g) 142 144 143 # 144 # Shifting functions 145 # 145 # Square roots 146 146 147 cdef void zmod_poly_left_shift(zmod_poly_t res, zmod_poly_t poly, unsigned long k) 148 cdef void zmod_poly_right_shift(zmod_poly_t res, zmod_poly_t poly, unsigned long k) 147 cdef void nmod_poly_invsqrt_series(nmod_poly_t g, nmod_poly_t h, long n) 148 cdef void nmod_poly_sqrt_series(nmod_poly_t g, nmod_poly_t h, long n) 149 int nmod_poly_sqrt(nmod_poly_t b, nmod_poly_t a) 149 150 150 # 151 # Polynomial multiplication 152 # 153 # All multiplication functions require that the modulus be no more than FLINT_BITS-1 bits 154 # 151 # Transcendental functions 155 152 156 cdef void zmod_poly_mul(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2) 157 cdef void zmod_poly_sqr(zmod_poly_t res, zmod_poly_t poly) 153 cdef void nmod_poly_atan_series(nmod_poly_t g, nmod_poly_t h, long n) 154 cdef void nmod_poly_tan_series(nmod_poly_t g, nmod_poly_t h, long n) 155 cdef void nmod_poly_asin_series(nmod_poly_t g, nmod_poly_t h, long n) 156 cdef void nmod_poly_sin_series(nmod_poly_t g, nmod_poly_t h, long n) 157 cdef void nmod_poly_cos_series(nmod_poly_t g, nmod_poly_t h, long n) 158 cdef void nmod_poly_asinh_series(nmod_poly_t g, nmod_poly_t h, long n) 159 cdef void nmod_poly_atanh_series(nmod_poly_t g, nmod_poly_t h, long n) 160 cdef void nmod_poly_sinh_series(nmod_poly_t g, nmod_poly_t h, long n) 161 cdef void nmod_poly_cosh_series(nmod_poly_t g, nmod_poly_t h, long n) 162 cdef void nmod_poly_tanh_series(nmod_poly_t g, nmod_poly_t h, long n) 163 cdef void nmod_poly_log_series(nmod_poly_t res, nmod_poly_t f, long n) 164 cdef void nmod_poly_exp_series(nmod_poly_t f, nmod_poly_t h, long) 158 165 159 # Requires that poly1 bits + poly2 bits + log_length is not greater than 2*FLINT_BITS166 # Inflation and deflation 160 167 161 cdef void zmod_poly_mul_KS(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long bits_input) 162 cdef void _zmod_poly_mul_KS(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long bits_input) 168 cdef unsigned long nmod_poly_deflation(nmod_poly_t input) 169 cdef void nmod_poly_deflate(nmod_poly_t result, nmod_poly_t input, unsigned long deflation) 170 cdef void nmod_poly_inflate(nmod_poly_t result, nmod_poly_t input, unsigned long inflation) 163 171 164 cdef void zmod_poly_mul_KS_trunc(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long bits_input, unsigned long trunc) 165 cdef void _zmod_poly_mul_KS_trunc(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long bits_input, unsigned long trunc) 172 # Factoring 166 173 167 cdef void _zmod_poly_mul_classical(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2) 168 cdef void __zmod_poly_mul_classical_mod_last(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long bits) 169 cdef void __zmod_poly_mul_classical_mod_throughout(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long bits) 170 cdef void zmod_poly_mul_classical(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2) 171 cdef void _zmod_poly_sqr_classical(zmod_poly_t res, zmod_poly_t poly) 172 cdef void zmod_poly_sqr_classical(zmod_poly_t res, zmod_poly_t poly) 173 174 cdef void _zmod_poly_mul_classical_trunc(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long trunc) 175 cdef void __zmod_poly_mul_classical_trunc_mod_last(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long bits, unsigned long trunc) 176 cdef void __zmod_poly_mul_classical_trunc_mod_throughout(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long bits, unsigned long trunc) 177 cdef void zmod_poly_mul_classical_trunc(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long trunc) 178 179 cdef void _zmod_poly_mul_classical_trunc_left(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long trunc) 180 cdef void __zmod_poly_mul_classical_trunc_left_mod_last(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long bits, unsigned long trunc) 181 cdef void __zmod_poly_mul_classical_trunc_left_mod_throughout(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long bits, unsigned long trunc) 182 cdef void zmod_poly_mul_classical_trunc_left(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long trunc) 183 184 cdef void zmod_poly_mul_trunc_n(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long trunc) 185 cdef void zmod_poly_mul_trunc_left_n(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, unsigned long trunc) 186 187 # 188 # Bit packing functions 189 # 190 191 cdef unsigned long zmod_poly_bits(zmod_poly_t poly) 192 cdef void _zmod_poly_bit_pack_mpn(mp_limb_t * res, zmod_poly_t poly, unsigned long bits, unsigned long length) 193 cdef void _zmod_poly_bit_unpack_mpn(zmod_poly_t poly, mp_limb_t *mpn, unsigned long length, unsigned long bits) 194 195 cdef void print_binary(unsigned long n, unsigned long len) 196 cdef void print_binary2(unsigned long n, unsigned long len, unsigned long space_bit) 197 198 # 199 # Scalar multiplication 200 # 201 202 cdef void _zmod_poly_scalar_mul(zmod_poly_t res, zmod_poly_t poly, unsigned long scalar) 203 cdef void zmod_poly_scalar_mul(zmod_poly_t res, zmod_poly_t poly, unsigned long scalar) 204 cdef void __zmod_poly_scalar_mul_without_mod(zmod_poly_t res, zmod_poly_t poly, unsigned long scalar) 205 206 # 207 # Division 208 # 209 210 cdef void zmod_poly_divrem_classical(zmod_poly_t Q, zmod_poly_t R, zmod_poly_t A, zmod_poly_t B) 211 cdef void __zmod_poly_divrem_classical_mod_last(zmod_poly_t Q, zmod_poly_t R, zmod_poly_t A, zmod_poly_t B) 212 cdef void zmod_poly_div_classical(zmod_poly_t Q, zmod_poly_t A, zmod_poly_t B) 213 cdef void __zmod_poly_div_classical_mod_last(zmod_poly_t Q, zmod_poly_t A, zmod_poly_t B) 214 cdef void zmod_poly_div_divconquer_recursive(zmod_poly_t Q, zmod_poly_t BQ, zmod_poly_t A, zmod_poly_t B) 215 cdef void zmod_poly_divrem_divconquer(zmod_poly_t Q, zmod_poly_t R, zmod_poly_t A, zmod_poly_t B) 216 cdef void zmod_poly_div_divconquer(zmod_poly_t Q, zmod_poly_t A, zmod_poly_t B) 217 218 # 219 # Newton Inversion 220 # 221 222 cdef void zmod_poly_newton_invert_basecase(zmod_poly_t Q_inv, zmod_poly_t Q, unsigned long n) 223 cdef void zmod_poly_newton_invert(zmod_poly_t Q_inv, zmod_poly_t Q, unsigned long n) 224 225 # 226 # Newton Division 227 # 228 229 cdef void zmod_poly_div_series(zmod_poly_t Q, zmod_poly_t A, zmod_poly_t B, unsigned long n) 230 cdef void zmod_poly_div_newton(zmod_poly_t Q, zmod_poly_t A, zmod_poly_t B) 231 cdef void zmod_poly_divrem_newton(zmod_poly_t Q, zmod_poly_t R, zmod_poly_t A, zmod_poly_t B) 232 233 cdef void zmod_poly_divrem(zmod_poly_t Q, zmod_poly_t R, zmod_poly_t A, zmod_poly_t B) 234 235 cdef void zmod_poly_div(zmod_poly_t Q, zmod_poly_t A, zmod_poly_t B) 236 237 # 238 # Resultant 239 # 240 241 cdef unsigned long zmod_poly_resultant_euclidean(zmod_poly_t a, zmod_poly_t b) 242 243 cdef unsigned long zmod_poly_resultant(zmod_poly_t a, zmod_poly_t b) 244 245 # 246 # GCD 247 # 248 249 cdef void zmod_poly_gcd(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2) 250 cdef int zmod_poly_gcd_invert(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2) 251 cdef void zmod_poly_xgcd(zmod_poly_t res, zmod_poly_t s, zmod_poly_t t, zmod_poly_t poly1, zmod_poly_t poly2) 252 253 254 255 # Composition / evaluation 256 257 cdef unsigned long zmod_poly_evaluate(zmod_poly_t, unsigned long) 258 cdef void zmod_poly_compose_horner(zmod_poly_t, zmod_poly_t, zmod_poly_t) 259 260 # Factorization 261 262 cdef bint zmod_poly_isirreducible(zmod_poly_t p) 263 264 ctypedef struct zmod_poly_factors_struct: 265 unsigned long num_factors 266 unsigned long* exponents 267 zmod_poly_t* factors 268 269 ctypedef zmod_poly_factors_struct* zmod_poly_factor_t 270 271 cdef void zmod_poly_factor_init(zmod_poly_factor_t) 272 cdef void zmod_poly_factor_clear(zmod_poly_factor_t) 273 cdef unsigned long zmod_poly_factor(zmod_poly_factor_t, zmod_poly_t) 274 cdef void zmod_poly_factor_square_free(zmod_poly_factor_t, zmod_poly_t) 275 cdef void zmod_poly_factor_berlekamp(zmod_poly_factor_t factors, zmod_poly_t f) 276 277 cdef void zmod_poly_factor_add(zmod_poly_factor_t fac, zmod_poly_t poly) 278 cdef void zmod_poly_factor_concat(zmod_poly_factor_t res, zmod_poly_factor_t fac) 279 cdef void zmod_poly_factor_print(zmod_poly_factor_t fac) 280 cdef void zmod_poly_factor_pow(zmod_poly_factor_t fac, unsigned long exp) 281 282 # 283 # Differentiation 284 # 285 286 cdef void zmod_poly_derivative(zmod_poly_t res, zmod_poly_t poly) 287 288 # 289 # Arithmetic modulo a polynomial 290 # 291 292 cdef void zmod_poly_mulmod(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, zmod_poly_t f) 293 cdef void zmod_poly_powmod(zmod_poly_t res,zmod_poly_t pol, long exp, zmod_poly_t f) 174 cdef void nmod_poly_factor_clear(nmod_poly_factor_t fac) 175 cdef void nmod_poly_factor_init(nmod_poly_factor_t fac) 176 cdef void nmod_poly_factor_insert(nmod_poly_factor_t fac, nmod_poly_t poly, unsigned long exp) 177 cdef void nmod_poly_factor_print(nmod_poly_factor_t fac) 178 cdef void nmod_poly_factor_concat(nmod_poly_factor_t res, nmod_poly_factor_t fac) 179 cdef void nmod_poly_factor_pow(nmod_poly_factor_t fac, unsigned long exp) 180 cdef unsigned long nmod_poly_remove(nmod_poly_t f, nmod_poly_t p) 181 cdef int nmod_poly_is_irreducible(nmod_poly_t f) 182 cdef int nmod_poly_is_squarefree(nmod_poly_t f) 183 cdef void nmod_poly_factor_cantor_zassenhaus(nmod_poly_factor_t res, nmod_poly_t f) 184 cdef void nmod_poly_factor_berlekamp(nmod_poly_factor_t factors, nmod_poly_t f) 185 cdef void nmod_poly_factor_squarefree(nmod_poly_factor_t res, nmod_poly_t f) 186 cdef mp_limb_t nmod_poly_factor_with_berlekamp(nmod_poly_factor_t result, nmod_poly_t input) 187 cdef mp_limb_t nmod_poly_factor_with_cantor_zassenhaus(nmod_poly_factor_t result, nmod_poly_t input) 188 cdef mp_limb_t nmod_poly_factor(nmod_poly_factor_t result, nmod_poly_t input) -
sage/libs/flint/zmod_poly_linkage.pxi
diff --git a/sage/libs/flint/zmod_poly_linkage.pxi b/sage/libs/flint/zmod_poly_linkage.pxi
a b 17 17 # http://www.gnu.org/licenses/ 18 18 #***************************************************************************** 19 19 20 from sage.libs.flint.zmod_poly cimport *, zmod_poly_t21 from sage.libs.flint. long_extras cimport *20 from sage.libs.flint.zmod_poly cimport *, nmod_poly_t 21 from sage.libs.flint.ulong_extras cimport * 22 22 23 23 include "../../ext/stdsage.pxi" 24 24 25 25 cdef inline celement *celement_new(unsigned long n): 26 cdef celement *g = <celement *>sage_malloc(sizeof( zmod_poly_t))27 zmod_poly_init(g, n)26 cdef celement *g = <celement *>sage_malloc(sizeof(nmod_poly_t)) 27 nmod_poly_init(g, n) 28 28 return g 29 29 30 cdef inline int celement_delete( zmod_poly_t e, unsigned long n):31 zmod_poly_clear(e)30 cdef inline int celement_delete(nmod_poly_t e, unsigned long n): 31 nmod_poly_clear(e) 32 32 sage_free(e) 33 33 34 cdef inline int celement_construct( zmod_poly_t e, unsigned long n):34 cdef inline int celement_construct(nmod_poly_t e, unsigned long n): 35 35 """ 36 36 EXAMPLE: 37 37 sage: P.<x> = GF(32003)[] 38 38 39 39 sage: Q.<x> = GF(7)[] 40 40 """ 41 zmod_poly_init(e, n)41 nmod_poly_init(e, n) 42 42 43 cdef inline int celement_destruct( zmod_poly_t e, unsigned long n):43 cdef inline int celement_destruct(nmod_poly_t e, unsigned long n): 44 44 """ 45 45 EXAMPLE: 46 46 sage: P.<x> = GF(32003)[] … … 49 49 sage: Q.<x> = GF(7)[] 50 50 sage: del x 51 51 """ 52 zmod_poly_clear(e)52 nmod_poly_clear(e) 53 53 54 cdef inline int celement_gen( zmod_poly_t e, long i, unsigned long n) except -2:54 cdef inline int celement_gen(nmod_poly_t e, long i, unsigned long n) except -2: 55 55 """ 56 56 EXAMPLE: 57 57 sage: P.<x> = GF(32003)[] 58 58 59 59 sage: Q.<x> = GF(7)[] 60 60 """ 61 zmod_poly_zero(e)62 zmod_poly_set_coeff_ui(e, 1, 1)61 nmod_poly_zero(e) 62 nmod_poly_set_coeff_ui(e, 1, 1) 63 63 64 cdef object celement_repr( zmod_poly_t e, unsigned long n):64 cdef object celement_repr(nmod_poly_t e, unsigned long n): 65 65 raise NotImplementedError 66 66 67 cdef inline int celement_set( zmod_poly_t res, zmod_poly_t a, unsigned long n) except -2:67 cdef inline int celement_set(nmod_poly_t res, nmod_poly_t a, unsigned long n) except -2: 68 68 """ 69 69 EXAMPLE: 70 70 sage: P.<x> = GF(32003)[] … … 89 89 6*x 90 90 """ 91 91 cdef unsigned long i 92 if a. p<= n:93 zmod_poly_set(res, a)92 if a.mod.n <= n: 93 nmod_poly_set(res, a) 94 94 else: 95 zmod_poly_zero(res)95 nmod_poly_zero(res) 96 96 for i from 0 <= i < a.length: 97 zmod_poly_set_coeff_ui(res, i, zmod_poly_get_coeff_ui(a, i) % n)97 nmod_poly_set_coeff_ui(res, i, nmod_poly_get_coeff_ui(a, i) % n) 98 98 99 cdef inline int celement_set_si( zmod_poly_t res, long i, unsigned long n) except -2:99 cdef inline int celement_set_si(nmod_poly_t res, long i, unsigned long n) except -2: 100 100 """ 101 101 EXAMPLE: 102 102 sage: P.<x> = GF(32003)[] … … 117 117 """ 118 118 while i < 0: 119 119 i += n 120 zmod_poly_zero(res)120 nmod_poly_zero(res) 121 121 if i: 122 zmod_poly_set_coeff_ui(res, 0, <unsigned long>i)122 nmod_poly_set_coeff_ui(res, 0, <unsigned long>i) 123 123 124 cdef inline long celement_get_si( zmod_poly_t res, unsigned long n) except -2:124 cdef inline long celement_get_si(nmod_poly_t res, unsigned long n) except -2: 125 125 raise NotImplementedError 126 126 127 cdef inline bint celement_is_zero( zmod_poly_t a, unsigned long n) except -2:127 cdef inline bint celement_is_zero(nmod_poly_t a, unsigned long n) except -2: 128 128 """ 129 129 EXAMPLE: 130 130 sage: P.<x> = GF(32003)[] … … 139 139 sage: Q(0).is_zero() 140 140 True 141 141 """ 142 # is_zero doesn't exist 143 return zmod_poly_degree(a) == -1 142 return nmod_poly_is_zero(a) 144 143 145 cdef inline bint celement_is_one( zmod_poly_t a, unsigned long n) except -2:144 cdef inline bint celement_is_one(nmod_poly_t a, unsigned long n) except -2: 146 145 """ 147 146 EXAMPLE: 148 147 sage: P.<x> = GF(32003)[] … … 158 157 False 159 158 """ 160 159 161 return zmod_poly_is_one(a)160 return nmod_poly_is_one(a) 162 161 163 cdef inline bint celement_equal( zmod_poly_t a, zmod_poly_t b, unsigned long n) except -2:162 cdef inline bint celement_equal(nmod_poly_t a, nmod_poly_t b, unsigned long n) except -2: 164 163 """ 165 164 EXAMPLE: 166 165 sage: P.<x> = GF(32003)[] … … 179 178 sage: (3*2)*x + 7 == 3*(2*x) + 1 + 1 180 179 False 181 180 """ 182 return zmod_poly_equal(a, b)181 return nmod_poly_equal(a, b) 183 182 184 cdef inline int celement_cmp( zmod_poly_t l, zmod_poly_t r, unsigned long n) except -2:183 cdef inline int celement_cmp(nmod_poly_t l, nmod_poly_t r, unsigned long n) except -2: 185 184 """ 186 185 EXAMPLE: 187 186 sage: P.<x> = GF(32003)[] … … 215 214 sage: f < g 216 215 True 217 216 """ 218 cdef int deg_right = zmod_poly_degree(r)219 cdef int degdiff = deg_right - zmod_poly_degree(l)217 cdef int deg_right = nmod_poly_degree(r) 218 cdef int degdiff = deg_right - nmod_poly_degree(l) 220 219 cdef int i 221 220 cdef unsigned long rcoeff, lcoeff 222 221 if degdiff > 0: … … 224 223 elif degdiff < 0: 225 224 return 1 226 225 else: 227 if zmod_poly_equal(l, r):226 if nmod_poly_equal(l, r): 228 227 return 0 229 228 i = deg_right 230 rcoeff = zmod_poly_get_coeff_ui(r, i)231 lcoeff = zmod_poly_get_coeff_ui(l, i)229 rcoeff = nmod_poly_get_coeff_ui(r, i) 230 lcoeff = nmod_poly_get_coeff_ui(l, i) 232 231 while rcoeff == lcoeff and i > 0: 233 232 i -= 1 234 rcoeff = zmod_poly_get_coeff_ui(r, i)235 lcoeff = zmod_poly_get_coeff_ui(l, i)233 rcoeff = nmod_poly_get_coeff_ui(r, i) 234 lcoeff = nmod_poly_get_coeff_ui(l, i) 236 235 return cmp(lcoeff, rcoeff) 237 236 238 cdef long celement_len( zmod_poly_t a, unsigned long n) except -2:237 cdef long celement_len(nmod_poly_t a, unsigned long n) except -2: 239 238 """ 240 239 EXAMPLE: 241 240 sage: P.<x> = GF(32003)[] … … 254 253 sage: P(0).degree() 255 254 -1 256 255 """ 257 return <long> zmod_poly_length(a)256 return <long>nmod_poly_length(a) 258 257 259 cdef inline int celement_add( zmod_poly_t res, zmod_poly_t a, zmod_poly_t b, unsigned long n) except -2:258 cdef inline int celement_add(nmod_poly_t res, nmod_poly_t a, nmod_poly_t b, unsigned long n) except -2: 260 259 """ 261 260 EXAMPLE: 262 261 sage: P.<x> = GF(32003)[] … … 267 266 sage: x + 1 268 267 x + 1 269 268 """ 270 zmod_poly_add(res, a, b)269 nmod_poly_add(res, a, b) 271 270 272 cdef inline int celement_sub( zmod_poly_t res, zmod_poly_t a, zmod_poly_t b, unsigned long n) except -2:271 cdef inline int celement_sub(nmod_poly_t res, nmod_poly_t a, nmod_poly_t b, unsigned long n) except -2: 273 272 """ 274 273 EXAMPLE: 275 274 sage: P.<x> = GF(32003)[] … … 280 279 sage: x - 1 281 280 x + 6 282 281 """ 283 zmod_poly_sub(res, a, b)282 nmod_poly_sub(res, a, b) 284 283 285 cdef inline int celement_neg( zmod_poly_t res, zmod_poly_t a, unsigned long n) except -2:284 cdef inline int celement_neg(nmod_poly_t res, nmod_poly_t a, unsigned long n) except -2: 286 285 """ 287 286 EXAMPLE: 288 287 sage: P.<x> = GF(32003)[] … … 293 292 sage: -(x + 2) 294 293 6*x + 5 295 294 """ 296 zmod_poly_neg(res, a)295 nmod_poly_neg(res, a) 297 296 298 cdef inline int celement_mul_scalar( zmod_poly_t res, zmod_poly_t p,297 cdef inline int celement_mul_scalar(nmod_poly_t res, nmod_poly_t p, 299 298 object c, unsigned long n) except -2: 300 299 """ 301 300 TESTS:: … … 307 306 sage: p*983 308 307 29561*x^2 + 18665*x + 17051 309 308 """ 310 zmod_poly_scalar_mul(res, p, (<unsigned long>c)%n)309 nmod_poly_scalar_mul_nmod(res, p, (<unsigned long>c)%n) 311 310 312 cdef inline int celement_mul( zmod_poly_t res, zmod_poly_t a, zmod_poly_t b, unsigned long n) except -2:311 cdef inline int celement_mul(nmod_poly_t res, nmod_poly_t a, nmod_poly_t b, unsigned long n) except -2: 313 312 """ 314 313 EXAMPLE: 315 314 sage: P.<x> = GF(32003)[] … … 320 319 sage: (x + 1) * (x + 2) 321 320 x^2 + 3*x + 2 322 321 """ 323 zmod_poly_mul(res, a, b)322 nmod_poly_mul(res, a, b) 324 323 325 cdef inline int celement_div( zmod_poly_t res, zmod_poly_t a, zmod_poly_t b, unsigned long n) except -2:324 cdef inline int celement_div(nmod_poly_t res, nmod_poly_t a, nmod_poly_t b, unsigned long n) except -2: 326 325 raise NotImplementedError 327 326 328 cdef inline int celement_floordiv( zmod_poly_t res, zmod_poly_t a, zmod_poly_t b, unsigned long n) except -2:327 cdef inline int celement_floordiv(nmod_poly_t res, nmod_poly_t a, nmod_poly_t b, unsigned long n) except -2: 329 328 """ 330 329 EXAMPLE: 331 330 sage: P.<x> = GF(32003)[] … … 348 347 sage: (x^2 + 3*x + 2)//(x + 2) 349 348 x + 1 350 349 """ 351 zmod_poly_div(res, a, b)350 nmod_poly_div(res, a, b) 352 351 353 cdef inline int celement_mod( zmod_poly_t res, zmod_poly_t a, zmod_poly_t b, unsigned long n) except -2:352 cdef inline int celement_mod(nmod_poly_t res, nmod_poly_t a, nmod_poly_t b, unsigned long n) except -2: 354 353 """ 355 354 EXAMPLE: 356 355 sage: P.<x> = GF(32003)[] … … 381 380 ... 382 381 ZeroDivisionError 383 382 """ 384 cdef zmod_poly_t q383 cdef nmod_poly_t q 385 384 cdef unsigned long leadcoeff, modulus 386 385 387 zmod_poly_init(q, n)388 leadcoeff = zmod_poly_get_coeff_ui(b, zmod_poly_degree(b))389 modulus = zmod_poly_modulus(b)390 if (leadcoeff > 1 and z_gcd(modulus,leadcoeff) != 1):386 nmod_poly_init(q, n) 387 leadcoeff = nmod_poly_get_coeff_ui(b, nmod_poly_degree(b)) 388 modulus = nmod_poly_modulus(b) 389 if (leadcoeff > 1 and n_gcd(modulus,leadcoeff) != 1): 391 390 raise ValueError("Leading coefficient of a must be invertible.") 392 391 393 zmod_poly_divrem(q, res, a, b)394 zmod_poly_clear(q)392 nmod_poly_divrem(q, res, a, b) 393 nmod_poly_clear(q) 395 394 396 cdef inline int celement_quorem( zmod_poly_t q, zmod_poly_t r, zmod_poly_t a, zmod_poly_t b, unsigned long n) except -2:395 cdef inline int celement_quorem(nmod_poly_t q, nmod_poly_t r, nmod_poly_t a, nmod_poly_t b, unsigned long n) except -2: 397 396 """ 398 397 EXAMPLES: 399 398 sage: R.<x> = Integers(125)[] … … 418 417 """ 419 418 cdef unsigned long leadcoeff, modulus 420 419 421 leadcoeff = zmod_poly_get_coeff_ui(b, zmod_poly_degree(b))422 modulus = zmod_poly_modulus(b)423 if (leadcoeff > 1 and z_gcd(modulus,leadcoeff) != 1):420 leadcoeff = nmod_poly_get_coeff_ui(b, nmod_poly_degree(b)) 421 modulus = nmod_poly_modulus(b) 422 if (leadcoeff > 1 and n_gcd(modulus,leadcoeff) != 1): 424 423 raise ValueError("Leading coefficient of a must be invertible.") 425 424 426 zmod_poly_divrem(q, r, a, b)425 nmod_poly_divrem(q, r, a, b) 427 426 428 cdef inline int celement_inv( zmod_poly_t res, zmod_poly_t a, unsigned long n) except -2:427 cdef inline int celement_inv(nmod_poly_t res, nmod_poly_t a, unsigned long n) except -2: 429 428 raise NotImplementedError 430 429 431 cdef inline int celement_pow( zmod_poly_t res, zmod_poly_t x, long e, zmod_poly_t modulus, unsigned long n) except -2:430 cdef inline int celement_pow(nmod_poly_t res, nmod_poly_t x, long e, nmod_poly_t modulus, unsigned long n) except -2: 432 431 """ 433 432 EXAMPLE: 434 433 sage: P.<x> = GF(32003)[] … … 480 479 sage: f^5 % g 481 480 7231*x + 17274 482 481 """ 483 cdef zmod_poly_t pow2484 cdef zmod_poly_t q485 cdef zmod_poly_t tmp482 cdef nmod_poly_t pow2 483 cdef nmod_poly_t q 484 cdef nmod_poly_t tmp 486 485 487 zmod_poly_init(q, n)488 zmod_poly_init(tmp, n)486 nmod_poly_init(q, n) 487 nmod_poly_init(tmp, n) 489 488 490 if zmod_poly_degree(x) == 1 and zmod_poly_get_coeff_ui(x,0) == 0 and zmod_poly_get_coeff_ui(x,1) == 1:491 zmod_poly_zero(res)492 zmod_poly_set_coeff_ui(res,e,1)489 if nmod_poly_degree(x) == 1 and nmod_poly_get_coeff_ui(x,0) == 0 and nmod_poly_get_coeff_ui(x,1) == 1: 490 nmod_poly_zero(res) 491 nmod_poly_set_coeff_ui(res,e,1) 493 492 elif e == 0: 494 zmod_poly_zero(res)495 zmod_poly_set_coeff_ui(res,0,1)493 nmod_poly_zero(res) 494 nmod_poly_set_coeff_ui(res,0,1) 496 495 elif e == 1: 497 zmod_poly_set(res, x)496 nmod_poly_set(res, x) 498 497 elif e == 2: 499 zmod_poly_sqr(res, x)498 nmod_poly_mul(res, x, x) 500 499 else: 501 500 if res == x: 502 zmod_poly_set(tmp, x)501 nmod_poly_set(tmp, x) 503 502 x = tmp 504 zmod_poly_init(pow2, n)505 zmod_poly_set(pow2, x)503 nmod_poly_init(pow2, n) 504 nmod_poly_set(pow2, x) 506 505 if e % 2: 507 zmod_poly_set(res, x)506 nmod_poly_set(res, x) 508 507 else: 509 zmod_poly_zero(res)510 zmod_poly_set_coeff_ui(res, 0, 1)508 nmod_poly_zero(res) 509 nmod_poly_set_coeff_ui(res, 0, 1) 511 510 e = e >> 1 512 511 while(e != 0): 513 zmod_poly_sqr(pow2, pow2)512 nmod_poly_mul(pow2, pow2, pow2) 514 513 if e % 2: 515 zmod_poly_mul(res, res, pow2)514 nmod_poly_mul(res, res, pow2) 516 515 e = e >> 1 517 516 if modulus != NULL: 518 zmod_poly_divrem(q, res, res, modulus)519 zmod_poly_clear(pow2)517 nmod_poly_divrem(q, res, res, modulus) 518 nmod_poly_clear(pow2) 520 519 521 520 if modulus != NULL: 522 zmod_poly_divrem(q, res, res, modulus)523 zmod_poly_clear(q)524 zmod_poly_clear(tmp)521 nmod_poly_divrem(q, res, res, modulus) 522 nmod_poly_clear(q) 523 nmod_poly_clear(tmp) 525 524 526 cdef inline int celement_gcd( zmod_poly_t res, zmod_poly_t a, zmod_poly_t b, unsigned long n) except -2:525 cdef inline int celement_gcd(nmod_poly_t res, nmod_poly_t a, nmod_poly_t b, unsigned long n) except -2: 527 526 """ 528 527 EXAMPLE: 529 528 sage: P.<x> = GF(32003)[] … … 563 562 True 564 563 """ 565 564 if celement_is_zero(b, n): 566 zmod_poly_set(res, a)565 nmod_poly_set(res, a) 567 566 return 0 568 567 569 zmod_poly_gcd(res, a, b)570 cdef unsigned long leadcoeff = zmod_poly_get_coeff_ui(res, zmod_poly_degree(res))571 cdef unsigned long modulus = zmod_poly_modulus(res)572 if z_gcd(modulus,leadcoeff) == 1:573 zmod_poly_make_monic(res, res)568 nmod_poly_gcd(res, a, b) 569 cdef unsigned long leadcoeff = nmod_poly_get_coeff_ui(res, nmod_poly_degree(res)) 570 cdef unsigned long modulus = nmod_poly_modulus(res) 571 if n_gcd(modulus,leadcoeff) == 1: 572 nmod_poly_make_monic(res, res) 574 573 575 cdef inline int celement_xgcd( zmod_poly_t res, zmod_poly_t s, zmod_poly_t t, zmod_poly_t a, zmod_poly_t b, unsigned long n) except -2:574 cdef inline int celement_xgcd(nmod_poly_t res, nmod_poly_t s, nmod_poly_t t, nmod_poly_t a, nmod_poly_t b, unsigned long n) except -2: 576 575 """ 577 576 EXAMPLE: 578 577 sage: P.<x> = GF(32003)[] … … 611 610 sage: (G//d)*d == G 612 611 True 613 612 """ 614 zmod_poly_xgcd(res, s, t, a, b)613 nmod_poly_xgcd(res, s, t, a, b) 615 614 616 615 617 616 cdef factor_helper(Polynomial_zmod_flint poly, bint squarefree=False): … … 624 623 sage: (prod(P.random_element()^i for i in range(5))).squarefree_decomposition() 625 624 (54) * (x^2 + 55*x + 839) * (x^2 + 48*x + 496)^2 * (x^2 + 435*x + 104)^3 * (x^2 + 176*x + 156)^4 626 625 """ 627 cdef zmod_poly_factor_t factors_c628 zmod_poly_factor_init(factors_c)626 cdef nmod_poly_factor_t factors_c 627 nmod_poly_factor_init(factors_c) 629 628 630 629 if squarefree: 631 zmod_poly_factor_square_free(factors_c, &poly.x)630 nmod_poly_factor_squarefree(factors_c, &poly.x) 632 631 else: 633 zmod_poly_factor(factors_c, &poly.x)632 nmod_poly_factor(factors_c, &poly.x) 634 633 635 634 factor_list = [] 636 635 cdef Polynomial_zmod_flint t 637 for i in range(factors_c.num _factors):636 for i in range(factors_c.num): 638 637 t = poly._new() 639 zmod_poly_swap(&t.x, factors_c.factors[i])640 factor_list.append((t, factors_c.exp onents[i]))638 nmod_poly_swap(&t.x, &factors_c.p[i]) 639 factor_list.append((t, factors_c.exp[i])) 641 640 642 zmod_poly_factor_clear(factors_c)641 nmod_poly_factor_clear(factors_c) 643 642 644 643 return Factorization(factor_list, unit=poly.leading_coefficient(), 645 644 sort=(not squarefree)) -
sage/modular/modsym/apply.pyx
diff --git a/sage/modular/modsym/apply.pyx b/sage/modular/modsym/apply.pyx
a b 54 54 fmpz_poly_set_coeff_si(self.g, 1, c) 55 55 56 56 # h = (f**i)*(g**(j-i)) 57 fmpz_poly_pow er(self.ff, self.f, i)58 fmpz_poly_pow er(self.gg, self.g, j-i)57 fmpz_poly_pow(self.ff, self.f, i) 58 fmpz_poly_pow(self.gg, self.g, j-i) 59 59 fmpz_poly_mul(ans, self.ff, self.gg) 60 60 61 61 return 0 -
sage/rings/fraction_field_FpT.pxd
diff --git a/sage/rings/fraction_field_FpT.pxd b/sage/rings/fraction_field_FpT.pxd
a b 7 7 from sage.categories.map cimport Section 8 8 9 9 cdef class FpTElement(RingElement): 10 cdef zmod_poly_t _numer, _denom10 cdef nmod_poly_t _numer, _denom 11 11 cdef bint initalized 12 12 cdef long p 13 13 … … 23 23 cdef parent 24 24 cdef long degree 25 25 cdef FpTElement cur 26 cdef zmod_poly_t g26 cdef nmod_poly_t g -
sage/rings/fraction_field_FpT.pyx
diff --git a/sage/rings/fraction_field_FpT.pyx b/sage/rings/fraction_field_FpT.pyx
a b 105 105 numer = parent.poly_ring(numer) 106 106 denom = parent.poly_ring(denom) 107 107 self.p = parent.p 108 zmod_poly_init(self._numer, self.p)109 zmod_poly_init(self._denom, self.p)108 nmod_poly_init(self._numer, self.p) 109 nmod_poly_init(self._denom, self.p) 110 110 self.initalized = True 111 111 cdef long n 112 112 for n, a in enumerate(numer): 113 zmod_poly_set_coeff_ui(self._numer, n, a)113 nmod_poly_set_coeff_ui(self._numer, n, a) 114 114 for n, a in enumerate(denom): 115 zmod_poly_set_coeff_ui(self._denom, n, a)115 nmod_poly_set_coeff_ui(self._denom, n, a) 116 116 if reduce: 117 117 normalize(self._numer, self._denom, self.p) 118 118 … … 127 127 sage: del t # indirect doctest 128 128 """ 129 129 if self.initalized: 130 zmod_poly_clear(self._numer)131 zmod_poly_clear(self._denom)130 nmod_poly_clear(self._numer) 131 nmod_poly_clear(self._denom) 132 132 133 133 def __reduce__(self): 134 134 """ … … 152 152 cdef FpTElement x = <FpTElement>PY_NEW(FpTElement) 153 153 x._parent = self._parent 154 154 x.p = self.p 155 zmod_poly_init_precomp(x._numer, x.p, self._numer.p_inv)156 zmod_poly_init_precomp(x._denom, x.p, self._numer.p_inv)155 nmod_poly_init_preinv(x._numer, x.p, self._numer.mod.ninv) 156 nmod_poly_init_preinv(x._denom, x.p, self._numer.mod.ninv) 157 157 x.initalized = True 158 158 return x 159 159 … … 164 164 cdef FpTElement x = <FpTElement>PY_NEW(FpTElement) 165 165 x._parent = self._parent 166 166 x.p = self.p 167 zmod_poly_init2_precomp(x._numer, x.p, self._numer.p_inv, self._numer.length)168 zmod_poly_init2_precomp(x._denom, x.p, self._denom.p_inv, self._denom.length)169 zmod_poly_set(x._numer, self._numer)170 zmod_poly_set(x._denom, self._denom)167 nmod_poly_init2_preinv(x._numer, x.p, self._numer.mod.ninv, self._numer.length) 168 nmod_poly_init2_preinv(x._denom, x.p, self._denom.mod.ninv, self._denom.length) 169 nmod_poly_set(x._numer, self._numer) 170 nmod_poly_set(x._denom, self._denom) 171 171 x.initalized = True 172 172 return x 173 173 … … 196 196 t^6 + 3*t^4 + 10*t^3 + 3*t^2 + 1 197 197 """ 198 198 cdef Polynomial_zmod_flint res = <Polynomial_zmod_flint>PY_NEW(Polynomial_zmod_flint) 199 zmod_poly_init2_precomp(&res.x, self.p, self._numer.p_inv, self._numer.length)200 zmod_poly_set(&res.x, self._numer)199 nmod_poly_init2_preinv(&res.x, self.p, self._numer.mod.ninv, self._numer.length) 200 nmod_poly_set(&res.x, self._numer) 201 201 res._parent = self._parent.poly_ring 202 202 res._cparent = get_cparent(self._parent.poly_ring) 203 203 return res … … 227 227 t^3 228 228 """ 229 229 cdef Polynomial_zmod_flint res = <Polynomial_zmod_flint>PY_NEW(Polynomial_zmod_flint) 230 zmod_poly_init2_precomp(&res.x, self.p, self._denom.p_inv, self._denom.length)231 zmod_poly_set(&res.x, self._denom)230 nmod_poly_init2_preinv(&res.x, self.p, self._denom.mod.ninv, self._denom.length) 231 nmod_poly_set(&res.x, self._denom) 232 232 res._parent = self._parent.poly_ring 233 233 res._cparent = get_cparent(self._parent.poly_ring) 234 234 return res … … 315 315 sage: (1-t)/t 316 316 (16*t + 1)/t 317 317 """ 318 if zmod_poly_degree(self._denom) == 0 and zmod_poly_get_coeff_ui(self._denom, 0) == 1:318 if nmod_poly_degree(self._denom) == 0 and nmod_poly_get_coeff_ui(self._denom, 0) == 1: 319 319 return repr(self.numer()) 320 320 else: 321 321 numer_s = repr(self.numer()) … … 338 338 sage: latex((t + 1)/(t-1)) 339 339 \frac{t + 1}{t + 6} 340 340 """ 341 if zmod_poly_degree(self._denom) == 0 and zmod_poly_get_coeff_ui(self._denom, 0) == 1:341 if nmod_poly_degree(self._denom) == 0 and nmod_poly_get_coeff_ui(self._denom, 0) == 1: 342 342 return self.numer()._latex_() 343 343 else: 344 344 return "\\frac{%s}{%s}" % (self.numer()._latex_(), self.denom()._latex_()) … … 391 391 False 392 392 """ 393 393 # They are normalized. 394 cdef int j = sage_cmp_ zmod_poly_t(self._numer, (<FpTElement>other)._numer)394 cdef int j = sage_cmp_nmod_poly_t(self._numer, (<FpTElement>other)._numer) 395 395 if j: return j 396 return sage_cmp_ zmod_poly_t(self._denom, (<FpTElement>other)._denom)396 return sage_cmp_nmod_poly_t(self._denom, (<FpTElement>other)._denom) 397 397 398 398 def __hash__(self): 399 399 """ … … 428 428 (4*t^2 + 3)/(t + 4) 429 429 """ 430 430 cdef FpTElement x = self._copy_c() 431 zmod_poly_neg(x._numer, x._numer)431 nmod_poly_neg(x._numer, x._numer) 432 432 return x 433 433 434 434 def __invert__(self): … … 442 442 sage: ~a # indirect doctest 443 443 (t + 4)/(t^2 + 2) 444 444 """ 445 if zmod_poly_degree(self._numer) == -1:445 if nmod_poly_degree(self._numer) == -1: 446 446 raise ZeroDivisionError 447 447 cdef FpTElement x = self._copy_c() 448 zmod_poly_swap(x._numer, x._denom)448 nmod_poly_swap(x._numer, x._denom) 449 449 return x 450 450 451 451 cpdef ModuleElement _add_(self, ModuleElement _other): … … 469 469 """ 470 470 cdef FpTElement other = <FpTElement>_other 471 471 cdef FpTElement x = self._new_c() 472 zmod_poly_mul(x._numer, self._numer, other._denom)473 zmod_poly_mul(x._denom, self._denom, other._numer) # use x._denom as a temp474 zmod_poly_add(x._numer, x._numer, x._denom)475 zmod_poly_mul(x._denom, self._denom, other._denom)472 nmod_poly_mul(x._numer, self._numer, other._denom) 473 nmod_poly_mul(x._denom, self._denom, other._numer) # use x._denom as a temp 474 nmod_poly_add(x._numer, x._numer, x._denom) 475 nmod_poly_mul(x._denom, self._denom, other._denom) 476 476 normalize(x._numer, x._denom, self.p) 477 477 return x 478 478 … … 491 491 """ 492 492 cdef FpTElement other = <FpTElement>_other 493 493 cdef FpTElement x = self._new_c() 494 zmod_poly_mul(x._numer, self._numer, other._denom)495 zmod_poly_mul(x._denom, self._denom, other._numer) # use x._denom as a temp496 zmod_poly_sub(x._numer, x._numer, x._denom)497 zmod_poly_mul(x._denom, self._denom, other._denom)494 nmod_poly_mul(x._numer, self._numer, other._denom) 495 nmod_poly_mul(x._denom, self._denom, other._numer) # use x._denom as a temp 496 nmod_poly_sub(x._numer, x._numer, x._denom) 497 nmod_poly_mul(x._denom, self._denom, other._denom) 498 498 normalize(x._numer, x._denom, self.p) 499 499 return x 500 500 … … 513 513 """ 514 514 cdef FpTElement other = <FpTElement>_other 515 515 cdef FpTElement x = self._new_c() 516 zmod_poly_mul(x._numer, self._numer, other._numer)517 zmod_poly_mul(x._denom, self._denom, other._denom)516 nmod_poly_mul(x._numer, self._numer, other._numer) 517 nmod_poly_mul(x._denom, self._denom, other._denom) 518 518 normalize(x._numer, x._denom, self.p) 519 519 return x 520 520 … … 534 534 t + 1 535 535 """ 536 536 cdef FpTElement other = <FpTElement>_other 537 if zmod_poly_degree(other._numer) == -1:537 if nmod_poly_degree(other._numer) == -1: 538 538 raise ZeroDivisionError 539 539 cdef FpTElement x = self._new_c() 540 zmod_poly_mul(x._numer, self._numer, other._denom)541 zmod_poly_mul(x._denom, self._denom, other._numer)540 nmod_poly_mul(x._numer, self._numer, other._denom) 541 nmod_poly_mul(x._denom, self._denom, other._numer) 542 542 normalize(x._numer, x._denom, self.p) 543 543 return x 544 544 … … 603 603 """ 604 604 cdef FpTElement next = self._copy_c() 605 605 cdef long a, lead 606 cdef zmod_poly_t g607 if zmod_poly_degree(self._numer) == -1:606 cdef nmod_poly_t g 607 if nmod_poly_degree(self._numer) == -1: 608 608 # self should be normalized, so denom == 1 609 zmod_poly_set_coeff_ui(next._numer, 0, 1)609 nmod_poly_set_coeff_ui(next._numer, 0, 1) 610 610 return next 611 lead = zmod_poly_leading(next._numer)611 lead = nmod_poly_leading(next._numer) 612 612 if lead < self.p - 1: 613 613 a = mod_inverse_int(lead, self.p) 614 614 # no overflow since self.p < 2^16 615 615 a = a * (lead + 1) % self.p 616 zmod_poly_scalar_mul(next._numer, next._numer, a)616 nmod_poly_scalar_mul_nmod(next._numer, next._numer, a) 617 617 else: 618 618 a = mod_inverse_int(lead, self.p) 619 zmod_poly_scalar_mul(next._numer, next._numer, a)619 nmod_poly_scalar_mul_nmod(next._numer, next._numer, a) 620 620 # now both next._numer and next._denom are monic. We figure out which is lexicographically bigger: 621 a = zmod_poly_cmp(next._numer, next._denom)621 a = nmod_poly_cmp(next._numer, next._denom) 622 622 if a == 0: 623 623 # next._numer and next._denom are relatively prime, so they're both 1. 624 zmod_poly_inc(next._denom, True)624 nmod_poly_inc(next._denom, True) 625 625 return next 626 zmod_poly_set(next._denom, next._numer)627 zmod_poly_set(next._numer, self._denom)626 nmod_poly_set(next._denom, next._numer) 627 nmod_poly_set(next._numer, self._denom) 628 628 if a < 0: 629 629 # since next._numer is smaller, we flip and return the inverse. 630 630 return next 631 631 elif a > 0: 632 632 # since next._numer is bigger, we're in the flipped phase. We flip back, and increment the numerator (until we reach the denominator). 633 zmod_poly_init(g, self.p)633 nmod_poly_init(g, self.p) 634 634 try: 635 635 while True: 636 zmod_poly_inc(next._numer, True)637 if zmod_poly_equal(next._numer, next._denom):636 nmod_poly_inc(next._numer, True) 637 if nmod_poly_equal(next._numer, next._denom): 638 638 # Since we've reached the denominator, we reset the numerator to 1 and increment the denominator. 639 zmod_poly_inc(next._denom, True)640 zmod_poly_zero(next._numer)641 zmod_poly_set_coeff_ui(next._numer, 0, 1)639 nmod_poly_inc(next._denom, True) 640 nmod_poly_zero(next._numer) 641 nmod_poly_set_coeff_ui(next._numer, 0, 1) 642 642 break 643 643 else: 644 644 # otherwise, we keep incrementing until we have a relatively prime numerator. 645 zmod_poly_gcd(g, next._numer, next._denom)646 if zmod_poly_is_one(g):645 nmod_poly_gcd(g, next._numer, next._denom) 646 if nmod_poly_is_one(g): 647 647 break 648 648 finally: 649 zmod_poly_clear(g)649 nmod_poly_clear(g) 650 650 return next 651 651 652 652 cpdef _sqrt_or_None(self): … … 686 686 [] 687 687 688 688 """ 689 if zmod_poly_degree(self._numer) == -1:689 if nmod_poly_degree(self._numer) == -1: 690 690 return self 691 if not zmod_poly_sqrt_check(self._numer) or not zmod_poly_sqrt_check(self._denom): 692 return None 693 cdef zmod_poly_t numer 694 cdef zmod_poly_t denom 691 cdef nmod_poly_t numer 692 cdef nmod_poly_t denom 695 693 cdef FpTElement res 696 try: 697 zmod_poly_init(denom, self.p) 698 zmod_poly_init(numer, self.p) 699 if not zmod_poly_sqrt0(numer, self._numer): 700 return None 701 if not zmod_poly_sqrt0(denom, self._denom): 702 return None 694 695 nmod_poly_init(denom, self.p) 696 nmod_poly_init(numer, self.p) 697 698 if nmod_poly_sqrt(numer, self._numer) and nmod_poly_sqrt(denom, self._denom): 703 699 res = self._new_c() 704 zmod_poly_swap(numer, res._numer)705 zmod_poly_swap(denom, res._denom)700 nmod_poly_swap(numer, res._numer) 701 nmod_poly_swap(denom, res._denom) 706 702 return res 707 finally: 708 zmod_poly_clear(numer) 709 zmod_poly_clear(denom) 710 703 else: 704 nmod_poly_clear(numer) 705 nmod_poly_clear(denom) 706 return None 707 711 708 cpdef bint is_square(self): 712 709 """ 713 710 Returns True if this element is the square of another element of the fraction field. … … 792 789 assert dummy is None 793 790 cdef FpTElement x = self._new_c() 794 791 if e >= 0: 795 zmod_poly_pow(x._numer, self._numer, e)796 zmod_poly_pow(x._denom, self._denom, e)792 nmod_poly_pow(x._numer, self._numer, e) 793 nmod_poly_pow(x._denom, self._denom, e) 797 794 else: 798 zmod_poly_pow(x._denom, self._numer, -e)799 zmod_poly_pow(x._numer, self._denom, -e)800 if zmod_poly_leading(x._denom) != 1:801 a = mod_inverse_int( zmod_poly_leading(x._denom), self.p)802 zmod_poly_scalar_mul(x._numer, x._numer, a)803 zmod_poly_scalar_mul(x._denom, x._denom, a)795 nmod_poly_pow(x._denom, self._numer, -e) 796 nmod_poly_pow(x._numer, self._denom, -e) 797 if nmod_poly_leading(x._denom) != 1: 798 a = mod_inverse_int(nmod_poly_leading(x._denom), self.p) 799 nmod_poly_scalar_mul_nmod(x._numer, x._numer, a) 800 nmod_poly_scalar_mul_nmod(x._denom, x._denom, a) 804 801 return x 805 802 806 803 … … 878 875 sage: I 879 876 <sage.rings.fraction_field_FpT.FpT_iter object at ...> 880 877 """ 881 zmod_poly_init(self.g, parent.characteristic())878 nmod_poly_init(self.g, parent.characteristic()) 882 879 883 880 def __dealloc__(self): 884 881 """ … … 891 888 sage: I = FpT_iter(K, 3) 892 889 sage: del I # indirect doctest 893 890 """ 894 zmod_poly_clear(self.g)891 nmod_poly_clear(self.g) 895 892 896 893 def __iter__(self): 897 894 """ … … 971 968 next = self.cur._copy_c() 972 969 sig_on() 973 970 while True: 974 zmod_poly_inc(next._numer, False)975 if zmod_poly_degree(next._numer) > self.degree:976 zmod_poly_inc(next._denom, True)977 if zmod_poly_degree(next._denom) > self.degree:971 nmod_poly_inc(next._numer, False) 972 if nmod_poly_degree(next._numer) > self.degree: 973 nmod_poly_inc(next._denom, True) 974 if nmod_poly_degree(next._denom) > self.degree: 978 975 sig_off() 979 976 raise StopIteration 980 zmod_poly_zero(next._numer)981 zmod_poly_set_coeff_ui(next._numer, 0, 1)982 zmod_poly_gcd(self.g, next._numer, next._denom)983 if zmod_poly_is_one(self.g):977 nmod_poly_zero(next._numer) 978 nmod_poly_set_coeff_ui(next._numer, 0, 1) 979 nmod_poly_gcd(self.g, next._numer, next._denom) 980 if nmod_poly_is_one(self.g): 984 981 break 985 982 sig_off() 986 983 self.cur = next 987 984 # self.cur = self.cur.next() 988 # if zmod_poly_degree(self.cur._numer) > self.degree:985 # if nmod_poly_degree(self.cur._numer) > self.degree: 989 986 # raise StopIteration 990 987 return self.cur 991 988 … … 1035 1032 cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement) 1036 1033 ans._parent = self._codomain 1037 1034 ans.p = self.p 1038 zmod_poly_init(ans._numer, ans.p)1039 zmod_poly_init(ans._denom, ans.p)1040 zmod_poly_set(ans._numer, &x.x)1041 zmod_poly_set_coeff_ui(ans._denom, 0, 1)1035 nmod_poly_init(ans._numer, ans.p) 1036 nmod_poly_init(ans._denom, ans.p) 1037 nmod_poly_set(ans._numer, &x.x) 1038 nmod_poly_set_coeff_ui(ans._denom, 0, 1) 1042 1039 ans.initalized = True 1043 1040 return ans 1044 1041 … … 1064 1061 cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement) 1065 1062 ans._parent = self._codomain 1066 1063 ans.p = self.p 1067 zmod_poly_init(ans._numer, ans.p)1068 zmod_poly_init(ans._denom, ans.p)1064 nmod_poly_init(ans._numer, ans.p) 1065 nmod_poly_init(ans._denom, ans.p) 1069 1066 cdef long r 1070 zmod_poly_set(ans._numer, &x.x)1067 nmod_poly_set(ans._numer, &x.x) 1071 1068 if len(args) == 0: 1072 zmod_poly_set_coeff_ui(ans._denom, 0, 1)1069 nmod_poly_set_coeff_ui(ans._denom, 0, 1) 1073 1070 elif len(args) == 1: 1074 1071 y = args[0] 1075 1072 if PY_TYPE_CHECK(y, Integer): 1076 1073 r = mpz_fdiv_ui((<Integer>y).value, self.p) 1077 1074 if r == 0: 1078 1075 raise ZeroDivisionError 1079 zmod_poly_set_coeff_ui(ans._denom, 0, r)1076 nmod_poly_set_coeff_ui(ans._denom, 0, r) 1080 1077 else: 1081 1078 # could use the coerce keyword being set to False to not check this... 1082 1079 if not (PY_TYPE_CHECK(y, Element) and y.parent() is self._domain): 1083 1080 # We could special case integers and GF(p) elements here. 1084 1081 y = self._domain(y) 1085 zmod_poly_set(ans._denom, &((<Polynomial_zmod_flint?>y).x))1082 nmod_poly_set(ans._denom, &((<Polynomial_zmod_flint?>y).x)) 1086 1083 else: 1087 1084 raise ValueError, "FpT only supports two positional arguments" 1088 1085 if not (kwds.has_key('reduce') and not kwds['reduce']): … … 1169 1166 """ 1170 1167 cdef FpTElement x = <FpTElement?>_x 1171 1168 cdef Polynomial_zmod_flint ans 1172 if zmod_poly_degree(x._denom) != 0:1169 if nmod_poly_degree(x._denom) != 0: 1173 1170 normalize(x._numer, x._denom, self.p) 1174 if zmod_poly_degree(x._denom) != 0:1171 if nmod_poly_degree(x._denom) != 0: 1175 1172 raise ValueError, "not integral" 1176 1173 ans = PY_NEW(Polynomial_zmod_flint) 1177 if zmod_poly_get_coeff_ui(x._denom, 0) != 1:1174 if nmod_poly_get_coeff_ui(x._denom, 0) != 1: 1178 1175 normalize(x._numer, x._denom, self.p) 1179 zmod_poly_init(&ans.x, self.p)1180 zmod_poly_set(&ans.x, x._numer)1176 nmod_poly_init(&ans.x, self.p) 1177 nmod_poly_set(&ans.x, x._numer) 1181 1178 ans._parent = self._codomain 1182 1179 ans._cparent = get_cparent(self._codomain) 1183 1180 return ans … … 1228 1225 cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement) 1229 1226 ans._parent = self._codomain 1230 1227 ans.p = self.p 1231 zmod_poly_init(ans._numer, ans.p)1232 zmod_poly_init(ans._denom, ans.p)1233 zmod_poly_set_coeff_ui(ans._numer, 0, x.ivalue)1234 zmod_poly_set_coeff_ui(ans._denom, 0, 1)1228 nmod_poly_init(ans._numer, ans.p) 1229 nmod_poly_init(ans._denom, ans.p) 1230 nmod_poly_set_coeff_ui(ans._numer, 0, x.ivalue) 1231 nmod_poly_set_coeff_ui(ans._denom, 0, 1) 1235 1232 ans.initalized = True 1236 1233 return ans 1237 1234 … … 1257 1254 cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement) 1258 1255 ans._parent = self._codomain 1259 1256 ans.p = self.p 1260 zmod_poly_init(ans._numer, ans.p)1261 zmod_poly_init(ans._denom, ans.p)1257 nmod_poly_init(ans._numer, ans.p) 1258 nmod_poly_init(ans._denom, ans.p) 1262 1259 cdef long r 1263 zmod_poly_set_coeff_ui(ans._numer, 0, x.ivalue)1260 nmod_poly_set_coeff_ui(ans._numer, 0, x.ivalue) 1264 1261 if len(args) == 0: 1265 zmod_poly_set_coeff_ui(ans._denom, 0, 1)1262 nmod_poly_set_coeff_ui(ans._denom, 0, 1) 1266 1263 if len(args) == 1: 1267 1264 y = args[0] 1268 1265 if PY_TYPE_CHECK(y, Integer): 1269 1266 r = mpz_fdiv_ui((<Integer>y).value, self.p) 1270 1267 if r == 0: 1271 1268 raise ZeroDivisionError 1272 zmod_poly_set_coeff_ui(ans._denom, 0, r)1269 nmod_poly_set_coeff_ui(ans._denom, 0, r) 1273 1270 else: 1274 1271 R = self._codomain.ring_of_integers() 1275 1272 # could use the coerce keyword being set to False to not check this... 1276 1273 if not (PY_TYPE_CHECK(y, Element) and y.parent() is R): 1277 1274 # We could special case integers and GF(p) elements here. 1278 1275 y = R(y) 1279 zmod_poly_set(ans._denom, &((<Polynomial_zmod_flint?>y).x))1276 nmod_poly_set(ans._denom, &((<Polynomial_zmod_flint?>y).x)) 1280 1277 else: 1281 1278 raise ValueError, "FpT only supports two positional arguments" 1282 1279 if not (kwds.has_key('reduce') and not kwds['reduce']): … … 1373 1370 """ 1374 1371 cdef FpTElement x = <FpTElement?>_x 1375 1372 cdef IntegerMod_int ans 1376 if zmod_poly_degree(x._denom) != 0 or zmod_poly_degree(x._numer) > 0:1373 if nmod_poly_degree(x._denom) != 0 or nmod_poly_degree(x._numer) > 0: 1377 1374 normalize(x._numer, x._denom, self.p) 1378 if zmod_poly_degree(x._denom) != 0:1375 if nmod_poly_degree(x._denom) != 0: 1379 1376 raise ValueError, "not integral" 1380 if zmod_poly_degree(x._numer) > 0:1377 if nmod_poly_degree(x._numer) > 0: 1381 1378 raise ValueError, "not constant" 1382 1379 ans = PY_NEW(IntegerMod_int) 1383 1380 ans.__modulus = self._codomain._pyx_order 1384 if zmod_poly_get_coeff_ui(x._denom, 0) != 1:1381 if nmod_poly_get_coeff_ui(x._denom, 0) != 1: 1385 1382 normalize(x._numer, x._denom, self.p) 1386 ans.ivalue = zmod_poly_get_coeff_ui(x._numer, 0)1383 ans.ivalue = nmod_poly_get_coeff_ui(x._numer, 0) 1387 1384 ans._parent = self._codomain 1388 1385 return ans 1389 1386 … … 1433 1430 cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement) 1434 1431 ans._parent = self._codomain 1435 1432 ans.p = self.p 1436 zmod_poly_init(ans._numer, ans.p)1437 zmod_poly_init(ans._denom, ans.p)1438 zmod_poly_set_coeff_ui(ans._numer, 0, mpz_fdiv_ui(x.value, self.p))1439 zmod_poly_set_coeff_ui(ans._denom, 0, 1)1433 nmod_poly_init(ans._numer, ans.p) 1434 nmod_poly_init(ans._denom, ans.p) 1435 nmod_poly_set_coeff_ui(ans._numer, 0, mpz_fdiv_ui(x.value, self.p)) 1436 nmod_poly_set_coeff_ui(ans._denom, 0, 1) 1440 1437 ans.initalized = True 1441 1438 return ans 1442 1439 … … 1464 1461 cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement) 1465 1462 ans._parent = self._codomain 1466 1463 ans.p = self.p 1467 zmod_poly_init(ans._numer, ans.p)1468 zmod_poly_init(ans._denom, ans.p)1464 nmod_poly_init(ans._numer, ans.p) 1465 nmod_poly_init(ans._denom, ans.p) 1469 1466 cdef long r