CALIB provides the Zpx
domain, representing the ring
Zp[x], the univariate polynomials having coefficients that are
integers modulo prime p.
The “values” of this domain are represented by the following object:
struct calib_Zpx_obj { int degree; /* Degree of polynomial */ int size; /* Size of coeff[] array (degree < size) */ const struct calib_Zpx_dom * dom; /* Polynomial domain. */ mpz_ptr coeff; /* Coefficients of polynomial. */ };
The following additional object is used to represent linked-lists of factors produced by various Zpx factorization algorithms:
struct calib_Zpx_factor { int multiplicity; struct calib_Zpx_obj * factor; struct calib_Zpx_factor * next; };
The CALIB Zpx
domain is constructed by specifying a Zp
domain used to represent the coefficients of the corresponding Zpx
polynomials.
One may access CALIB’s Zpx
domain as follows:
#include "calib/Zpx.h" /* #includes "calib/Zp.h" */ ... struct calib_Zp_dom * Zp; struct calib_Zpx_dom * Zpx; struct calib_Zpx_obj poly1, poly2; ... Zp = calib_get_Zp_dom_ui (47); /* Integers modulo 47 */ Zpx = calib_make_Zpx_dom (Zp); ... Zpx -> init (&poly1); Zpx -> init (&poly2); ... Zpx -> mul (&poly1, &poly1, &poly2); ... Zpx -> clear (&poly2); Zpx -> clear (&poly1); calib_free_Zpx_dom (Zpx); calib_free_Zp_dom (Zp);
The CALIB Zpx
domain supports the following settings:
/* * Which factorization algorithm to use (for square-free polynomials). */ enum calib_Zpx_factor_method { CALIB_ZPX_FACTOR_METHOD_BERLEKAMP, CALIB_ZPX_FACTOR_METHOD_DDF, }; /* * The "settings" object for the Zpx domain. */ struct calib_Zpx_settings { /* Factorization method for square-free Zpx polynomials. */ enum calib_Zpx_factor_method factor_method; }; /* * Newly created Zpx domains default to these settings. */ extern struct calib_Zpx_settings calib_Zpx_default_settings;
Each CALIB Zpx
domain has its own copy of these settings
(consulted by the domain’s operations):
struct calib_Zpx_dom { ... struct calib_Zpx_settings settings; ... };
These settings are initialized from calib_Zpx_default_settings
when the domain is constructed, but applications may alter these
settings after construction, if desired.
The default Zpx factor_method
is to use Berlekamp’s algorithm.
The struct calib_Zpx_dom
object contains the following members
(pointers to functions) that provide operations of the domain:
void (*init) (const struct calib_Zpx_dom * K_of_x, struct calib_Zpx_obj * x);
Initialize the given Zpx polynomial x
, where:
K_of_x | is the Zpx ring/domain the polynomial belongs to; and |
x | is the polynomial to initialize. |
void (*init_degree) (const struct calib_Zpx_dom * K_of_x, struct calib_Zpx_obj * x, int degree);
Initialize the given Zpx polynomial x
(while assuring that
internal buffers are sufficiently large to hold a polynomial of up to
the given degree
without further allocation), where:
K_of_x | is the Zpx ring/domain the polynomial belongs to; |
x | is the polynomial to initialize; and |
degree | is the guaranteed minimimum degree polynomial that x
will be able to hold (without further buffer allocation) upon
successful completion of this operation. |
void (*alloc) (struct calib_Zpx_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_Zpx_obj * x);
Clear out the given polynomial dst
(freeing all memory it might
hold and returning it to the constant value of zero), where:
dst | is the polynomial to be cleared. |
void (*set) (struct calib_Zpx_obj * rop, const struct calib_Zpx_obj * op);
Set rop
to op
in Zpx, where:
rop | is the polynomial receiving the result; |
op | is the polynomial to copy. |
void (*set_si) (struct calib_Zpx_obj * rop, calib_si_t op);
Set rop
to op
in Zpx, where:
rop | is the polynomial receiving the result; |
op | is the integer value to set. |
void (*set_z) (struct calib_Zpx_obj * rop, mpz_srcptr op);
Set rop
to op
in Zpx, where:
rop | is the polynomial receiving the result; |
op | is the GMP integer value to set. |
void (*set_q) (struct calib_Zpx_obj * rop, mpq_srcptr op);
Set rop
to op
in Zpx, where:
rop | is the polynomial receiving the result; |
op | is the GMP rational value to set. |
void (*set_var_power) (struct calib_Zpx_obj * rop, int power);
Set rop
to x ** power
in Zpx, where:
rop | is the Zpx polynomial receiving the result; |
power | is the power to set (must be non-negative). |
void (*set_Zx) (struct calib_Zpx_obj * rop, const struct calib_Zx_obj * op);
Set rop
to op
in Zpx, where:
rop | is the destination Zpx polynomial; and |
op | is the source Zx polynomial. |
The coefficients of the source polynomial are reduced modulo p during the copy.
void (*set_Qa) (struct calib_Zpx_obj * rop, const struct calib_Qa_obj * op);
Set rop
to op
in Zpx, where:
rop | is the destination Zpx polynomial; and |
op | is the source Qa polynomial. |
The rational coefficients of the source polynomial are reduced modulo p during the copy.
void (*add) (struct calib_Zpx_obj * rop, const struct calib_Zpx_obj * op1, const struct calib_Zpx_obj * op2);
Set rop
to op1 + op2
in Zpx, where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*sub) (struct calib_Zpx_obj * rop, const struct calib_Zpx_obj * op1, const struct calib_Zpx_obj * op2);
Set rop
to op1 - op2
in Zpx, where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*neg) (struct calib_Zpx_obj * rop, const struct calib_Zpx_obj * op);
Set rop
to - op
in Zpx, where:
rop | is the Zpx polynomial receiving the result; and |
op | is the Zpx polynomial being negated. |
void (*mul) (struct calib_Zpx_obj * rop, const struct calib_Zpx_obj * op1, const struct calib_Zpx_obj * op2);
Set rop
to op1 * op2
in Zpx, where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*mul_z) (struct calib_Zpx_obj * rop, const struct calib_Zpx_obj * op1, mpz_srcptr op2);
Set rop
to op1 * op2
in Zpx, 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_Zpx_obj * rop, const struct calib_Zpx_obj * op, int power);
Set rop
to op ** power
in Zpx, 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_Zpx_obj * (*dup) (const struct calib_Zpx_obj * op);
Return a dynamically-allocated Zpx polynomial that is a copy of
op
, where:
op | is the polynomial to be duplicated. |
void (*free) (struct calib_Zpx_obj * poly);
Free the given dynamically-allocated polynomial poly
, where:
poly | is the polynomial to be freed. |
This is equivalent to performing Zpx -> clear (poly);
, followed
by free (poly);
.
void (*monicize) (struct calib_Zpx_obj * poly);
Modify the given Zpx polynomial poly
to be monic, where:
result
, where:
poly | is the polynomial to make monic. |
void (*eval) (mpz_ptr rop, const struct calib_Zpx_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_Zpx_obj * quotient, struct calib_Zpx_obj * remainder, const struct calib_Zpx_obj * a, const struct calib_Zpx_obj * b);
Polynomial division in Zp[x], where:
quotient | receives the quotient polynomial (may be NULL); |
remainder | receives the remainder polynomial (may be NULL); |
a | is the dividend polynomial; and |
b | is the divisor polynomial (may not be zero). |
Division in Zp[x] has the following properties:
void (*gcd) (struct calib_Zpx_obj * gcd, const struct calib_Zpx_obj * a, const struct calib_Zpx_obj * b);
Compute the greatest common divisor (GCD) of a
and b
,
storing the result in gcd
, where:
gcd | receives the resulting GCD polynomial (always monic); |
a | is the first operand polynomial; and |
b | is the second operand polynomial. |
void (*extgcd) (struct calib_Zpx_obj * gcd, struct calib_Zpx_obj * xa, struct calib_Zpx_obj * xb, const struct calib_Zpx_obj * a, const struct calib_Zpx_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 (always monic); |
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:
struct calib_Zpx_factor * (*factor) (const struct calib_Zpx_obj * poly);
Factor the given polynomial poly
into its irreducible
factors, returning a linked list of these factors, where:
poly | is the Zpx polynomial to be factored. |
Except for an optional leading constant factor, all other factors are monic and irreducible.
struct calib_Zpx_factor * (*factor_square_free) (const struct calib_Zpx_obj * poly);
Factor the given polynomial poly
into square-free factors, where:
poly | is the Zpx polynomial to be factored. |
struct calib_Zpx_factor * (*finish_sqf) (const struct calib_Zpx_factor * sqfactors);
Given a list of monic, 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 Zpx polynomial factors for which factorization into irreducibles is desired. |
void (*free_factors) (struct calib_Zpx_factor * factors);
Free up the given list of Zpx factors, where:
factors | is a linked-list factors to be freed. |
void (*resultant) (mpz_ptr result, const struct calib_Zpx_obj * a, const struct calib_Zpx_obj * b);
Compute the resultant of Zpx polynomials a
and b
,
storing the result in result
, where:
result | the GMP integer that receives the result; |
a | is the first operand polynomial; and |
b | is the second operand polynomial. |
void (*derivative) (struct calib_Zpx_obj * rop, const struct calib_Zpx_obj * op);
Set rop
to be the derivative of op
, where:
rop | receives the resulting derivative; and |
op | is the polynomial to differentiate. |
calib_bool (*zerop) (const struct calib_Zpx_obj * op);
Return 1 if-and-only-if the given Zpx polynomial is identically zero and 0 otherwise, where:
op | is the Zpx polynomial to test for zero. |
calib_bool (*onep) (const struct calib_Zpx_obj * op);
Return 1 if-and-only-if the given Zpx polynomial is identically 1 and 0 otherwise, where:
op | is the Zpx polynomial to test for one. |
void (*set_genrep) (struct calib_Zpx_obj * rop, const struct calib_genrep * op, const char * var);
Compute a Zpx polynomial obtained from the given genrep op
,
interpreting var
to be the name of the variable used by the Zpx
polynomial, storing the result in rop
, where:
rop | receives the resulting Zpx polynomial; |
op | is the genrep to convert into Zpx polynomial form; and |
var | is the variable name (appearing within genrep op ) that is
to be interpreted as the polynomial variable in Zpx. |
struct calib_genrep * (*to_genrep) (const struct calib_Zpx_dom * K_of_x, const struct calib_Zpx_obj * op, const char * var);
Return a dynamically-allocated genrep corresponding to the given Zpx
polynomial op
, using var
as the name of the polynomial
variable within the returned genrep, where:
K_of_x | is the Zpx ring/domain performing this operation; |
op | is the Zpx polynomial to convert into genrep form; and |
var | is the variable name to use in the genrep for the polynomial variable of Zpx. |
struct calib_genrep * (*factors_to_genrep) (const struct calib_Zpx_factor * factors, const char * var);
Return a dynamically-allocated genrep corresponding to the given list
of Zpx factors
, using var
as the name of the polynomial
variable within the returned genrep, where:
factors | is the list of Zpx polynomial factors to convert into genrep form; and |
var | is the variable name to use in the genrep for the polynomial variable of Zpx. |
void (*print_maxima) (const struct calib_Zpx_obj * op);
Print the given Zpx polynomial op
to stdout using syntax that
can be directly read by Maxima, where:
op | is the Zpx polynomial to be printed. |