CALIB provides the Qax
domain, representing the ring
Q(a)[x], the univariate polynomials having coefficients that
are an algebraic extension of the rationals.
The “values” of this domain are represented by the following object:
/* * An instance of a polynomial in K[x], where K = Q(a). */ struct calib_Qax_obj { int degree; /* Degree of polynomial */ int size; /* Size of coeff buffer */ const struct calib_Qax_dom * dom; /* Qax domain of polymial */ struct calib_Qa_obj * coeff; /* Coefficients of polynomial. */ };
The CALIB Qax
domain is constructed by specifying a Qa
domain used to represent the coefficients of the corresponding Qax
polynomials.
One may access CALIB’s Qax
domain as follows:
#include "calib/Qax.h" ... struct calib_Zx_obj * gpoly; struct calib_Qa_dom * Qa; struct calib_Qax_dom * Qax; struct calib_Qax_obj poly1, poly2; ... gpoly = /* generator poly in Z[x] */ Qa = calib_make_Qa_dom (gpoly); Qax = calib_make_Qax_dom (Qa); ... Qax -> init (Qax, &poly1); Qax -> init (Qax, &poly2); ... Qax -> mul (Qax, &poly1, &poly1, &poly2); ... Qax -> clear (&poly2); Qax -> clear (&poly1); calib_free_Qax_dom (Qax); calib_free_Qa_dom (Qa);
The CALIB Qax
domain supports the following settings:
/* * Which factorization algorithm to use (for square-free polynomials). */ enum calib_Qax_factor_method { CALIB_QAX_FACTOR_METHOD_WEINBERGER_ROTHSCHILD, CALIB_QAX_FACTOR_METHOD_NORM }; /* * The "settings" object for the Qax domain. */ struct calib_Qax_settings { /* Factorization method for square-free Qax polynomials. */ enum calib_Qax_factor_method factor_method; /* Print initial factors during Weinberger-Rothschild? */ calib_bool WR_print_initial_factors; /* Print lifted factors during Weinberger-Rothschild? */ calib_bool WR_print_lifted_factors; /* Print trial factor combinations during Weinberger-Rothschild? */ calib_bool WR_print_trial_factor_combinations; }; /* * Newly created Qax domains default to these settings. */ extern struct calib_Qax_settings calib_Qax_default_settings;
Each CALIB Qax
domain has its own copy of these settings
(consulted by the domain’s operations):
struct calib_Qax_dom { ... struct calib_Qax_settings settings; ... };
These settings are initialized from calib_Qax_default_settings
when the domain is constructed, but applications may alter these
settings after construction, if desired.
The struct calib_Qax_dom
object contains the following members
(pointers to functions) that provide operations of the domain:
void (*init) (const struct calib_Qax_dom * K_of_x, struct calib_Qax_obj * x);
Initialize the given Qax polynomial x
to be the constant zero
polynomial of the given Qax domain K_of_x
, where:
K_of_x | is the Qax ring/domain performing this operation; and |
x | is the polynomial to initialize. |
void (*init_degree) (const calib_Qax_dom * K_of_x, struct calib_Qax_obj * x, int degree);
Initialize the given Qax polynomial x
to be the constant zero
polynomial (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 Qax ring/domain performing this operation; |
x | is the polynomial to initialize; and |
degree | is the guaranteed minimimum degree polynomial that dst
will be able to hold (without further buffer allocation) upon
successful completion of this operation. |
void (*alloc) (struct calib_Qax_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 dst will
be able to hold (without further buffer allocation) upon successful
completion of this operation. |
void (*clear) (struct calib_Qax_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_Qax_obj * rop, const struct calib_Qax_obj * op);
Set rop
to op
in Q(a)[x], where:
rop | is the polynomial receiving the result; |
op | is the polynomial to copy. |
void (*set_si) (struct calib_Qax_obj * rop, calib_si_t op);
Set rop
to op
in Q(a)[x], where:
rop | is the polynomial receiving the result; |
op | is the signed integer value to set. |
void (*set_z) (struct calib_Qax_obj * rop, mpz_srcptr op);
Set rop
to op
in Q(a)[x], where:
rop | is the polynomial receiving the result; |
op | is the GMP integer value to set. |
void (*set_q) (struct calib_Qax_obj * rop, mpq_srcptr op);
Set rop
to op
in Q(a)[x], where:
rop | is the polynomial receiving the result; |
op | is the GMP rational value to set. |
void (*set_var_power) (struct calib_Qax_obj * rop, int power);
Set the polynomial rop
to be x**power
(x
is the Qax polynomial variable), where:
rop | is the polynomial receiving the result; |
power | is the power to set (must be non-negative). |
void (*set_Zx) (struct calib_Qax_obj * rop, const struct calib_Zx_obj * op);
Set rop
to op
, converting from Zx to Qax form, where:
rop | the destination Qax polynomial / domain; and |
op | the source Zx polynomial. |
void (*add) (struct calib_Qax_obj * rop, const struct calib_Qax_obj * op1, const struct calib_Qax_obj * op2);
Set rop
to op1 + op2
in Q(a)[x], where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*sub) (struct calib_Qax_obj * rop, const struct calib_Qax_obj * op1, const struct calib_Qax_obj * op2);
Set rop
to op1 - op2
in Q(a)[x], where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*neg) (struct calib_Qax_obj * rop, const struct calib_Qax_obj * op);
Set rop
to - op
in Q(a)[x], where:
rop | is the Qax polynomial receiving the result; and |
op | is the Qax polynomial being negated. |
void (*mul) (struct calib_Qax_obj * rop, const struct calib_Qax_obj * op1, const struct calib_Qax_obj * op2);
Set rop
to op1 * op2
in Q(a)[x], where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*ipow) (struct calib_Qax_obj * rop, const struct calib_Qax_obj * op, int power);
Set rop
to op ** power
in Q(a)[x], 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_Qax_obj * (*dup) (const struct calib_Qax_obj * op);
Return a dynamically-allocated Qax polynomial that is a copy of
op
, where:
op | is the polynomial to be duplicated. |
void (*free) (struct calib_Qax_obj * poly);
Free the given dynamically-allocated polynomial poly
, where:
poly | is the polynomial to be freed. |
This is equivalent to performing Qax -> clear (poly);
, followed
by free (poly);
.
void (*eval) (struct calib_Qa_obj * rop, const struct calib_Qax_obj * poly, const struct calib_Qa_obj * value);
Evaluate polynomial poly
at the given value
, storing the
result in rop
, where:
rop | is the Qa value object receiving the result; |
poly | is the polynomial to be evaluated; and |
value | is the Qa value at which to evaluate the polynomial. |
void (*eval_poly) (struct calib_Qax_obj * rop, const struct calib_Qax_obj * poly, const struct calib_Qax_obj * value);
Evaluate polynomial poly
at the given value
(which is
itself a polynomial in K_of_X
), storing the result in
rop
, where:
rop | receives the Qax polynomial result; |
poly | is the polynomial to be evaluated; and |
value | is the Qax polynomial at which to evaluate the polynomial. |
void (*div) (struct calib_Qax_obj * quotient, struct calib_Qax_obj * remainder, const struct calib_Qax_obj * a, const struct calib_Qax_obj * b);
Polynomial division in Q(a)[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 Q(a)[x] has the following properties:
void (*gcd) (struct calib_Qax_obj * gcd, const struct calib_Qax_obj * a, const struct calib_Qax_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. |
The GCD is always monic unless a = b = 0.
void (*extgcd) (struct calib_Qax_obj * gcd, struct calib_Qax_obj * xa, struct calib_Qax_obj * xb, const struct calib_Qax_obj * a, const struct calib_Qax_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_Qax_factor * (*factor) (const struct calib_Qax_obj * poly);
Factor the given polynomial poly
into its irreducible
factors over Q(a)[x], returning a linked list of these factors,
where:
poly | is the Qax polynomial to be factored. |
Except for an optional leading constant factor, all other factors are monic and irreducible.
struct calib_Qax_factor * (*factor_square_free) (const struct calib_Qax_obj * sqfpoly);
Given sqfpoly
that is monic, square-free and of degree at least
1, factor it into irreducible factors, where
sqfpoly | is the Qax polynomial to be factored. |
This is a subroutine used by Qax::factor(). Two different methods are supported:
struct calib_Qax_factor * (*finish_sqf) ( const struct calib_Qax_factor * sqfactors);
Given a list of monic, square-free polynomial sqfactors
,
“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 Qax polynomial factors for which factorization into irreducibles is desired. |
void (*free_factors) (struct calib_Qax_factor * factors);
Free up the given list of Qax factors, where:
factors | is a linked-list factors to be freed. |
const struct calib_Qax_dom * (*algint_dom) (const struct calib_Qax_dom * dom);
Return the Qax domain representing the algebraic integer corresponding
to given domain dom
, where:
dom | is the Qax domain for which to get the corresponding algebraic integer domain. |
Returns dom
when the coefficient field of dom
is already
an algebraic integer.
Note: Do NOT free this domain, because it is owned by the given
Q(a)[x] domain dom
!
void (*to_algint) (struct calib_Qax_obj * rop, const struct calib_Qax_obj * op);
Set rop
to be the same Q(a)[x] value as op
, but
coefficients represented in terms of the algebraic integer
corresponding to op
’s coefficient domain, where:
rop | is the Qax polynomial receiving the result; and |
op | is the source Qax polynomial. |
Let D be the Qax domain of op
.
The domain of rop
must either be identically D, or it
must be the algebraic integer domain corresponding to D (e.g.,
as returned by Qax::algint_dom()
).
void (*from_algint) (struct calib_Qax_obj * rop, const struct calib_Qax_obj * op);
Set rop
to be the same Q(a)[x] polynomial as op
,
converting the coefficients from the algebraic integer domain back to
the original (possibly algebraic non-integer) domain, where:
rop | is the Qax polynomial receiving the result; and |
op | is the source Qax polynomial. |
Let D be the Qax domain of rop
.
The domain of op
must either be identically D, or it
must be the algebraic integer domain corresponding to D
(e.g., as returned by Qax::algint_dom()
).
calib_bool (*zerop) (const struct calib_Qax_obj * op);
Return 1 if-and-only-if the given Qax polynomial is identically zero and 0 otherwise, where:
op | is the Qax polynomial to test for zero. |
calib_bool (*onep) (const struct calib_Qax_obj * op);
Return 1 if-and-only-if the given Qax polynomial is identically one and 0 otherwise, where:
op | is the Qax polynomial to test for one. |
void (*set_genrep) (struct calib_Qax_obj * rop, const struct calib_genrep * op, const char * xvar, const char * avar);
Compute a Qax polynomial obtained from the given genrep op
,
interpreting xvar
to be the name of the variable used by the
Qax polynomial and avar
to be the name of the variable used by
the Qa coefficients, storing the result in rop
, where:
rop | is the Qax polynomial receiving the result; |
op | is the genrep to convert into Qax polynomial form; |
xvar | is the variable name (appearing within genrep op ) that is
to be interpreted as the polynomial variable in Qax; and |
avar | is the variable name (appearing within genrep op ) that is
to be interpreted as the variable used by the Qa coefficients. |
struct calib_genrep * (*to_genrep) (const struct calib_Qax_obj * op, const char * xvar, const char * avar);
Return a dynamically-allocated genrep corresponding to the given Qax
polynomial op
, using xvar
as the name of the Qax
polynomial variable and avar
as the name of the Qa
coefficient variable within the returned genrep, where:
op | is the Qax polynomial to convert into genrep form; |
xvar | is the variable name to use in the genrep for the polynomial variable of Qax; and |
avar | is the variable name to use in the genrep for the Qa coefficients. |
struct calib_genrep * (*factors_to_genrep) (const struct calib_Qax_factor * factors, const char * xvar, const char * avar);
Return a dynamically-allocated genrep corresponding to the given list
of Qax factors
, using xvar
as the name of the Qax
polynomial variable and avar
as the name of the Qa
coefficient variable within the returned genrep, where:
factors | is the list of Qax polynomial factors to convert into genrep form; and |
xvar | is the variable name to use in the genrep for the polynomial variable of Qax; |
avar | is the variable name to use in the genrep for the Qa coefficients. |
size_t (*bit_size) (const struct calib_Qax_obj * op);
Return the maximum “bit size” among all rational coefficients of the
given Qax polynomial op
(the rational bit size is the number of significant bits in the
product of the numerator and denominator), where:
op | is the Qax polynomial for which to return the bit size. |
size_t (*bit_size) (const struct calib_Qax_factor * factors);
Return the maximum “bit size” among all rational coefficients of all
the given list factors
of Qax factors
(the rational bit size is the number of significant bits in the
product of the numerator and denominator), where:
factors | is a linked-list of Qax polynomial factors for which to return the bit size. |
const struct calib_Zax_dom * (*get_Zax_dom) (const struct calib_Qax_dom * K_of_x);
Return the Z(a)[x] version of the given Q(a)[x] domain
K_of_x
, where:
K_of_x | is the Qax polynomial domain whose corresponding Zax polynomial domain is sought. |
Note: Do NOT free this domain, because it is owned by the given
Q(a)[x] domain K_of_x
!