[BACK]Return to ntlconv.cpp CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_ntl

File: [local] / OpenXM / src / ox_ntl / ntlconv.cpp (download)

Revision 1.6, Fri Oct 18 01:28:52 2013 UTC (10 years, 6 months ago) by iwane
Branch: MAIN
CVS Tags: RELEASE_1_3_1_13b, HEAD
Changes since 1.5: +10 -12 lines

update NTL 5.3.3 -> 6.0.0 and fix compile errors

/* $OpenXM: OpenXM/src/ox_ntl/ntlconv.cpp,v 1.6 2013/10/18 01:28:52 iwane Exp $ */

#include <NTL/ZZX.h>
#include <NTL/mat_ZZ.h>

#include <sstream>
#include <string>
#include <string.h>

#include "ntl.h"

#if __NTL_DEBUG
#define __NTL_PRINT (1)
#endif

/*==========================================================================*
 * Block interrupt input
 *==========================================================================*/
#define BLOCK_NEW_CMO()         BLOCK_INPUT()
#define UNBLOCK_NEW_CMO()       UNBLOCK_INPUT()



/*==========================================================================*
 * Check string format
 *==========================================================================*/

#define NtlIsSpace(c)  ((c) == ' ' || (c) == '\t')
#define NtlIsDigit(c)  ((c) >= '0' && (c) <= '9')

/****************************************************************************
 *
 * test for string format of integer
 *
 * PARAM : I : str    : string
 *       : O : endptr :
 * RETURN: !0         : the string tests true
 *       :  0         : the string tests false
 *
 ****************************************************************************/
static int
ntl_isZZstr_(const char *str, char const **endptr)
{
	while (NtlIsSpace(*str))
		str++;

	/* NTL reject "+999"  */
	if (*str == '-')
		str++;

	if (!NtlIsDigit(*str))
		return (0);

	str++;

	while (NtlIsDigit(*str))
		str++;

	*endptr = str;

	return (!0);

}

static int
ntl_isZZstr(const char *str)
{
	const char *ptr;
	int ret = ntl_isZZstr_(str, &ptr);
	if (!ret)
		return (ret);

	while (NtlIsSpace(*ptr))
		ptr++;

	return (*ptr == '\0');
}


/****************************************************************************
 *
 * test for string format of univariate polynomials with integer coefficients
 * in NTL style.
 *
 * PARAM : I : str    : string
 *       : O : endptr :
 * RETURN: !0         : the string tests true
 *       :  0         : the string tests false
 *
 ****************************************************************************/
static int
ntl_isZZXstr_(const char *str, char const **endptr)
{
	const char *s;

	while (NtlIsSpace(*str))
		str++;

	if (*str != '[')
		return (0);

	str++;

	while (*str != ']' && *str != '\0') {

		if (!ntl_isZZstr_(str, &s))
			return (0);
		str = s;

		while (NtlIsSpace(*str))
			str++;
	}

	while (NtlIsSpace(*str))
		str++;

	if (*str != ']')
		return (0);

	str++;
	*endptr = str;
	return (!0);
}

static int
ntl_isZZXstr(const char *str)
{
	const char *ptr;
	int ret = ntl_isZZXstr_(str, &ptr);
	if (!ret)
		return (ret);

	while (NtlIsSpace(*ptr))
		ptr++;

	return (*ptr == '\0');
}


/*==========================================================================*
 * Convert
 *==========================================================================*/
/****************************************************************************
 * convert ZZ to cmo_zz
 *
 * PARAM : I : z       : integer
 * RETURN: cmo_zz
 ****************************************************************************/
cmo_zz *
ZZ_to_cmo_zz(const ZZ &z)
{
	cmo_zz *c;
	const char *ptr;

	std::ostringstream sout;
	sout << z << '\0';
	std::string tmp = sout.str();
	ptr = tmp.c_str();

	BLOCK_NEW_CMO();
	c = new_cmo_zz_set_string((char*)ptr);
	UNBLOCK_NEW_CMO();
	
	return (c);
}


/****************************************************************************
 * convert cmo to ZZ which is integer
 *
 * PARAM : O : z       : integer.
 *       : I : c       : cmo.
 * RETURN: success     : NTL_SUCCESS
 *       : failure     : NTL_FAILURE
 ****************************************************************************/
int
cmo_to_ZZ(ZZ &z, cmo *c)
{
	int ret = NTL_SUCCESS;
	char *str;

	switch (c->tag) {
	case CMO_ZERO:
	case CMO_NULL:
		z = to_ZZ(0);
		break;
	case CMO_ZZ:
	{
		str = new_string_set_cmo(c);
		z = to_ZZ(str);
		break;
	}
	case CMO_INT32:
		z = to_ZZ(((cmo_int32 *)c)->i);
		break;
	case CMO_STRING:
	{
		str = ((cmo_string *)c)->s;
		if (!ntl_isZZstr(str))
			return (NTL_FAILURE);
		z = to_ZZ(str);
		break;
	}
	default:
		ret = NTL_FAILURE;
		break;
	}

	return (ret);
}


/****************************************************************************
 * convert cmo to ZZX which is polynomial in Z[x]
 *
 * PARAM : O : f       : polynomial in Z[x]
 *       : I : m       : cmo.
 *       : O : x       : indeterminate
 * RETURN: success     : NTL_SUCCESS
 *       : failure     : NTL_FAILURE
 ****************************************************************************/
cmo_list *
mat_zz_to_cmo(mat_ZZ &mat)
{
	cmo_list *list;

	cmo_zz *zz;
	int row, col;
	int i, j;

	row = (int)mat.NumRows();
	col = (int)mat.NumCols();

	BLOCK_NEW_CMO();
	list = list_appendl(NULL, new_cmo_int32(row), new_cmo_int32(col), NULL);

	for (i = 0; i < row; i++) {
		for (j = 0; j < col; j++) {
			zz = ZZ_to_cmo_zz(mat[i][j]);
			list_append(list, (cmo *)zz);
		}
	}
	UNBLOCK_NEW_CMO();

	return (list);
}




/****************************************************************************
 * convert cmo to ZZX which is polynomial in Z[x]
 *
 * PARAM : O : f       : polynomial in Z[x]
 *       : I : m       : cmo.
 *       : O : x       : indeterminate
 * RETURN: success     : NTL_SUCCESS
 *       : failure     : NTL_FAILURE
 ****************************************************************************/
int
cmo_to_mat_zz(mat_ZZ &mat, cmo *m)
{
	cmo_list *list;
	int ret;
	ZZ row, col, size;
	int len;
	cell *el;
	int i, j;
	int c, r;

	if (m->tag != CMO_LIST) {
		return (NTL_FAILURE);
	}

	list = (cmo_list *)m;
	len = list_length(list);

	if (len < 2) {
		return (NTL_FAILURE);
	}

	el = list_first(list);
	ret = cmo_to_ZZ(row, el->cmo);
	if (ret != NTL_SUCCESS) {
		return (ret);
	}

	el = list_next(el);
	ret = cmo_to_ZZ(col, el->cmo);
	if (ret != NTL_SUCCESS) {
		return (ret);
	}

	mul(size, row, col);

	if (len - 2 != size) {
		return (NTL_FAILURE);
	}

	/* row and col is less than INT_MAX */
	r = to_int(row);
	c = to_int(col);
	mat.SetDims(r, c);
	for (i = 0; i < r; i++) {
		for (j = 0; j < c; j++) {
			el = list_next(el);
			ret = cmo_to_ZZ(mat[i][j], el->cmo);
			if (ret) {
				return (ret);
			}
		}
	}
	return (NTL_SUCCESS);
}



/****************************************************************************
 * convert cmo to ZZX which is polynomial in Z[x]
 *
 * PARAM : O : f       : polynomial in Z[x]
 *       : I : m       : cmo.
 *       : O : x       : indeterminate
 * RETURN: success     : NTL_SUCCESS
 *       : failure     : NTL_FAILURE
 ****************************************************************************/
int
cmo_to_ZZX(ZZX &f, cmo *m, cmo_indeterminate *&x)
{
	char *str;
	int ret;

	switch (m->tag) {
	case CMO_STRING:   /* [ 3 4 7 ] ==> 3+4*x+7*x^2 */
		str = ((cmo_string *)m)->s;
		ret = ntl_isZZXstr(str);

		if (!ret) {
			/* format error */
			return (NTL_FAILURE);
		}
		{
			std::istringstream sin(str);
			sin >> f;
		}
		break;
	case CMO_RECURSIVE_POLYNOMIAL:
	{
		cmo_recursive_polynomial *rec = (cmo_recursive_polynomial *)m;
		cmo_polynomial_in_one_variable *poly = (cmo_polynomial_in_one_variable *)rec->coef;
		cell *el;

		if (poly->tag != CMO_POLYNOMIAL_IN_ONE_VARIABLE) {
			return (NTL_FAILURE);
		}

		el = list_first((cmo_list *)poly);

		f = 0;

		while (!list_endof((cmo_list *)poly, el)) {
			ZZ c;
			cmo *coef = el->cmo;
			int exp = el->exp;

			ret = cmo_to_ZZ(c, coef);
			if (ret != NTL_SUCCESS) {
				return (NTL_FAILURE);
			}

			SetCoeff(f, exp, c);

			el = list_next(el);			
		}


		el = list_first(rec->ringdef);
		x = (cmo_indeterminate *)el->cmo;

		break;	
	}
	default:
		break;
	}
	return (NTL_SUCCESS);
}



/****************************************************************************
 * convert polynomial in Z[x] to cmo_recursive_polynomial
 *
 * PARAM : I : factor  : polynomial in Z[x]
 *       : I : x       : indeterminate
 * RETURN: 
 ****************************************************************************/
cmo_recursive_polynomial *
ZZX_to_cmo(ZZX &factor, cmo_indeterminate *x)
{
	cmo_recursive_polynomial *rec;
	cmo_polynomial_in_one_variable *poly;

	cmo_list *ringdef;
	int i;
	cmo *coef;

	BLOCK_NEW_CMO();

	ringdef = new_cmo_list();
	list_append(ringdef, (cmo *)x);

	poly = new_cmo_polynomial_in_one_variable(0);
	for (i = deg(factor); i >= 0; i--) {
		if (coeff(factor, i) == 0)
			continue;

		coef = (cmo *)ZZ_to_cmo_zz(coeff(factor, i));
		list_append_monomial((cmo_list *)poly, coef, i);
	}

	rec = new_cmo_recursive_polynomial(ringdef, (cmo *)poly);

	UNBLOCK_NEW_CMO();

	return (rec);
}


/****************************************************************************
 * convert pair of factor and multiplicity to cmo_list
 *
 * PARAM : I : factor  : polynomial in Z[x]
 *       : I : d       : multiplicity
 *       : I : x       : indeterminate
 * RETURN: 
 ****************************************************************************/
cmo_list *
ZZX_int_to_cmo(ZZX &factor, int d, cmo_indeterminate *x)
{
	cmo_recursive_polynomial *poly;
	cmo_int32 *deg;
	cmo_list *list;

	poly = ZZX_to_cmo(factor, x);

	BLOCK_NEW_CMO();

	deg = new_cmo_int32(d);
	list = list_appendl(NULL, poly, deg, NULL);

	UNBLOCK_NEW_CMO();

	return (list);
}


/****************************************************************************
 * convert vec_pair_ZZX_long(list which pair of factor and multiplicity)
 * to cmo_list
 *
 * PARAM : I : factors : list which pair of factor and multiplicity 
 *       :   :         :  [[factor1,multiplicity1][factor2,multiplicity2]...]
 *       : I : x       : indeterminate
 * RETURN: 
 ****************************************************************************/
cmo_list *
vec_pair_ZZX_long_to_cmo(vec_pair_ZZX_long &factors, cmo_indeterminate *x)
{
	int i;
	cmo_list *list;
	cmo_list *factor;

	BLOCK_NEW_CMO();

	list = new_cmo_list();
	for (i = 0; i < factors.length(); i++) {
		factor = ZZX_int_to_cmo(factors[i].a, (int)factors[i].b, x);
		list_append(list, (cmo *)factor);
	}

	UNBLOCK_NEW_CMO();

	return (list);
}


/****************************************************************************
 * convert local object to cmo.
 * for SM_popCMO
 *
 * PARAM : I : p : cmo
 * RETURN: cmo
 ****************************************************************************/
cmo *
convert_cmon(cmo *p)
{
	switch (p->tag) {
	case CMON_ZZ:
	{
		cmon_zz_t *z = (cmon_zz_t *)p;
		return ((cmo *)ZZ_to_cmo_zz(*z->z));
	}
	case CMON_ZZX:
	{
		cmon_zzx_t *f = (cmon_zzx_t *)p;
		return ((cmo *)ZZX_to_cmo(*f->f, f->x));
	}
	case CMON_FACTORS:
	{
		cmon_factors_t *f = (cmon_factors_t *)p;
		cmo_zz *z = ZZ_to_cmo_zz(*f->cont);
		cmo_list *list = vec_pair_ZZX_long_to_cmo(*f->f, f->x);
		return ((cmo *)list_appendl(NULL, (cmo *)z, list, NULL));
	}
	case CMON_MAT_ZZ:
	{
		cmon_mat_zz_t *m = (cmon_mat_zz_t *)p;
		cmo_list *list = mat_zz_to_cmo(*m->mat);
		return ((cmo *)list);
	}
	default:
		return (p);
	}
}



/****************************************************************************
 * convert tag of local object to tag of cmo.
 * for SM_pushCMOtag
 *
 * PARAM : I : p : cmo
 * RETURN:  tag
 ****************************************************************************/
int
get_cmon_tag(cmo *p)
{
	switch (p->tag) {
	case CMON_ZZ:
		return (CMO_ZZ);
	case CMON_ZZX:
		return (CMO_RECURSIVE_POLYNOMIAL);
	case CMON_FACTORS:
		return (CMO_LIST);
	case CMON_MAT_ZZ:
		return (CMON_MAT_ZZ);
	default:
		return (p->tag);
	}
}