Next: Qx, Previous: Genrep Functions, Up: Top [Contents][Index]
CALIB provides the Zx
domain, representing the ring
Z[x], the univariate polynomials having integer coefficients.
The “values” of this domain are represented by the following object:
struct calib_Zx_obj { int degree; /* Degree of polynomial */ int size; /* Size of coeff[] array (degree < size) */ mpz_ptr coeff; /* Coefficients of polynomial. */ };
These objects are subject to init()
and clear()
operations.
All such objects must be initialized prior to use by any other CALIB
operation.
Memory leaks result if they are not cleared when done.
The following additional object is used to represent linked-lists of factors produced by various Zx factorization algorithms:
struct calib_Zx_factor { int multiplicity; struct calib_Zx_obj * factor; struct calib_Zx_factor * next; };
No data is needed to instantiate the Zx
domain.
(There is only one such object, and cannot be freed.)
Nonetheless, the Zx
domain object is the only way to access the
operations provided by this domain.
One may access CALIB’s Zx
domain as follows:
#include "calib/Zx.h" ... const struct calib_Zx_dom * Zx; struct calib_Zx_obj poly1, poly2; ... Zx = calib_get_Zx_dom (); ... Zx -> init (&poly1); Zx -> init (&poly2); ... Zx -> mul (&poly1, &poly1, &poly2); ... Zx -> clear (&poly2); Zx -> clear (&poly1);
The CALIB Zx
domain supports the following settings:
/* * Which factorization algorithm to use (for square-free polynomials). */ enum calib_Zx_factor_method { CALIB_ZX_FACTOR_METHOD_ZASSENHAUS, CALIB_ZX_FACTOR_METHOD_VAN_HOEIJ, }; /* * Which method to use for lifting modular factors. */ enum calib_Zx_lift_method { CALIB_ZX_LIFT_METHOD_LINEAR, CALIB_ZX_LIFT_METHOD_QUADRATIC, }; /* * Which method to use for gcd (gcd, a, b). (The gcd_n() function always * uses modular.) */ enum calib_Zx_gcd_method { CALIB_ZX_GCD_METHOD_MODULAR, CALIB_ZX_GCD_METHOD_PRS }; /* * The "settings" object for the Zx domain. */ struct calib_Zx_settings { /* Factorization method for square-free Zx polynomials. */ enum calib_Zx_factor_method factor_method; /* Method for lifting modular factors. */ enum calib_Zx_lift_method lift_method; /* Method to use for two-operand gcd(). */ enum calib_Zx_gcd_method gcd_method; /* If number of remaining modular factors does not exceed this, */ /* then use exhaustive enumeration instead of Van Hoeij. */ int VH_max_enumerate; /* Enable trace output from Z[x] factorization algorithm. */ /* Zero is none. Higher values give more output. */ int factor_trace_level; /* Van Hoeij uses resultant-based trace root bound? */ calib_bool VH_use_resultant_trace_root_bound; /* Validate lifted modular factors? */ calib_bool validate_lifted_modular_factors; }; /* * All ssettings for Zx domain are global. */ extern struct calib_Zx_settings calib_Zx_settings;
The struct calib_Zx_dom
object contains the following members
(pointers to functions) that provide operations of the domain:
void (*init) (struct calib_Zx_obj * x);
Initialize the given Zx polynomial x
, where:
x | is the polynomial to initialize. |
void (*init_si) (struct calib_Zx_obj * x, calib_si_t op);
Initialize the given Zx polynomial x
to the given constant
value op
, where:
x | is the polynomial to initialize; and |
op | is the constant value to which the polynomial is set. |
void (*alloc) (struct calib_Zx_obj * rop, int degree);
Force the given (already initialized) polynomial rop
to have
buffer space sufficient to hold a polynomial of at least the given
degree
, where:
rop | is the polynomial whose allocation is to be adjusted; and |
degree | is the guaranteed minimum degree polynomial that rop will
be able to hold (without further buffer allocation) upon successful
completion of this operation. |
void (*clear) (struct calib_Zx_obj * x);
Clear out the given polynomial x
(freeing all memory it might
hold and returning it to the constant value of zero), where:
x | is the polynomial to be cleared. |
void (*set) (struct calib_Zx_obj * rop, const struct calib_Zx_obj * op);
Set rop
to op
in Zx, where:
rop | is the polynomial receiving the result; |
op | is the polynomial to copy. |
void (*set_si) (struct calib_Zx_obj * rop, calib_si_t op);
Set rop
to op
in Zx, where:
rop | is the polynomial receiving the result; |
op | is the integer value to set. |
void (*set_z) (struct calib_Zx_obj * rop, mpz_srcptr op);
Set rop
to op
in Zx, where:
rop | is the polynomial receiving the result; and |
op | is the GMP integer value to set. |
void (*set_var_power) (struct calib_Zx_obj * rop, int power);
Set rop
to x ** power
in Zx, where:
rop | is the polynomial receiving the result; |
power | is the power to set (must be non-negative). |
void (*add) (struct calib_Zx_obj * rop, const struct calib_Zx_obj * op1, const struct calib_Zx_obj * op2);
Set rop
to op1 + op2
in Zx, where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*sub) (struct calib_Zx_obj * rop, const struct calib_Zx_obj * op1, const struct calib_Zx_obj * op2);
Set rop
to op1 - op2
in Zx, where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*neg) (struct calib_Zx_obj * rop, const struct calib_Zx_obj * op);
Set rop
to - op
in Zx, where:
rop | is the polynomial receiving the result; |
op | is the operand to negate. |
void (*mul) (struct calib_Zx_obj * rop, const struct calib_Zx_obj * op1, const struct calib_Zx_obj * op2);
Set rop
to op1 * op2
in Zx, where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*mul_z) (struct calib_Zx_obj * rop, const struct calib_Zx_obj * op1, mpz_srcptr op2);
Set rop
to op1 * op2
in Zx, where:
rop | is the polynomial receiving the result; |
op1 | is the first (polynomial) operand; and |
op2 | is the second (GMP integer) operand. |
void (*ipow) (struct calib_Zx_obj * rop, const struct calib_Zx_obj * op, int power);
Set rop
to op ** power
in Zx, where:
where:
rop | is the polynomial receiving the result; |
op | is the polynomial to exponentiate; and |
power | is the power to take (must be >= 0). |
struct calib_Zx_obj * (*dup) (const struct calib_Zx_obj * op);
Return a dynamically-allocated Zx polynomial that is a copy of
op
, where:
op | is the polynomial to be duplicated. |
void (*free) (struct calib_Zx_obj * poly);
Free the given dynamically-allocated polynomial poly
, where:
poly | is the polynomial to be freed. |
This is equivalent to performing Zx -> clear (poly);
, followed
by free (poly);
.
void (*eval) (mpz_ptr rop, const struct calib_Zx_obj * poly, mpz_srcptr value);
Evaluate polynomial poly
at the given value
, storing the
result in rop
, where:
rop | is the GMP integer receiving the result; |
poly | is the polynomial to be evaluated; and |
value | is the value at which to evaluate the polynomial. |
void (*div) (struct calib_Zx_obj * quotient, struct calib_Zx_obj * remainder, mpz_ptr d, const struct calib_Zx_obj * a, const struct calib_Zx_obj * b);
Polynomial pseudo-division in Z[x], where:
quotient | receives the quotient polynomial (may be NULL); |
remainder | receives the remainder polynomial (may be NULL); |
d | receives the “denominator” value (may be NULL); |
a | is the dividend polynomial; and |
b | is the divisor polynomial (must not be zero). |
Pseudo-division has the following properties:
calib_bool (*exactly_divides) (struct calib_Zx_obj * quotient, const struct calib_Zx_obj * a, const struct calib_Zx_obj * b);
Return 1 if-and-only-if a
is exactly divisible by b
(setting quotient
such that a = b * quotient
);
returns 0 otherwise (without modifying quotient
), where:
quotient | receives the quotient polynomial (may be NULL); |
a | is the dividend polynomial; and |
b | is the divisor polynomial (may not be zero). |
void (*div_z_exact) (struct calib_Zx_obj * rop, const struct calib_Zx_obj * op1, mpz_srcptr op2);
Set rop
to op1 / op2
in Zx, where:
result | receives result polynomial; |
poly | is the dividend polynomial; and |
z | is the GMP integer by which to divide poly . |
It is a fatal error if the division is not exact.
void (*gcd) (struct calib_Zx_obj * gcd, const struct calib_Zx_obj * a, const struct calib_Zx_obj * b);
Compute the greatest common divisor (GCD) of a
and b
,
storing the result in gcd
, where:
gcd | receives the resulting GCD polynomial; |
a | is the first operand polynomial; and |
b | is the second operand polynomial. |
void (*gcd_n) (struct calib_Zx_obj * gcd, struct calib_Zx_obj ** cofact, int npoly, const struct calib_Zx_obj * const * poly_ptrs);
Compute the greatest common divisor (GCD) polynomial that simultaneously divides n given polynomials, where:
gcd | receives the resulting GCD polynomial; |
cofact | is an array of n pointers to polynomials receiving the cofactor corresponding to each given input polynomial (may be NULL); |
npoly | is the number n of input polynomials provided; and |
poly_ptrs | is an array of n pointers to input polynomials whose GCD is to be computed. |
This can be vastly more efficient that decomposing this into
n-1 consecutive calls to the gcd
function.
void (*extgcd) (struct calib_Zx_obj * gcd, struct calib_Zx_obj * xa, struct calib_Zx_obj * xb, const struct calib_Zx_obj * a, const struct calib_Zx_obj * b);
The extended Euclidean algorithm.
Compute polynomials gcd
, xa
and xb
such that
gcd = a * xa + b * xb, where:
gcd | receives the resulting GCD polynomial; |
xa | receives the multiplier polynomial for a ; |
xb | receives the multiplier polynomial for b ; |
a | is the first operand polynomial; and |
b | is the second operand polynomial. |
The result satisfies the following properties:
void (*prim_part) (mpz_ptr content, struct calib_Zx_obj * ppart, const struct calib_Zx_obj * op);
Compute the content
and primitive part ppart
of the
given polynomial op
, where:
content | a GMP integer receiving the content of op ; |
ppart | receives primitive part of op ; and |
op | the polynomial to be decomposed into content and primitive parts. |
void (*resultant) (mpz_ptr result, const struct calib_Zx_obj * a, const struct calib_Zx_obj * b);
Compute the resultant of polynomials a
and b
(an integer value), storing the result in result
, where:
result | is the resultant of given polynomials; |
a | is the first operand; and |
b | is the second operand. |
void (*discriminant) (mpz_ptr result const struct calib_Zx_obj * poly);
Compute the discriminant of polynomial poly
(an integer value),
storing the result in result
, where:
result | is the discriminant of the given polynomial; |
poly | is the polynomial whose discriminant is to be computed. |
void (*derivative) (struct calib_Zx_obj * rop, const struct calib_Zx_obj * op);
Set rop
to be the derivative of Zx polynomial op
, where:
rop | is the derivative of the given polynomial; and |
op | is the polynomial whose derivative is to be computed. |
struct calib_Zx_obj * (*cvZpx) (const struct calib_Zpx_obj * op);
Return a dynamically-allocated polynomial in Z[x] that
corresponds to the given polynomial op
in Zp[x] (the Z
coefficients chosen to have smallest absolute value that are
equivalent to the corresponding Zp coefficient), where:
op | is the Zpx polynomial to convert into signed Zx form. |
struct calib_Zx_factor * (*factor) (const struct calib_Zx_obj * poly);
Factor the given polynomial poly
into its irreducible factors,
returning a linked list of these factors, where:
poly | is the Zx polynomial to be factored. |
Note: If a suitable implementation of the Lenstra-Lenstra-Lovász (LLL) lattice-basis reduction algorithm is provided, this function uses the Van Hoeij algorithm that runs in polynomial time. (FPLLL is the only currently supported LLL implementation.) Otherwise the Zassenhaus algorithm is used that can require exponential time on certain classes of polynomials.
struct calib_Zx_factor * (*factor_square_free) (const struct calib_Zx_obj * poly);
Given a polynomial poly
that must be both primitive and
square-free (all factors occur exactly once), factor poly
into
its irreducible factors, returning a linked-list of these factors,
where:
poly | is the primitive, square-free Zx polynomial to be factored. |
Note: See the above note regarding LLL and Van Hoeij algorithms.
struct calib_Zx_factor * (*finish_sqf) (const struct calib_Zx_factor * sqfactors);
Given a list of primitive, square-free polynomial factors
,
“finish” the factorization by factoring each such factor into
irreducible polynomials, returning a linked-list of these factors,
where:
sqfactors | is a linked-list of primitive, square-free Zx polynomial factors for which factorization into irreducibles is desired. |
Note: See the above note regarding LLL and Van Hoeij algorithms.
void (*free_factors) (struct calib_Zx_factor * factors);
Free up the given list of Zx factors, where:
factors | is a linked-list factors to be freed. |
calib_bool (*zerop) (const struct calib_Zx_obj * op);
Return 1 if-and-only-if the given Zx polynomial is identically zero and 0 otherwise, where:
op | is the Zx polynomial to test for zero. |
calib_bool (*onep) (const struct calib_Zx_obj * op);
Return 1 if-and-only-if the given Zx polynomial is identically one and 0 otherwise, where:
op | is the Zx polynomial to test for one. |
void (*set_genrep) (struct calib_Zx_obj * rop, const struct calib_genrep * op, const char * var);
Convert the given genrep op
into Zx form, interpreting
var
to be the name of the variable used by the Zx polynomial,
storing the result into rop
, where:
rop | receives the resulting Zx polynomial; |
op | is the genrep to convert into Zx polynomial form; and |
var | is the variable name (appearing within genrep op ) that is
to be interpreted as the polynomial variable in Zx. |
struct calib_genrep * (*to_genrep) (const struct calib_Zx_obj * op, const char * var);
Return a dynamically-allocated genrep corresponding to the given Zx
polynomial op
, using var
as the name of the polynomial
variable within the returned genrep, where:
op | is the Zx polynomial to convert into genrep form; and |
var | is the variable name to use in the genrep for the polynomial variable of Zx. |
struct calib_genrep * (*factors_to_genrep) (const struct calib_Zx_factor * factors, const char * var);
Return a dynamically-allocated genrep corresponding to the given list
of Zx factors
, using var
as the name of the polynomial
variable within the returned genrep, where:
factors | is the list of Zx polynomial factors to convert into genrep form; and |
var | is the variable name to use in the genrep for the polynomial variable of Zx. |
void (*print_maxima) (const struct calib_Zx_obj * op);
Print the given Zx polynomial op
to stdout using syntax that
can be directly read by Maxima, where:
op | is the Zx polynomial to be printed. |
Next: Qx, Previous: Genrep Functions, Up: Top [Contents][Index]