CALIB provides the Zax
domain, representing the ring
Z(a)[x], the univariate polynomials having coefficients that
are an algebraic extension of the integers.
The “values” of this domain are represented by the following object:
struct calib_Zax_obj { int degree; /* Degree of polynomial */ int size; /* Size of coeff buffer (degree < size) */ const struct calib_Zax_dom * dom; /* Domain of polynomial */ mpz_ptr coeff; /* Coefficients of polynomial. */ };
The CALIB Zax
domain is constructed by specifying a Za
domain used to represent the coefficients of the corresponding Zax
polynomials.
One may access CALIB’s Zax
domain as follows:
#include "calib/Zax.h" ... struct calib_Zx_obj * gpoly; struct calib_Za_dom * Za; struct calib_Zax_dom * Zax; struct calib_Zax_obj poly1, poly2; ... gpoly = /* generator poly in Z[x] */ Za = calib_make_Za_dom (gpoly); Zax = calib_make_Zax_dom (Za); ... Zax -> init (&poly1); Zax -> init (&poly2); ... Zax -> mul (&poly1, &poly1, &poly2); ... Zax -> clear (&poly2); Zax -> clear (&poly1); calib_free_Zax_dom (Zax); calib_free_Za_dom (Za);
The struct calib_Zax_dom
object contains the following members
(pointers to functions) that provide operations of the domain:
void (*init) (const struct calib_Zax_dom * R_of_x, struct calib_Zax_obj * x);
Initialize the given Zax polynomial x
, where:
R_of_x | is the Zax ring/domain the polynomial belongs to; and |
x | is the polynomial to initialize. |
void (*init_degree) (const struct calib_Zax_dom * R_of_x, struct calib_Zax_obj * x, int degree);
Initialize the given Zax polynomial x
(while assuring that
internal buffers are sufficiently large to hold a polynomial of up to
the given degree
without further allocation), where:
R_of_x | is the Zax 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 (*init_si) (const struct calib_Zax_dom * R_of_x, struct calib_Zax_obj * x, calib_si_t op);
Initialize the given Zax polynomial x
to have the constant
value op
(while assuring that internal buffers are sufficiently
large to hold a polynomial of up to the given degree
without
further allocation), where:
R_of_x | is the Zax ring/domain performing this operation; |
x | is the polynomial to initialize; and |
op | is the constant value to which polynomial x is set. |
void (*alloc) (struct calib_Zax_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_Zax_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_Zax_obj * rop, const struct calib_Zax_obj * op);
Set rop
to op
in Zax, where:
rop | is the polynomial receiving the result; |
op | is the polynomial to copy. |
void (*set_si) (struct calib_Zax_obj * rop, calib_si_t op);
Set rop
to op
in Zax, where:
rop | is the polynomial receiving the result; |
op | is the integer value to set. |
void (*set_z) (struct calib_Zax_obj * rop, mpz_srcptr op);
Set rop
to op
in Zax, where:
rop | is the polynomial receiving the result; |
op | is the GMP integer value to set. |
void (*set_q) (struct calib_Zax_obj * rop, mpq_srcptr op);
Set rop
to op
in Zax, where:
rop | is the polynomial receiving the result; |
op | is the GMP rational value to set (must have denominator of 1). |
void (*set_var_power) (struct calib_Zax_obj * rop, int power);
Set rop
to x ** power
in Zax, where:
rop | is the Zpx polynomial receiving the result; |
power | is the power to set (must be non-negative). |
void (*add) (struct calib_Zax_obj * rop, const struct calib_Zax_obj * op1, const struct calib_Zax_obj * op2);
Set rop
to op1 + op2
in Zax, where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*sub) (struct calib_Zax_obj * rop, const struct calib_Zax_obj * op1, const struct calib_Zax_obj * op2);
Set rop
to op1 - op2
in Zax, where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*neg) (struct calib_Zax_obj * rop, const struct calib_Zax_obj * op);
Set rop
to - op
in Zax, where:
rop | is the Zax polynomial receiving the result; and |
op | is the Zax polynomial being negated. |
void (*mul) (struct calib_Zax_obj * rop, const struct calib_Zax_obj * op1, const struct calib_Zax_obj * op2);
Set rop
to op1 * op2
in Zax, where:
result
, where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*mul_z) (struct calib_Zax_obj * rop, const struct calib_Zax_obj * op1, mpz_srcptr op2);
Set rop
to op1 * op2
in Zax, 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_Zax_obj * rop, const calib_Zax_obj * op, int power); struct calib_Zax_obj * poly);
Set rop
to op ** power
in Zax, 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_Zax_obj * (*dup) (const struct calib_Zax_obj * op);
Return a dynamically-allocated Zax polynomial that is a copy of
op
, where:
op | is the polynomial to be duplicated. |
void (*free) (struct calib_Zax_obj * poly);
Free the given dynamically-allocated polynomial poly
, where:
poly | is the polynomial to be freed. |
This is equivalent to performing Zax -> clear (poly);
, followed
by free (poly);
.
void (*eval) (struct calib_Za_obj * rop, const struct calib_Zax_obj * op, const struct calib_Za_obj * value);
Evaluate polynomial op
at the given value
, storing the
result in rop
, where:
rop | is the Za value object receiving the result; |
op | is the polynomial to be evaluated; and |
value | is the Za value at which to evaluate op . |
void (*div) (struct calib_Zax_obj * quotient, struct calib_Zax_obj * remainder, mpz_ptr d, const struct calib_Zax_obj * a, const struct calib_Zax_obj * b);
Polynomial division in Zp[x], where:
quotient | receives the quotient polynomial (may be NULL); |
remainder | receives the remainder polynomial (may be NULL); |
d | receives the common denominator (may be NULL); |
a | is the dividend polynomial; and |
b | is the divisor polynomial (may not be zero). |
Division in Z(a)[x] has the following properties:
void (*div_z_exact) (struct calib_Zax_obj * rop, const struct calib_Zax_obj * op1, mpz_srcptr op2);
Set rop
to op1 / op2
in Zax, where:
rop | is the polynomial receiving the result; |
op1 | is the first (polynomial) operand; and |
op2 | is the second (GMP integer) operand. |
The division must be exact or a fatal error results.
void (*extgcd) (struct calib_Zax_obj * gcd, struct calib_Zax_obj * xa, struct calib_Zax_obj * xb, const struct calib_Zax_obj * a, const struct calib_Zax_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 (monic unless a = b = 0); |
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_Zax_obj * (*cvZax) (const struct calib_Zax_dom * Zax const struct calib_Zax_obj * op);
Return a dynamically-allocated Zax polynomial that is copied from the
given Zax polynomial op
, where:
Zax | is the source Zax ring/domain; |
op | is the Zax polynomial to be copied into Zax form. |
The generator polynomials defining Zax
and the domain of
op
are intended to be different.
struct calib_Zax_obj * (*cvGFpkx) (const struct calib_Zax_dom * K_of_x, const struct calib_GFpkx_dom * gfpkx, const struct calib_GFpkx_obj * gfpoly);
Return a dynamically-allocated Zax polynomial that is copied from the
given GFpkx polynomial src
, where:
K_of_x | is the Zax ring/domain performing this operation; |
gfpkx | is the GFpkx ring/domain for gfpoly ; and |
gfpoly | is the GFpkx polynomial to be copied into Zax form. |
The generator polynomials defining K_of_x
and gfpkx
must
be identical or a fatal error occurs.
struct calib_Zax_obj * (*cvQax) (const struct calib_Zax_dom * R_of_x, const struct calib_Qax_obj * qpoly, mpz_srcptr d);
Return a dynamically-allocated Zax polynomial that is copied from the
given Qax polynomial qpoly
(after multiplying by d
to
clear all denominators), where:
R_of_x | is the Zax ring/domain performing this operation; |
qpoly | is the source Qax polynomial to convert; and |
d | is the common demoninator by which to multiply. |
The generator polynomials defining R_of_x
and the domain of
qpoly
must be identical or a fatal error occurs.
It is also a fatal error if any non-integral coefficients
remain after multiplying by d
.
calib_bool (*zerop) (const struct calib_Zax_obj * op);
Return 1 if-and-only-if the given Zax polynomial is identically zero and 0 otherwise, where:
op | is the Zax polynomial to test for zero. |
calib_bool (*onep) (const struct calib_Zax_obj * op);
Return 1 if-and-only-if the given Zax polynomial is identically one and 0 otherwise, where:
op | is the Zax polynomial to test for one. |
void (*set_genrep) (struct calib_Zax_obj * rop, const struct calib_genrep * op, const char * xvar, const char * avar);
Comput a Zax polynomial obtained from the given genrep op
,
interpreting xvar
to be the name of the variable used by the
Zax polynomial and avar
to be the name of the variable denoting
the algebraic number, storing the result in rop
, where:
rop | receives the resulting Zax polynomial; |
op | is the genrep to convert into Zax polynomial form; |
xvar | is the variable name (appearing within genrep op ) that is
interpreted as the polynomial variable in Zax; and |
avar | is the variable name (appearing within genrep op ) that is
interpreted as being the algebraic number. |
struct calib_genrep * (*to_genrep) (const struct calib_Zax_obj * op, const char * xvar, const char * avar);
Return a dynamically-allocated genrep corresponding to the given Zax
polynomial op
, using xvar
as the name of the polynomial
variable within the returned genrep and avar
as the name of the
algebraic number, where:
op | is the Zax polynomial to convert into genrep form; |
xvar | is the variable name to use in the genrep for the polynomial variable of Zax; and |
avar | is the variable name to use in the genrep for the algebraid number. |