Next: , Previous: , Up: Top   [Contents][Index]


15 Qa — The Field Q(a)

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:

Qa::init():

	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:

fis the Qa domain performing this operation; and
xis the Qa value object to be initialized.

Qa::clear():

	void		(*clear) (struct calib_Qa_obj *	x);

Clear out the given Qa value object x (freeing all memory it might hold), where:

xis the Qa value object to be cleared.

Qa::set():

	void	(*set) (struct calib_Qa_obj *		rop,
			const struct calib_Qa_obj *	op);

Set rop to op in Q(a), where:

ropis the Qa value object receiving the result; and
srcis the source Qa value object.

Qa::set_si():

	void	(*set_si) (struct calib_Qa_obj *	rop,
			   calib_si_t			op);

Set rop to op in Q(a), where:

ropis the Qa value object receiving the result; and
opis the signed integer to convert into Q(a) form.

Qa::set_z():

	void	(*set_z) (struct calib_Qa_obj *		rop,
			  mpz_srcptr			op);

Set rop to op in Q(a), where:

ropis the Qa value object receiving the result; and
opis the GMP integer to convert into Q(a) form.

Qa::set_q():

	void	(*set_q) (struct calib_Qa_obj *		rop,
			  mpq_srcptr			op);

Set rop to op in Q(a), where:

ropis the Qa value object receiving the result; and
opis the GMP rational to convert into Q(a) form.

Qa::set_var_power():

	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:

ropis the Qa value object receiving the result; and
poweris the power to set (may be positive, zero or negative).

Qa::set_Za_q():

	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:

ropis the Qa value object receiving the result;
op1is the Za value to convert into Qa form; and
op2is 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).

Qa::set_Zx():

	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:

ropis the Qa value object receiving the result;
opis the Zx polynomial to evaluate at a.

Polynomial op must have degree strictly less than the generator polynomial of the Qa field.

Qa::add():

	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:

ropis the Qa value object receiving the result;
op1is the first operand; and
op2is the second operand.

Qa::sub():

	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:

ropis the Qa value object receiving the result;
op1is the first operand; and
op2is the second operand.

Qa::neg():

	void	(*neg) (const struct calib_Qa_dom *	f,
			mpq_ptr				result,
			mpq_srcptr			op);

Set rop to - op in Q(a), where:

ropis the Qa value object receiving the result; and
opis the operand being negated.

Qa::mul():

	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:

ropis the Qa value object receiving the result;
op1is the first operand; and
op2is the second operand.

Qa::mul_si():

	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:

ropis the Qa value object receiving the result;
op1is the first operand; and
op2is the second operand.

Qa::mul_z():

	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:

ropis the Qa value object receiving the result;
op1is the first operand; and
op2is the second operand.

Qa::mul_q():

	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:

ropis the Qa value object receiving the result;
op1is the first operand; and
op2is the second operand.

Qa::ipow():

	void	(*ipow) (struct calib_Qa_obj *		rop,
			 const struct calib_Qa_obj *	op,
			 int				power);

Set rop to op**power in Q(a), where:

ropis the Qa value object receiving the result;
opis the operand to exponentiate; and
poweris the power to take (can be positive, negative or zero).

Qa::inv():

	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:

ropis the Qa value object receiving the result; and
opis the operand to invert.

Qa::is_algint():

	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:

domis the Qa domain to test.

Qa::algint_dom():

	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:

domis 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!

Qa::to_algint():

	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:

ropis the Qa value object receiving the result; and
opis 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()).

Qa::from_algint():

	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:

ropis the Qa value object receiving the result; and
opis 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()).

Qa::degree():

	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:

opis the operand whose degree is to be returned.

Qa::zerop():

	calib_bool
		(*zerop) (const struct calib_Qa_obj *	op);

Return 1 if-and-only-if op is identically zero and 0 otherwise, where:

opis the Qa value object to test for zero.

Qa::onep():

	calib_bool
		(*onep) (const struct calib_Qa_obj *	op);

Return 1 if-and-only-if op is identically 1 and 0 otherwise, where:

opis the Qa value object to test for one.

Qa::set_genrep():

	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:

ropis the Qa value object receiving the Q(a) value;
opis the genrep being converted; and
varis the name of the algebraic number a appearing within genrep op.

Qa::to_genrep():

	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:

opis value from Q(a) being converted to genrep form; and
varis the name of the algebraic number a as it should appear within the genrep returned.

Qa::bit_size():

	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:

opis the Qa value for which to return the bit size.

Qa::get_coeffs():

	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:

opis 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).

Qa::set_coeffs():

	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:

ropis the Qa value object receiving the result;
degreeis the degree (in algebraic number a) of the value; and
coeffsis 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)).

Qa::get_Za_dom():

	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:

fis 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!


Next: , Previous: , Up: Top   [Contents][Index]