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


8 Zxyz — The Polynomial Ring Z[x,y,z,...]

CALIB provides the Zxyz domain, representing the ring Z[x,y,z,...], the multivariate polynomials having integer coefficients. The “values” of this domain are represented by the following object:

struct calib_Zxyz_obj {
	int			nterms;	/* Number of terms in polynomial */
	int			size;	/* Size of pow[] and coeff[] arrays */
	const struct calib_Zxyz_dom *
				dom;	/* Domain of polynomial */
	int *			pow;	/* Powers of each var, each term */
	mpz_ptr			coeff;	/* Coefficient for each term	*/
};

A Zxyz polynomial with n terms and k variables uses n*k elements of the pow array (each term specifies the exponent for all k variables); and n elements of the coeff array. The terms are sorted lexically by their k-element power vectors (largest degrees before smaller).

These objects are subject to init() and clear() operations. All such objects must be initialized prior to use by any other CALIB operation. Memory leaks result if they are not cleared when done.

The following additional object is used to represent linked-lists of factors produced by various Zxyz factorization algorithms:

struct calib_Zxyz_factor {
	int				multiplicity;
	struct calib_Zxyz_obj *		factor;
	struct calib_Zxyz_factor *	next;
};

When making a Zxyz domain, one must specify the number of variables and a textual name for each. These are stored in the fields:

	struct calib_Zxyz_dom {
		int	nvars;		/* Number of variables */
		char **	vars;		/* Name of each variable */
		...
	};

One may access CALIB’s Zxyz domain as follows:

	#include "calib/Zxyz.h"
	...
        const struct calib_Zxyz_dom *	Zxyz;
	struct calib_Zxyz_obj		poly1, poly2;
	const char *			varnames [3] = {"x", "y", "z"};
	...
	Zxyz = calib_make_Zxyz_dom (3, varnames);
	...
	Zxyz -> init (&poly1);
	Zxyz -> init (&poly2);
	...
	Zxyz -> mul (&poly1, &poly1, &poly2);
	...
	Zxyz -> clear (&poly2);
	Zxyz -> clear (&poly1);
	...
	calib_free_Zxyz_dom (Zxyz);

The struct calib_Zxyz_dom object contains the following members (pointers to functions) that provide operations of the domain:

Zxyz::init():

	void	(*init) (const struct calib_Zxyz_dom *	dom,
			 struct calib_Zxyz_obj *	x);

Initialize the given Zxyz polynomial x, where:

domis the Zxyz ring/domain the polynomial belongs to; and
xis the polynomial to initialize.

Zxyz::init_si():

	void	(*init_si) (const struct calib_Zxyz_dom *	dom,
			    struct calib_Zxyz_obj *		x,
			    calib_si_t			        op);

Initialize the given Zxyz polynomial x to the given constant value op, where:

domis the Zxyz ring/domain the polynomial belongs to; and
xis the polynomial to initialize; and
opis the constant value to which polynomial x is set.

Zxyz::alloc():

	void	(*alloc) (struct calib_Zxyz_obj *	rop,
			  int				nterms);

Force the given (already initialized) polynomial rop to have buffer space sufficient to hold a polynomial having at least the given nterms number of (non-zero) terms, where:

ropis the polynomial whose allocation is to be adjusted; and
ntermsis the guaranteed minimum number of terms that polynomial rop will be able to hold (without further buffer allocation) upon successful completion of this operation.

Zxyz::clear():

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

Clear out the given polynomial x (freeing all memory it might hold and returning it to the constant value of zero), where:

xis the polynomial to be cleared.

Zxyz::set():

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

Set rop to op in Zxyz, where:

ropis the polynomial receiving the result;
opis the polynomial to copy.

Zxyz::set_si():

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

Set rop to op in Zxyz, where:

ropis the polynomial receiving the result;
opis the integer value to set.

Zxyz::set_z():

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

Set rop to op in Zxyz, where:

ropis the polynomial receiving the result;
opis the GMP integer value to set.

Zxyz::set_var_power():

	void	(*set_var_power)
			 (struct calib_Zxyz_obj *	rop,
			  int				var,
			  int				power);

Set rop to var ** power in Zxyz, where:

ropis the polynomial receiving the result;
varis the index of the variable; and
poweris the power to set (must be non-negative).

Zxyz::add():

	void	(*add) (struct calib_Zxyz_obj *		rop,
			const struct calib_Zxyz_obj *	op1,
			const struct calib_Zxyz_obj *	op2);

Set rop to op1 + op2 in Zxyz, where:

ropis the polynomial receiving the result;
op1is the first operand; and
op2is the second operand.

Zxyz::add_n():

	void	(*add_n) (struct calib_Zxyz_obj *		rop,
			  int					npoly,
			  const struct calib_Zxyz_obj **	poly_ptrs);

Add npoly polynomials together (given by the poly_ptrs), storing the result in rop, where:

ropis the polynomial receiving the result;
npolyis the number of polynomials being added; and
poly_ptrsis an array of pointers to the polynomials being added.

Zxyz::sub():

	void	(*sub) (struct calib_Zxyz_obj *		rop,
			const struct calib_Zxyz_obj *	op1,
			const struct calib_Zxyz_obj *	op2);

Set rop to op1 - op2 in Zxyz, where:

ropis the polynomial receiving the result;
op1is the first operand; and
op2is the second operand.

Zxyz::neg():

	void	(*neg) (struct calib_Zxyz_obj *		rop,
			const struct calib_Zxyz_obj *	op);

Set rop to - op in Zxyz, where:

ropis the polynomial receiving the result;
opis the operand to negate.

Zxyz::mul():

	void	(*mul) (struct calib_Zxyz_obj *		rop,
			const struct calib_Zxyz_obj *	op1,
			const struct calib_Zxyz_obj *	op2);

Set rop to op1 * op2 in Zxyz, where:

ropis the polynomial receiving the result;
op1is the first operand; and
op2is the second operand.

Zxyz::mul_z():

	void	(*mul_z) (struct calib_Zxyz_obj *	rop,
			  const struct calib_Zxyz_obj *	op1,
			  mpz_srcptr			op2);

Set rop to op1 * op2 in Zxyz, where:

ropis the polynomial receiving the result;
op1is the first (polynomial) operand; and
op2is the second (GMP integer) operand.

Zxyz::ipow():

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

Set rop to op ** power in Zxyz, where:

ropis the polynomial receiving the result;
opis the polynomial to exponentiate; and
poweris the power to take (must be >= 0).

Zxyz::dup():

	struct calib_Zxyz_obj *
		(*dup) (const struct calib_Zxyz_obj *	op);

Return a dynamically-allocated Zxyz polynomial that is a copy of op, where:

opis the polynomial to be duplicated.

Zxyz::free():

	void	(*free) (struct calib_Zxyz_obj *	poly);

Free the given dynamically-allocated polynomial poly, where:

polyis the polynomial to be freed.

This is equivalent to performing Zxyz -> clear (poly);, followed by free (poly);.

Zxyz::eval():

	void	(*eval) (mpz_ptr			rop,
			 const struct calib_Zxyz_obj *	poly,
			 mpz_srcptr			values);

Evaluate polynomial poly at the given values, storing the result in rrop, where:

ropis the GMP integer receiving the result;
polyis the polynomial to be evaluated; and
valuesis an array of GMP integer values (one per variable) at which to evaluate the polynomial.

Zxyz::eval_var_subset():

	void	(*eval_var_subset)
			(struct calib_Zxyz_obj *	rop,
			 const struct calib_Zxyz_obj *	poly,
			 const calib_bool *		evflags,
			 mpz_srcptr			values);

Evaluate polynomial poly at a specified subset of its variables, storing the result in rop. For each variable i, evaluate away variable i at value values[i] if-and-only-if evflags[i] is true, where:

ropis the GMP integer receiving the result;
polyis the polynomial to be evaluated;
evflagsis an array of booleans (one per variable) for which TRUE means to evaluate the corresponding variable; and
valuesis an array of GMP integer values (one per variable) at which to evaluate the polynomial.

Zxyz::div():

	void	(*div) (struct calib_Zxyz_obj *		quotient,
			struct calib_Zxyz_obj *		remainder,
			struct calib_Zxyz_obj *		d,
			const struct calib_Zxyz_obj *	a,
			const struct calib_Zxyz_obj *	b,
			int				var);

Polynomial pseudo-division in Z[x,y,z] with respect to a specified main variable var, where:

quotientreceives the quotient polynomial (may be NULL);
remainderreceives the remainder polynomial (may be NULL);
dreceives the “denominator” value (may be NULL);
ais the dividend polynomial;
bis the divisor polynomial (may not be zero);
varis the main variable for division.

Pseudo-division has the following properties:

Zxyz::div_z_exact():

	void	(*div_z_exact)
			(struct calib_Zxyz_obj *	rop,
			 const struct calib_Zxyz_obj *	op1,
			 mpz_srcptr			op2);

Set rop to op1 / op2 in Zxyz, where:

ropreceives result polynomial;
op1is the dividend polynomial; and
op2is the GMP integer by which to divide poly.

It is a fatal error if the division is not exact.

Zxyz::div_remove():

	int	(*div_remove)
			(struct calib_Zxyz_obj *	rop,
			 const struct calib_Zxyz_obj *	op1,
			 const struct calib_Zxyz_obj *	op2);

Repeatedly divide polynomial op1 by polynomial op2 until no more factors op2 can be removed, storing op1 / op2**k into rop and returning k, where:

ropreceives result polynomial;
op1is the dividend polynomial; and
op2is the divisor polynomial.

Zxyz::gcd():

	void	(*gcd) (struct calib_Zxyz_obj *		gcd,
			const struct calib_Zxyz_obj *	a,
			const struct calib_Zxyz_obj *	b);

Compute the greatest common divisor (GCD) of a and b, storing the result in gcd, where:

gcdreceives the resulting GCD polynomial;
ais the first operand polynomial; and
bis the second operand polynomial.

Zxyz::gcd_n():

	void	(*gcd_n) (struct calib_Zxyz_obj *	gcd,
			  struct calib_Zxyz_obj **	cofact,
			  int				npoly,
			  const struct calib_Zxyz_obj **
							array);

Compute the greatest common divisor (GCD) polynomial that simultaneously divides n given polynomials, where:

gcdreceives the resulting GCD polynomial;
cofactis an array of nfact pointers to polynomials receiving the cofactor corresponding to each given input polynomial (may be NULL);
npolyis the number of input polynomials provided; and
arrayis an array of nfact pointers to input polynomials whose GCD is to be computed.

This can be vastly more efficient that decomposing this into nfact-1 consecutive calls to the gcd function.

Zxyz::extgcd():

	void	(*extgcd) (struct calib_Zxyz_obj *		gcd,
			   struct calib_Zxyz_obj *		xa,
			   struct calib_Zxyz_obj *		xb,
			   mpz_ptr				d,
			   const struct calib_Zxyz_obj *	a,
			   const struct calib_Zxyz_obj *	b);

The extended Euclidean algorithm. Compute polynomials gcd, xa and xb such that gcd = a * xa + b * xb, where:

gcdreceives the resulting GCD polynomial;
xareceives the multiplier polynomial for a;
xbreceives the multiplier polynomial for b;
dreceives the denominator for xa and xb;
ais the first operand polynomial; and
bis the second operand polynomial.

Zxyz::z_content():

	void	(*z_content)
			(mpz_ptr			zcont,
			 const struct calib_Zxyz_obj *	op);

Compute the integer content zcont of the given polynomial op, where:

zconta GMP integer receiving the content of op;
opthe polynomial whose integer content is to be computed.

Zxyz::strip_z_content():

	void	(*strip_z_content)
			(mpz_ptr			zcont,
			 struct calib_Zxyz_obj *	poly);

Compute and remove the content from the given polynomial poly, where:

zconta GMP integer receiving the content of poly;
polythe polynomial whose content is to be computed and removed.

Zxyz::prim_part():

	void	(*prim_part)
			(mpz_ptr			content,
			 struct calib_Zxyz_obj *	ppart,
			 const struct calib_Zxyz_obj *	op,
			 int				var);

Compute the multi-variate polynomial content (with respect to given main variable var) of polynomial op and setting ppart to be the primitive part, where:

contentreceives the content of op with respect to variable var;
ppartreceives primitive part of op with respect to variable var;
opthe polynomial to be decomposed into content and primitive parts; and
varis the main variable with respect to which the content is computed.

Zxyz::resultant():

	void	(*resultant)
			(mpz_ptr			result,
			 const struct calib_Zxyz_obj *	a,
			 const struct calib_Zxyz_obj *	b,
			 int				var);

Compute the resultant of polynomials a and b with respect to given main variable var, storing the result in result, where:

resultis the resultant of given polynomials;
ais the first operand;
bis the second operand; and
varis the main variable to use / eliminate.

Zxyz::resultant_old():

	struct calib_Zxyz_factor *
		(*resultant)
			(const struct calib_Zxyz_obj *	a,
			 const struct calib_Zxyz_obj *	b,
			 int				var);

Compute the resultant of polynomials a and b with respect to given main variable var, returning the result as a partially-factored list of factors, where:

ais the first operand;
bis the second operand; and
varis the main variable to use / eliminate.

Note: This is an old and very naive implementation!!! Use only on small polynomials of fairly low degree!

Zxyz::discriminant():

	void	(*discriminant)
			(struct calib_Zxyz_obj *	rop,
			 const struct calib_Zxyz_obj *	op,
			 int				var);

Set rop to be the discriminant of polynomial op with respect to variable var, where:

ropis the resulting polynomial;
opis the polynomial for which to compute the discriminant; and
varis the main variable to use / eliminate.

Zxyz::cvZpxyz():

	void	(*cvZpxyz) (const calib_Zxyz_obj *		rop,
			    const struct calib_Zp_dom *		Zp,
			    const struct calib_Zxyz_obj *	op);

Compute a polynomial in Z[x,y,z] that is the corresponding representative of the given polynomial op in Zp[x,y,z] (given in Zxyz form but having coefficients mod p — the Z coefficients are chosen to have smallest absolute value that are equivalent to the correponding Zp coefficient), storing the result in rrop, where:

ropreceives the resulting polynomial;
Zpis the source Zp coefficient domain; and
opis the Zxyz polynomial (with Zp coefficients) to convert into Zxyz form.

Zxyz::factor():

	struct calib_Zxyz_factor *
		(*factor) (const struct calib_Zxyz_obj *	poly);

Factor the given polynomial poly into its irreducible factors, returning a linked list of these factors, where:

polyis the Zxyz polynomial to be factored.

See the Note in Zx::factor() regarding the Van Hoeij and LLL algorithms.

Zxyz::sqf_factor():

	struct calib_Zxyz_factor *
		(*sqf_factor)
			(const struct calib_Zxyz_obj *	poly);

Perform “square-free factorization” of given polynomial poly, where:

polyis the Zxyz polynomial to be square-free factored.

Zxyz::free_factors():

	void	(*free_factors)
			(struct calib_Zxyz_factor *	factors);

Free up the given list of Zxyz factors, where:

factorsis a linked-list factors to be freed.

Zxyz::map_to_subring():

	struct calib_Zxyz_obj *
		(*map_to_subring)
			(struct calib_Zxyz_obj *	result,
			 const struct calib_Zxyz_obj *	poly,
			 const struct calib_Zxyz_dom *	subring,
			 const int *			varmap);

Map the given polynomial poly from its original ring into a new polynomial whose coefficients reside in the given subring. The varmap array controls this mapping on a variable-by-variable basis. Let i be a variable index within the original polynomial ring, and let j = varmap [i]. Then j = -1 ==> variable i remains in the source ring, whereas j >= 0 ==> variable i (from the original ring) maps to variable j of the subring. (j must satisfy 0 <= j < subring.nvars.)

Since the calib_Zxyz_obj representation handles only GMP integer coefficients, the result object contains only dummy “1” coefficient values. The actual coefficients are found in this function’s return values, which is an array of struct calib_Zxyz_obj objects (each of whose dom member is the given subring). This returned array has the same number of elements as result -> nterms. It is the caller’s responsibility to free up the coefficient array when done with it. The arguments are:

resultThe high-level structural result (but with “dummy” coefficient values of 1);
polyis the Zxyz polynomial to be mapped into the given subring;
subringis the Zxyz domain describing the subring into which we are mapping coefficients; and
varmapis the array specifying how each variable in poly is to be mapped.

Zxyz::copy_into_superring():

	struct calib_Zxyz_obj *
		(*copy_into_superring)
			(struct calib_Zxyz_obj *	rop,
			 const struct calib_Zxyz_obj *	op);

Set rop to op. The domain of rop and op need not be the same, but the rop domain must have at least as many variables as the domain of op. Extra variables receive a power of zero in every term copied. The arguments are:

ropthe destination polynomial / domain; and
opthe source polynomial / domain.

Zxyz::convert_with_varmap():

	void	(*convert_with_varmap)
			(struct calib_Zxyz_obj *	rop,
			 const struct calib_Zxyz_obj *	op,
			 const int *			varmap);

Convert a polynomial from one ring to another, mapping variables according to the given varmap. Variables mapping to -1 in the varmap must not appear in the source polynomial op. The arguments are:

ropthe destination polynomial / domain;
opthe source polynomial / domain; and
varmapthe variable mapping array.

Zxyz::copy_from_Zx():

	void	(*copy_from_Zx)
			(struct calib_Zxyz_obj *	rop,
			 const struct calib_Zx_obj *	op,
			 int				var);

Set Zxyz polynomial rop to Zx polynomial op. The polynomial op becomes a polynomial in the given var of the rop polynomial. The arguments are:

ropthe destination Zxyz polynomial / domain;
opthe source Zx polynomial; and
varthe dst polynomial variable to use.

Zxyz::copy_into_Zx():

	void	(*copy_into_Zx)
			(struct calib_Zx_obj *		rop,
			 const struct calib_Zxyz_obj *	op,
			 int				var);

Set Zx polynomial rop to Zxyz polynomial op (which must contain only given variable var), where:

ropthe destination Zx polynomial;
opthe source Zxyz polynomial / domain; and
varthe source polynomial variable.

Zxyz::copy_from_Zpx():

	void	(*copy_from_Zpx)
			(struct calib_Zxyz_obj *	rop,
			 const struct calib_Zpx_obj *	op,
			 int				var);

Set Zxyz polynomial rop from Zpx polynomial op. The polynomial op becomes a polynomial in the given var of the rop polynomial. The arguments are:

ropthe destination Zxyz polynomial / domain;
opthe source Zpx polynomial; and
varthe destination polynomial variable to use.

Zxyz::copy_into_Zpx():

	void	(*copy_into_Zpx)
			(struct calib_Zpx_obj *		rop,
			 const struct calib_Zxyz_obj *	op,
			 int				var);

Set Zpx polynomial rop to Zxyz polynomial op (which must contain only givenvariable var), where:

ropthe destination Zpx polynomial;
opthe source Zxyz polynomial / domain; and
varthe source polynomial variable.

Zxyz::copy_from_Qax():

	void	(*copy_from_Qax)
			(struct calib_Zxyz_obj *	rop,
			 mpz_ptr			denom,
			 const struct calib_Qax_obj *	op,
			 int				xvar,
			 int				avar);

Copy the given op polynomial (in Qax form) into the given destination polynomial (in Zxyz form). The op polynomial’s main variable becomes xvar of the rop polynomial, while the op polynomial’s algebraic variable becomes the given avar of the rop polynomial, where:

ropthe destination Zxyz polynomial / domain;
denomreceives the common denominator;
opthe source Qax polynomial;
xvarmain variable of op becomes variable xvar in rop polynomial; and
avaralgebraic variable of op becomes variable avar in rop polynomial.

Zxyz::copy_into_Qax():

	void	(*copy_into_Qax)
			(struct calib_Qax_obj *		rop,
			 const struct calib_Zxyz_obj *	op,
			 int				xvar,
			 int				avar);

Set Qax polynomial rop to Zxyz polynomial op. Variable xvar of op becomes the main variable of rop, while variable avar of op becomes the algebraic variable of rop, where:

ropthe destination Qax polynomial;
opthe source Zxyz polynomial / domain; and
xvarsource polynomial variable xvar becomes the main variable of rop; and
avarsource polynomial variable avar becomes the algebraic number variable of rop.

Zxyz::add_vars():

	struct calib_Zxyz_dom *
		(*add_vars)
			(const struct Zxyz_dom *	dom,
			 int				nvars,
			 const char * const *		newvars);

Create a new Zxyz domain having the given additional variables over those in given domain dom, where:

domis the original Zxyz domain;
nvarsis the number of variables to add; and
newvarsis an array of the new variable names being added.

Zxyz::zerop():

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

Return 1 if-and-only-if the given Zxyz polynomial is identically zero and 0 otherwise, where:

opis the Zxyz polynomial to test for zero.

Zxyz::onep():

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

Return 1 if-and-only-if the given Zxyz polynomial is identically 1 and 0 otherwise, where:

opis the Zxyz polynomial to test for one.

Zxyz::set_genrep():

	void	(*set_genrep) (struct calib_Zxyz_obj *		rop,
			       const struct calib_genrep *	op);

Compute a Zxyz polynomial obtained from the given genrep op, storing the result in rop. Use the domain of rop to map variable names in op to variable numbers in the resulting polynomial, where:

ropreceives the resulting Zxyz polynomial;
opis the genrep to convert into Zxyz polynomial form.

Zxyz::to_genrep():

	struct calib_genrep *
		(*to_genrep) (const struct calib_Zxyz_obj *	op);

Return a dynamically-allocated genrep corresponding to the given Zxyz polynomial op (whose Zxyz domain provides variable names to use for each variable number), where:

opis the Zxyz polynomial to convert into genrep form.

Zxyz::factors_to_genrep():

	struct calib_genrep *
		(*factors_to_genrep)
			(const struct calib_Zxyz_factor *	factors);

Return a dynamically-allocated genrep corresponding to the given list of Zxyz factors (each of whose Zxyz domain provides variable names to use for each variable number), where:

factorsis the list of Zxyz polynomial factors to convert into genrep form.

Zxyz::print_maxima():

	void	(*print_maxima)
			(const struct calib_Zxyz_obj *	op);

Print the given Zxyz polynomial op to stdout using syntax that can be directly read by Maxima, where:

opis the Zxyz polynomial to be printed.

Zxyz::print_maxima_nnl():

	void	(*print_maxima_nnl)
			(const struct calib_Zxyz_obj *	op);

Print the given Zxyz polynomial op to stdout using syntax that can be directly read by Maxima (but with no terminating newline), where:

opis the Zxyz polynomial to be printed.

Zxyz::lookup_var():

	int	(*lookup_var)
			(const struct calib_Zxyz_dom *	dom,
			 const char *			var);

Return the index of the variable whose name is var, or -1 if var does not match any of the variables in the given domain dom, where:

domis the Zxyz domain within which to lookup variable var; and
varis the variable name to query.

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