CALIB provides the Qa
domain, representing the field
Q(a), the extension of the rationals with given algebraic
number a (specified via an irreducible polynomial in
Z[x] of degree at least 2).
The “values” of this domain are represented by the following object:
/* * An instance of a value in Q(a). We represent this as the product * of a rational multiplier times a primitive Z[x] polynomial whose leading * coefficient (if any) is strictly positive. */ struct calib_Qa_obj { mpq_t qfact; /* Rational multiplier */ const struct calib_Qa_dom * dom; /* Q(a) domain containing this value */ int degree; /* Degree of this value in a */ mpz_ptr coeff; /* Coefficients. This is always an */ /* array of k integers so that */ /* reallocation is never required */ };
These objects are subject to init()
and clear()
operations.
Memory leaks result if they are not cleared when done.
The CALIB Qa
domain is constructed by specifying an irreducible
polynomial in Z[x] of degree at least 2.
One may access CALIB’s Qa
domain as follows:
#include "calib/Qa.h" ... struct calib_Zx_obj * apoly; struct calib_Qa_dom * Qa; apoly = /* polynomial defining 'a'. */ Qa = calib_make_Qa_dom (apoly); ... calib_free_Qa_dom (Qa);
Let d be the degree of the polynomial defining the algebraic
number a.
The “values” of this Qa domain are polynomials in Q[a] having
degree at most d-1 stored in the struct calib_Za_obj
object.
The struct calib_Qa_dom
object contains the following members
(pointers to functions) that provide operations of the domain:
void (*init) (const struct calib_Qa_dom * f, struct calib_Qa_obj * x);
Initialize Qa value object x
to be a member of the Qa domain
f
, where:
f | is the Qa domain performing this operation; and |
x | is the Qa value object to be initialized. |
void (*clear) (struct calib_Qa_obj * x);
Clear out the given Qa value object x
(freeing all memory it
might hold), where:
x | is the Qa value object to be cleared. |
void (*set) (struct calib_Qa_obj * rop, const struct calib_Qa_obj * op);
Set rop
to op
in Q(a), where:
rop | is the Qa value object receiving the result; and |
src | is the source Qa value object. |
void (*set_si) (struct calib_Qa_obj * rop, calib_si_t op);
Set rop
to op
in Q(a), where:
rop | is the Qa value object receiving the result; and |
op | is the signed integer to convert into Q(a) form. |
void (*set_z) (struct calib_Qa_obj * rop, mpz_srcptr op);
Set rop
to op
in Q(a), where:
rop | is the Qa value object receiving the result; and |
op | is the GMP integer to convert into Q(a) form. |
void (*set_q) (struct calib_Qa_obj * rop, mpq_srcptr op);
Set rop
to op
in Q(a), where:
rop | is the Qa value object receiving the result; and |
op | is the GMP rational to convert into Q(a) form. |
void (*set_var_power) (struct calib_Qa_obj * rop, int power);
Set rop
to a**power
in Q(a) (a is the
Q(a) polynomial variable), where:
rop | is the Qa value object receiving the result; and |
power | is the power to set (may be positive, zero or negative). |
void (*set_Za_q) (struct calib_Qa_obj * rop, const struct calib_Za_obj * op1, mpq_srcptr op2);
Set rop
to op1 * op2
(op1
is a Za value
and op2
is a GMP rational), where:
rop | is the Qa value object receiving the result; |
op1 | is the Za value to convert into Qa form; and |
op2 | is a GMP rational multiplier. |
The generator polynomials for rop
and op1
must have the
same degree (so that this conversion can be done one coefficient at a
time).
void (*set_Zx) (struct calib_Qa_obj * rop, const struct calib_Zx_obj * op);
Set rop
to op
(op
is a Zx polynomial whose variable
becomes a
), where:
rop | is the Qa value object receiving the result; |
op | is the Zx polynomial to evaluate at a . |
Polynomial op
must have degree strictly less than the generator
polynomial of the Qa field.
void (*add) (struct calib_Qa_obj * rop, const struct calib_Qa_obj * op1, const struct calib_Qa_obj * op2);
Set rop
to op1 + op2
in Q(a), where:
rop | is the Qa value object receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*sub) (struct calib_Qa_obj * rop, const struct calib_Qa_obj * op1, const struct calib_Qa_obj * op2);
Set rop
to op1 - op2
in Q(a), where:
rop | is the Qa value object receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*neg) (const struct calib_Qa_dom * f, mpq_ptr result, mpq_srcptr op);
Set rop
to - op
in Q(a)
, where:
rop | is the Qa value object receiving the result; and |
op | is the operand being negated. |
void (*mul) (struct calib_Qa_obj * rop, const struct calib_Qa_obj * op1, const struct calib_Qa_obj * op2);
Set rop
to op1 * op2
in Q(a), where:
rop | is the Qa value object receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*mul_si) (struct calib_Qa_obj * rop, const struct calib_Qa_obj * op1, calib_si_t op2);
Set rop
to op1 * op2
in Q(a), where:
rop | is the Qa value object receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*mul_z) (struct calib_Qa_obj * rop, const struct calib_Qa_obj * op1, mpz_srcptr op2);
Set rop
to op1 * op2
in Q(a), where:
rop | is the Qa value object receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*mul_q) (struct calib_Qa_obj * rop, const struct calib_Qa_obj * op1, mpq_srcptr op2);
Set rop
to op1 * op2
in Q(a), where:
rop | is the Qa value object receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*ipow) (struct calib_Qa_obj * rop, const struct calib_Qa_obj * op, int power);
Set rop
to op**power
in Q(a), where:
rop | is the Qa value object receiving the result; |
op | is the operand to exponentiate; and |
power | is the power to take (can be positive, negative or zero). |
void (*inv) (struct calib_Qa_obj * rop, const struct calib_Qa_obj * op);
Set rop
to the multiplicative inverse of op
in
Q(a), where:
rop | is the Qa value object receiving the result; and |
op | is the operand to invert. |
calib_bool (*is_algint) (const struct calib_Qa_dom * dom);
Return TRUE if-and-only-if the given Q(a) domain is an algebraic integer, where:
dom | is the Qa domain to test. |
const struct calib_Qa_dom * (*algint_dom) (const struct calib_Qa_dom * dom);
Return the Qa domain representing the algebraic integer corresponding
to given domain dom
, where:
dom | is the Qa domain for which to get the corresponding algebraic integer domain. |
Returns dom
when dom
is already an algebraic integer.
Note: Do NOT free this domain, because it is owned by the given
Q(a) domain dom
!
void (*to_algint) (struct calib_Qa_obj * rop, const struct calib_Qa_obj * op);
Set rop
to be the same Q(a) value as op
, but
represented in terms of the algebraic integer corresponding to
op
’s domain, where:
rop | is the Qa value object receiving the result; and |
op | is the source Qa value. |
Let D be the Qa 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 Qa::algint_dom()
).
void (*from_algint) (struct calib_Qa_obj * rop, const struct calib_Qa_obj * op);
Set rop
to be the same Q(a) value as op
, converting
from the algebraic integer domain back to the original (possibly
algebraic non-integer) domain, where:
rop | is the Qa value object receiving the result; and |
op | is the source Qa value. |
Let D be the Qa 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 Qa::algint_dom()
).
int (*degree) (const struct calib_Qa_obj * op);
Return the degree (in variable a of the Q(a)
generator polyomial) of the given element op
of
Q(a), where:
op | is the operand whose degree is to be returned. |
calib_bool (*zerop) (const struct calib_Qa_obj * op);
Return 1 if-and-only-if op
is identically zero and 0 otherwise,
where:
op | is the Qa value object to test for zero. |
calib_bool (*onep) (const struct calib_Qa_obj * op);
Return 1 if-and-only-if op
is identically 1 and 0 otherwise,
where:
op | is the Qa value object to test for one. |
void (*set_genrep) (struct calib_Qa_obj * rop, const struct calib_genrep * op, const char * var);
Given a genrep op
and the name var
of the Q(a)
generator polynomial variable (as it appears in op
), convert
this genrep into a value in this Q(a) domain, storing the
result in rop
, where:
rop | is the Qa value object receiving the Q(a) value; |
op | is the genrep being converted; and |
var | is the name of the algebraic number a appearing within
genrep op . |
struct calib_genrep * (*to_genrep) (const struct calib_Qa_obj * op, const char * var);
Return a dynamically-allocated genrep representing the given Qa
value op
, using the given variable name var
to represent
the algebraic number a of Q(a), where:
op | is value from Q(a) being converted to genrep form; and |
var | is the name of the algebraic number a as it should appear
within the genrep returned. |
size_t (*bit_size) (const struct calib_Qa_obj * op);
Return the maximum “bit size” among all rational coefficients of the
given Qa value op
(the rational bit size is the number of significant bits in the
product of the numerator and denominator), where:
op | is the Qa value for which to return the bit size. |
mpq_ptr (*get_coeffs) (const struct calib_Qa_obj * op);
Return an array of GMP rationals containing the coefficients of the
given Qa value op
, where:
op | is the Qa value for which to return the coefficients. |
It is the caller’s responsibility to free the returned array (of
length op->degree+1
).
void (*set_coeffs) (struct calib_Qa_obj * rop, int degree, mpq_srcptr coeffs);
Set rop
to be the Q(a) value having the given degree
degree
and rational coefficients coeffs
, where:
rop | is the Qa value object receiving the result; |
degree | is the degree (in algebraic number a ) of the value; and |
coeffs | is an array of degree+1 rational coefficients. |
It is permitted for degree >= k
, where k
is the degree
of the generator polynomial g(a)
defining this algebraic number
domain (in which case the resulting value is reduced modulo
g(a)
).
const struct calib_Za_dom * (*get_Za_dom) (const struct calib_Qa_dom * f);
Return the Z(a) version of this Q(a) domain, where:
f | is the Qa field/domain whose corresponding Za ring/domain is sought. |
Note: Do NOT free this domain, because it is owned by the given
Q(a) domain rp
!