This is polynom.c in view mode; [Download] [Up]
/****************************************************************************
**
*A polynom.c GAP source Frank Celler
**
*H @(#)$Id: polynom.c,v 3.19 1994/05/06 13:20:03 fceller Rel $
**
*Y Copyright 1990-1992, Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany
**
*H $Log: polynom.c,v $
*H Revision 3.19 1994/05/06 13:20:03 fceller
*H removed unused variable
*H
*H Revision 3.18 1994/02/07 14:11:32 fceller
*H changed interface slightly, the functions now accept list with
*H mixed entries and they will not automatically shorten the result
*H
*H Revision 3.17 1993/10/15 09:09:50 martin
*H added 'register' to circumvent a MPW C compiler bug
*H
*H Revision 3.16 1993/06/02 11:37:13 fceller
*H added 'ProductsCoeffsMod', renamed 'ReduceModCoeffs' to 'ReduceCoeffsMod'
*H
*H Revision 3.15 1993/05/05 11:11:43 fceller
*H replace a wrong 'TYPE' by 'XType'
*H
*H Revision 3.14 1993/03/01 10:33:13 fceller
*H adapted to new list concept
*H
*H Revision 3.13 1993/02/11 17:08:55 fceller
*H removed creation of T_VECTOR of length 4
*H
*H Revision 3.12 1993/02/04 18:20:32 martin
*H fixed 'PowerModVecInt' from passing wrong degree to 'MultiplyVector'
*H
*H Revision 3.11 1993/02/04 10:51:10 martin
*H changed to use 'plist' interface
*H
*H Revision 3.10 1993/01/06 17:53:39 fceller
*H removed creation of T_VECFFE of length 4
*H
*H Revision 3.9 1992/11/25 11:28:50 fceller
*H fixed a bug in 'UnifyFFE'
*H
*H Revision 3.8 1992/11/16 17:49:35 fceller
*H added 'ReduceCoeffs' and 'ShiftedCoeffs'
*H
*H Revision 3.7 1992/08/20 10:56:59 fceller
*H pleased GCC
*H
*H Revision 3.6 1992/08/17 11:18:46 fceller
*H fixed handling of empty lists in 'AddCoeffs'
*H
*H Revision 3.5 1992/07/06 08:09:09 fceller
*H fixed a typo
*H
*H Revision 3.4 1992/07/02 11:06:19 fceller
*H add 'AddCoeffs'
*H
*H Revision 3.3 1992/07/02 10:09:00 fceller
*H add 'SumCoeffs'
*H
*H Revision 3.2 1992/05/25 08:56:08 fceller
*H Initial GAP 3.2 release
*/
#include "system.h" /* system dependent functions */
#include "gasman.h" /* dynamic storage manager */
#include "scanner.h" /* reading of tokens and printing */
#include "eval.h" /* evaluator main dispatcher */
#include "integer.h" /* arbitrary size integers */
#include "finfield.h" /* finite field package */
#include "list.h" /* generic list package */
#include "plist.h" /* plain list package */
#include "vector.h" /* vector package */
#include "vecffe.h" /* finite field vector package */
#include "polynom.h" /* polynomial package */
/****************************************************************************
**
*F UnifiedFieldVecFFE( <hdL>, <hdR> ) . . . unify fields of <hdL> and <hdR>
**
** Convert two finite field vectors into finite field vectors over the same
** finite field. Signal an error if this conversion fails.
*/
TypHandle UnifiedFieldVecFFE ( hdL, hdR )
TypHandle hdL; /* first finite field vector */
TypHandle hdR; /* second finite field vector */
{
TypHandle hdFld; /* handle of the field */
unsigned long p; /* characteristic */
unsigned long q; /* size of common finite field */
unsigned long q1; /* size of field of row */
unsigned long dl; /* degree of <hdL> */
unsigned long dr; /* degree of <hdR> */
TypHandle hdElm; /* one row of the list */
TypFFE v; /* value of one element */
unsigned long i, k; /* loop variables */
/* if <hdL> and <hdR> have already the same field return */
if ( FLD_VECFFE(hdL) == FLD_VECFFE(hdR) )
return FLD_VECFFE(hdL);
/* check the we know a common superfield of <hdL> and <hdR> */
p = CharVecFFE(hdL);
if ( p != CharVecFFE(hdR) )
return Error( "vectors have different characteristic", 0L, 0L );
/* compute degree of superfield */
dl = DegreeVecFFE(hdL);
dr = DegreeVecFFE(hdR);
for ( k = dl; dl % dr != 0; dl += k ) ;
/* make sure we can handle this field */
if ( ( 2 <= p && 17 <= dl ) || ( 3 <= p && 11 <= dl )
|| ( 5 <= p && 7 <= dl ) || ( 7 <= p && 6 <= dl )
|| ( 11 <= p && 5 <= dl ) || ( 17 <= p && 4 <= dl )
|| ( 41 <= p && 3 <= dl ) || ( 257 <= p && 2 <= dl ) )
{
return Error( "common superfield is too large", 0L, 0L );
}
/* get a field that contains all elements */
for ( q = 1, k = 1; k <= dl; k++ ) q *= p;
if ( (SIZE_FF(FLD_VECFFE(hdL))-1) % (q-1) == 0 )
hdFld = FLD_VECFFE(hdL);
else if ( (SIZE_FF(FLD_VECFFE(hdR))-1) % (q-1) == 0 )
hdFld = FLD_VECFFE(hdR);
else
hdFld = FLD_FFE( RootFiniteField( q ) );
q = SIZE_FF(hdFld);
/* convert <hdL> and <hdR> */
for ( i = 0; i <= 1; i++ )
{
hdElm = ( i == 0 ) ? hdL : hdR;
if ( FLD_VECFFE(hdElm) != hdFld )
{
q1 = SIZE_FF( FLD_VECFFE(hdElm) );
for ( k = LEN_VECFFE(hdElm); 0 < k; k-- )
{
v = VAL_VECFFE( hdElm, k );
SET_VAL_VECFFE( hdElm, k, v==0 ? v : (v-1)*(q-1)/(q1-1)+1 );
}
SET_FLD_VECFFE( hdElm, hdFld );
}
}
/* and return the common */
return FLD_VECFFE(hdL);
}
/****************************************************************************
**
*F FunShiftedCoeffs( <hdCall> ) . . . . . internal function 'ShiftedCoeffs'
**
** 'FunShiftedCoeffs' implements 'ShiftedCoeffs( <l>, <n> )'
*/
TypHandle (*TabShiftedCoeffs[T_VAR]) P(( TypHandle, long ));
TypHandle FunShiftedCoeffs ( hdCall )
TypHandle hdCall;
{
TypHandle hdC; /* coeffs list */
TypHandle hdN; /* number of shifts */
/* check arguments */
if ( SIZE(hdCall) != 3 * SIZE_HD )
return Error( "usage: ShiftedCoeffs( <c>, <nr> )", 0L, 0L );
hdC = EVAL( PTR(hdCall)[1] );
hdN = EVAL( PTR(hdCall)[2] );
if ( TYPE(hdN) != T_INT )
return Error( "<nr> must be an integer", 0L, 0L );
/* jump through the table */
return TabShiftedCoeffs[XType(hdC)]( hdC, HD_TO_INT(hdN) );
}
TypHandle CantShiftedCoeffs ( hdList, n )
TypHandle hdList;
long n;
{
return Error( "<list> must be a vector", 0L, 0L );
}
TypHandle ShiftedCoeffsListx ( hdC, n )
TypHandle hdC;
long n;
{
TypHandle hdS; /* result */
TypHandle hdZero; /* zero element */
long l; /* length of <hdC> */
long i;
/* compute the length of <hdC> */
l = LEN_LIST(hdC);
if ( l == 0 )
hdS = Copy(hdC);
/* if <n> is negative shrink <hdC> */
else if ( n < 0 ) {
/* if <l> is not bigger than <n>, <hdC> will shrink to nothing */
if ( l <= -n ) {
hdS = NewBag( T_LIST, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdS, 0 );
return hdS;
}
/* allocate a new vector and copy the entries */
hdS = NewBag( T_LIST, SIZE_PLEN_PLIST(l+n) );
SET_LEN_PLIST( hdS, l+n );
for ( i = l; -n < i; i-- )
SET_ELM_PLIST( hdS, i+n, ELM_PLIST(hdC,i) );
}
/* if <n> is positive, copy entries and leading zero */
else if ( 0 < n ) {
hdS = NewBag( T_LIST, SIZE_PLEN_PLIST(l+n) );
SET_LEN_PLIST( hdS, l+n );
for ( i = l; 0 < i; i-- )
SET_ELM_PLIST( hdS, i+n, ELM_PLIST(hdC,i) );
hdZero = PROD( ELML_LIST(hdC,1), INT_TO_HD(0) );
for ( i = n; 0 < i; i-- )
SET_ELM_PLIST( hdS, i, hdZero );
}
/* if <n> is zero, return a copy of <hdC> */
else
hdS = Copy(hdC);
/* return <hdS> */
return hdS;
}
TypHandle ShiftedCoeffsVecFFE ( hdC, n )
TypHandle hdC;
long n;
{
TypHandle hdS; /* result */
TypFFE tmp; /* temporary */
long l; /* length of <hdC> */
long i;
/* compute the length of <hdC> */
l = LEN_VECFFE(hdC);
/* if <n> is negative shrink <hdL> */
if ( n < 0 ) {
/* if <l> is not bigger than <n>, <hdL> will shrink to nothing */
if ( l <= -n ) {
hdS = NewBag( T_LIST, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdS, 0 );
return hdS;
}
/* allocate a new vector and copy the entries */
hdS = NewBag( T_VECFFE, SIZE_PLEN_VECFFE(l+n) );
SET_FLD_VECFFE( hdS, FLD_VECFFE(hdC) );
for ( i = l; -n < i; i-- ) {
tmp = VAL_VECFFE( hdC, i );
SET_VAL_VECFFE( hdS, i+n, tmp );
}
}
/* if <n> is positive, copy <hdC> and leading zeros */
else if ( 0 < n )
{
hdS = NewBag( T_VECFFE, SIZE_PLEN_VECFFE(l+n) );
SET_FLD_VECFFE( hdS, FLD_VECFFE(hdC) );
for ( i = l; 0 < i; i-- ) {
tmp = VAL_VECFFE( hdC, i );
SET_VAL_VECFFE( hdS, i+n, tmp );
}
for ( i = n; 0 < i; i-- )
SET_VAL_VECFFE( hdS, i, 0 );
}
/* if <n> is zero, copy <hdL> and shrink if necessary */
else
hdS = Copy(hdC);
return hdS;
}
/****************************************************************************
**
*F FunNormalizeCoeffs( <hdCall> ) . . . internal function 'NormalizeCoeffs'
**
** 'FunNormalizeCoeffs' implements 'NormalizeCoeffs( <c> )'
*/
TypHandle (*TabNormalizeCoeffs[T_VAR]) P(( TypHandle ));
TypHandle FunNormalizeCoeffs ( hdCall )
TypHandle hdCall;
{
TypHandle hdC;
/* check arguments */
if ( SIZE( hdCall ) != 2 * SIZE_HD )
return Error( "usage: NormalizeCoeffs( <c> )", 0L, 0L );
hdC = EVAL( PTR(hdCall)[1] );
/* jump through the table */
return TabNormalizeCoeffs[XType(hdC)]( hdC );
}
TypHandle CantNormalizeCoeffs ( hdList )
TypHandle hdList;
{
return Error( "<list> must be a vector", 0L, 0L );
}
TypHandle NormalizeCoeffsVecFFE ( hdC )
TypHandle hdC;
{
TypFFE tmp; /* temporary */
long len; /* length of <hdC> */
long l1; /* first non zero entry */
long l2; /* last non zero entry */
long i; /* loop */
/* check for leading zeros */
len = LEN_VECFFE(hdC);
for ( l1 = 1; l1 <= len; l1++ )
if ( VAL_VECFFE( hdC, l1 ) != 0 )
break;
/* check for trailing zero */
for ( l2 = len; l1 < l2; l2-- )
if ( VAL_VECFFE( hdC, l2 ) != 0 )
break;
/* if it is trivial, return empty list */
if ( l2 < l1 ) {
Retype( hdC, T_LIST );
Resize( hdC, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdC, 0 );
return INT_TO_HD(0);
}
/* remove leadinf zeros */
if ( 1 < l1 )
for ( i = l1; i <= l2; i++ ) {
tmp = VAL_VECFFE( hdC, i );
SET_VAL_VECFFE( hdC, i-l1+1, tmp );
}
/* shrink vector */
Resize( hdC, SIZE_PLEN_VECFFE(l2-l1+1) );
/* return the number of removed trailing zeros */
return INT_TO_HD(l1-1);
}
TypHandle NormalizeCoeffsListx ( hdC )
TypHandle hdC;
{
TypHandle hdZero; /* temporary */
TypHandle hdTmp; /* temporary */
long len; /* length of <hdC> */
long l1; /* first non zero entry */
long l2; /* last non zero entry */
long i; /* loop */
/* construct zero */
if ( LEN_LIST(hdC) == 0 )
return INT_TO_HD(0);
hdZero = PROD( INT_TO_HD(0), ELM_LIST(hdC,1) );
/* check for leading zeros */
len = LEN_LIST(hdC);
for ( l1 = 1; l1 <= len; l1++ ) {
hdTmp = ELML_LIST(hdC,l1);
if ( EQ( hdTmp, hdZero ) == HdFalse )
break;
}
/* check for trailing zero */
for ( l2 = len; l1 < l2; l2-- ) {
hdTmp = ELML_LIST(hdC,l2);
if ( EQ( hdTmp, hdZero ) == HdFalse )
break;
}
/* if it is trivial, return empty list */
if ( l2 < l1 ) {
Retype( hdC, T_LIST );
Resize( hdC, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdC, 0 );
return INT_TO_HD(0);
}
/* remove leading zeros */
if ( 1 < l1 )
for ( i = l1; i <= l2; i++ ) {
hdTmp = ELML_LIST( hdC, i );
SET_ELM_PLIST( hdC, i-l1+1, hdTmp );
}
/* shrink vector */
Resize( hdC, SIZE_PLEN_PLIST(l2-l1+1) );
SET_LEN_PLIST( hdC, l2-l1+1 );
/* return the number of removed trailing zeros */
return INT_TO_HD(l1-1);
}
/****************************************************************************
**
*F FunShrinkCoeffs( <hdCall> ) . . . . . . internal function 'ShrinkCoeffs'
**
** 'FunShrinkCoeffs' implements 'ShrinkCoeffs( <c> )'
*/
void (*TabShrinkCoeffs[T_VAR]) P(( TypHandle ));
TypHandle FunShrinkCoeffs ( hdCall )
TypHandle hdCall;
{
TypHandle hdC;
/* check arguments */
if ( SIZE( hdCall ) != 2 * SIZE_HD )
return Error( "usage: ShrinkCoeffs( <c> )", 0L, 0L );
hdC = EVAL( PTR(hdCall)[1] );
/* jump through the table */
TabShrinkCoeffs[XType(hdC)]( hdC );
return HdVoid;
}
void CantShrinkCoeffs ( hdList )
TypHandle hdList;
{
Error( "<list> must be a vector", 0L, 0L );
}
void ShrinkCoeffsVecFFE ( hdC )
TypHandle hdC;
{
long len; /* length of <hdC> */
long i; /* loop */
/* check for trailing zero */
len = LEN_VECFFE(hdC);
for ( i = len; 0 < i; i-- )
if ( VAL_VECFFE( hdC, i ) != 0 )
break;
/* if it is trivial, return empty list */
if ( 0 == i ) {
Retype( hdC, T_LIST );
Resize( hdC, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdC, 0 );
return;
}
/* shrink vector */
Resize( hdC, SIZE_PLEN_VECFFE(i) );
}
void ShrinkCoeffsListx ( hdC )
TypHandle hdC;
{
TypHandle hdZero; /* temporary */
TypHandle hdTmp; /* temporary */
long len; /* length of <hdC> */
long i; /* loop */
/* construct zero */
if ( LEN_LIST(hdC) == 0 )
return;
hdZero = PROD( INT_TO_HD(0), ELM_LIST(hdC,1) );
/* check for trailing zero */
len = LEN_LIST(hdC);
for ( i = len; 0 < i; i-- ) {
hdTmp = ELML_LIST(hdC,i);
if ( EQ( hdTmp, hdZero ) == HdFalse )
break;
}
/* if it is trivial, return empty list */
if ( 0 == i ) {
Retype( hdC, T_LIST );
Resize( hdC, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdC, 0 );
return;
}
/* shrink vector */
Resize( hdC, SIZE_PLEN_PLIST(i) );
SET_LEN_PLIST( hdC, i );
}
/****************************************************************************
**
*F ADD_COEFFS( <hdL>, <hdR>, <hdM> ) . . . . . <hdL>+<hdM>*<hdR> into <hdL>
**
#define ADD_COEFFS( hdL, hdR, hdM ) \
(TabAddCoeffs[XType(hdL)][XType(hdR)]( hdL, hdR, hdM ))
*/
void (*TabAddCoeffs[T_VAR][T_VAR]) P(( TypHandle, TypHandle, TypHandle ));
void CantAddCoeffs ( hdL, hdR, hdM )
TypHandle hdL;
TypHandle hdR;
TypHandle hdM;
{
Error("<l> and <r> must be vectors over a common field", 0L, 0L);
}
void AddCoeffsListxListx ( hdL, hdR, hdM )
TypHandle hdL;
TypHandle hdR;
TypHandle hdM;
{
TypHandle hdLL; /* one element of <hdL> */
TypHandle hdRR; /* one element of <hdR> */
TypHandle hdAA; /* sum of <hdLL> and <hdRR> */
long l; /* length of <hdL> */
long r; /* length of <hdR> */
long m; /* minimum of <l> and <r> */
long i; /* loop variables */
/* compute the length of <hdL> and <hdR> */
l = LEN_LIST(hdL);
r = LEN_LIST(hdR);
/* if <l> is less than <r>, enlarge <hdL> */
if ( l < r ) {
hdLL = PROD( ELML_LIST(hdR,1), INT_TO_HD(0) );
for ( i = l+1; i <= r; i++ )
ASS_LIST( hdL, i, hdLL );
l = r;
}
/* add <hdR> to <hdL> */
m = ( l < r ) ? l : r;
if ( hdM == INT_TO_HD(1) ) {
for ( i = 1; i <= m; i++ ) {
hdLL = ELM_LIST( hdL, i );
hdRR = ELM_LIST( hdR, i );
hdAA = SUM( hdLL, hdRR );
ASS_LIST( hdL, i, hdAA );
}
for ( i = m+1; i <= r; i++ ) {
hdRR = ELM_LIST( hdR, i );
ASS_LIST( hdL, i, hdRR );
}
}
else {
for ( i = 1; i <= m; i++ ) {
hdLL = ELM_LIST( hdL, i );
hdRR = ELM_LIST( hdR, i );
hdRR = PROD( hdRR, hdM );
hdAA = SUM( hdLL, hdRR );
ASS_LIST( hdL, i, hdAA );
}
for ( i = m+1; i <= r; i++ ) {
hdRR = ELM_LIST( hdR, i );
hdRR = PROD( hdRR, hdM );
ASS_LIST( hdL, i, hdRR );
}
}
}
void AddCoeffsVecFFEVecFFE ( hdL, hdR, hdM )
TypHandle hdL;
TypHandle hdR;
TypHandle hdM;
{
long l; /* degree plus one of left polynomial */
long r; /* degree plus one of right polynomial */
TypFFE m; /* multiple of <hdR> to add */
TypFFE * ptL; /* coeffs vectors of left polynomial */
TypFFE * ptR; /* coeffs vectors of right polynomial */
TypFFE * ptE; /* end of coeffs vector of sum */
TypFFE * f; /* finite field */
TypFFE t; /* temp for FFEs */
/* if <hdM> is a finite field element check the field */
if ( TYPE(hdM) == T_FFE ) {
if ( UnifiedFieldVecFFE(hdL,hdR) == FLD_FFE(hdM) )
m = VAL_FFE(hdM);
else {
hdR = PROD( hdR, hdM );
m = 1;
}
}
/* otherwise replace <hdR> by the <hdM> multiple */
else {
if ( INT_TO_HD(1) != hdM ) {
hdR = PROD( hdR, hdM );
hdM = INT_TO_HD(1);
TabAddCoeffs[XType(hdL)][XType(hdR)]( hdL, hdR, hdM );
return;
}
else
m = 1;
}
/* if <m> is trivial there is nothing to add */
if ( m == 0 )
return;
/* if <l> is less than <r> enlarge <hdL> */
l = LEN_VECFFE(hdL);
r = LEN_VECFFE(hdR);
if ( l < r ) {
Resize( hdL, SIZE_PLEN_VECFFE(r) );
SET_VAL_VECFFE( hdL, l+1, 0 );
l = r;
}
/* get the common finite field */
f = (TypFFE*) PTR( UnifiedFieldVecFFE( hdL, hdR ) );
/* set up all the pointers */
ptL = (TypFFE*)( PTR(hdL) + 1 );
ptR = (TypFFE*)( PTR(hdR) + 1 );
ptE = ptR + r;
/* add <hdR> to <hdL> */
if ( m == 1 ) {
while ( ptR < ptE ) {
*ptL = SUM_FF( *ptL, *ptR, f );
ptL++;
ptR++;
}
}
else {
while ( ptR < ptE ) {
t = PROD_FF( *ptR, m, f );
*ptL = SUM_FF( *ptL, t, f );
ptL++;
ptR++;
}
}
}
void AddCoeffsListxVecFFE ( hdL, hdR, hdM )
TypHandle hdL;
TypHandle hdR;
TypHandle hdM;
{
/* catch the special case that <hdL> is empty */
if ( LEN_LIST(hdL) == 0 ) {
Retype( hdL, T_VECFFE );
Resize( hdL, SIZE_PLEN_VECFFE(1) );
SET_FLD_VECFFE( hdL, FLD_VECFFE(hdR) );
SET_VAL_VECFFE( hdL, 1, 0 );
/* use 'AddCoeffsVecFFEVecFFE' */
AddCoeffsVecFFEVecFFE( hdL, hdR, hdM );
}
/* use 'AddCoeffsListxListx' */
else
AddCoeffsListxListx( hdL, hdR, hdM );
}
/****************************************************************************
**
*F FunAddCoeffs( <hdCall> ) . . . . . . . . . internal function 'AddCoeffs'
**
** 'FunAddCoeffs' implements 'AddCoeffs( <l>, <r> )'
*/
TypHandle FunAddCoeffs ( hdCall )
TypHandle hdCall;
{
TypHandle hdL;
TypHandle hdR;
TypHandle hdM;
/* check arguments */
if ( 4 * SIZE_HD < SIZE(hdCall) || SIZE(hdCall) < 3 * SIZE_HD )
return Error( "usage: AddCoeffs( <l>, <r> )", 0L, 0L );
hdL = EVAL( PTR(hdCall)[1] );
hdR = EVAL( PTR(hdCall)[2] );
if ( 4 * SIZE_HD == SIZE(hdCall) )
hdM = EVAL( PTR(hdCall)[3] );
else
hdM = INT_TO_HD(1);
/* jump through the table */
TabAddCoeffs[XType(hdL)][XType(hdR)]( hdL, hdR, hdM );
return HdVoid;
}
/****************************************************************************
**
*F FunSumCoeffs( <hdCall> ) . . . . . . . . . internal function 'SumCoeffs'
**
** 'FunSumCoeffs' implements 'SumCoeffs( <l>, <r> )'
*/
TypHandle FunSumCoeffs ( hdCall )
TypHandle hdCall;
{
TypHandle hdL;
TypHandle hdR;
TypHandle hdM;
/* check arguments */
if ( SIZE(hdCall) != 3 * SIZE_HD )
return Error( "usage: SumCoeffs( <l>, <r> )", 0L, 0L );
hdL = Copy( EVAL( PTR(hdCall)[1] ) );
hdR = EVAL( PTR(hdCall)[2] );
hdM = INT_TO_HD(1);
/* jump through the table */
TabAddCoeffs[XType(hdL)][XType(hdR)]( hdL, hdR, hdM );
/* and return the result stored in <hdL> */
return hdL;
}
/****************************************************************************
**
*F MULTIPLY_COEFFS( <hdP>, <hdL>, <l>, <hdR>, <r> ) <hdL>*<hdR> into <hdP>
**
#define MULTIPLY_COEFFS(hdP,hdL,l,hdR,r) \
(TabMultiplyCoeffs[XType(hdL)][XType(hdR)](hdP,hdL,l,hdR,r))
*/
long (*TabMultiplyCoeffs[T_VAR][T_VAR]) P((
TypHandle, TypHandle, long, TypHandle, long ));
long CantMultiplyCoeffs ( hdP, hdL, l, hdR, r )
TypHandle hdP; /* space for result of <hdL> * <hdR> */
TypHandle hdL; /* left polynomial coeffs */
TypHandle hdR; /* right polynomial coeffs */
long l; /* degree plus one of left polynomial */
long r; /* degree plus one of right polynomial */
{
Error( "<l> and <r> must be vectors over a common field", 0L, 0L);
return 0;
}
long MultiplyCoeffsListxListx ( hdP, hdL, l, hdR, r )
TypHandle hdP; /* space for result of <hdL> * <hdR> */
TypHandle hdL; /* left polynomial coeffs */
TypHandle hdR; /* right polynomial coeffs */
long l; /* degree plus one of left polynomial */
long r; /* degree plus one of right polynomial */
{
TypHandle hdLL; /* one element of <hdL> */
TypHandle hdRR; /* one element of <hdR> */
TypHandle hdPP; /* one element of <hdP> */
TypHandle hdTT; /* temp element */
long i,u,k; /* loop variables */
/* catch the trivial case */
if ( l == 0 || r == 0 )
return 0;
/* fold the product */
for ( i = l+r; 1 < i; i-- )
{
hdPP = INT_TO_HD(0);
u = ( i-1 < l ) ? i-1 : l;
for ( k = ( i-r < 1 ) ? 1 : i-r; k <= u; k++ )
{
hdLL = ELML_LIST( hdL, k );
hdRR = ELMR_LIST( hdR, i-k );
hdTT = PROD( hdLL, hdRR );
hdPP = SUM( hdPP, hdTT );
}
ASS_LIST( hdP, i-1, hdPP );
}
return r+l-1;
}
long MultiplyCoeffsVecFFEVecFFE ( hdP, hdL, l, hdR, r )
TypHandle hdP; /* space for result of <hdL> * <hdR> */
TypHandle hdL; /* left polynomial coeffs */
TypHandle hdR; /* right polynomial coeffs */
long l; /* degree plus one of left polynomial */
long r; /* degree plus one of right polynomial */
{
TypFFE * ptL; /* coeffs vectors of left polynomial */
TypFFE * ptLL; /* coeffs vectors of left polynomial */
TypFFE * ptEnd; /* end of <ptL> */
TypFFE * ptR; /* coeffs vectors of right polynomial */
TypFFE * ptP; /* coeffs vectors of product */
TypFFE * ptPP; /* coeffs vectors of product */
TypFFE * f; /* finite field */
TypFFE t; /* temp for FFEs */
long i; /* loop variable */
/* if the one of the polynomials is trivial, return the zero poly */
if ( l == 0 || r == 0 )
return 0;
/* get a common field of <hdL> and <hdR> */
f = (TypFFE*) PTR( UnifiedFieldVecFFE( hdL, hdR ) );
/* set common field in <hdP> */
SET_FLD_VECFFE( hdP, FLD_VECFFE(hdL) );
/* chose larger vector as multiplicator */
if ( l < r ) {
ptL = (TypFFE*)( PTR(hdL) + 1 );
ptR = (TypFFE*)( PTR(hdR) + 1 );
}
else {
ptR = (TypFFE*)( PTR(hdL) + 1 );
ptL = (TypFFE*)( PTR(hdR) + 1 );
i = l; l = r; r = i;
}
/* clear <hdP> */
ptP = (TypFFE*)( PTR(hdP) + 1 );
for ( ptPP = ptP, ptEnd = ptP + (l+r-1); ptPP < ptEnd; ptPP++ )
*ptPP = 0;
/* add <hdL> to <hdP> multiplied by the elements of <hdR> */
ptEnd = ptL + l;
for ( i = 0; i < r; i++, ptR++, ptP++ ) {
if ( *ptR != 0 ) {
for ( ptLL = ptL, ptPP = ptP; ptLL < ptEnd; ptLL++, ptPP++ )
if ( *ptLL != 0 ) {
t = PROD_FF( *ptLL, *ptR, f );
*ptPP = SUM_FF( *ptPP, t, f );
}
}
}
return l+r-1;
}
/****************************************************************************
**
*F FunProductCoeffs( <hdCall> ) . . . . . internal function 'ProductCoeffs'
**
** 'FunProductCoeffs' implements 'ProductCoeffs( <l>, <r> )'
*/
TypHandle (*TabProductCoeffs[T_VAR][T_VAR]) P(( TypHandle, TypHandle ));
TypHandle FunProductCoeffs ( hdCall )
TypHandle hdCall;
{
TypHandle hdL;
TypHandle hdR;
/* check arguments */
if ( SIZE(hdCall) != 3 * SIZE_HD )
return Error( "usage: ProductCoeffs( <l>, <r> )", 0L, 0L );
hdL = EVAL( PTR(hdCall)[1] );
hdR = EVAL( PTR(hdCall)[2] );
/* jump through the table */
return TabProductCoeffs[XType(hdL)][XType(hdR)]( hdL, hdR );
}
TypHandle CantProductCoeffs ( hdL, hdR )
TypHandle hdL;
TypHandle hdR;
{
return Error("<l> and <r> must be vectors over a common field", 0L, 0L);
}
TypHandle ProductCoeffsListxListx ( hdL, hdR )
TypHandle hdL;
TypHandle hdR;
{
TypHandle hdP; /* result */
long l; /* length of <hdL> */
long r; /* length of <hdR> */
/* get the length of <hdL> and hd <hdR> */
l = LEN_LIST(hdL);
r = LEN_LIST(hdR);
/* if <hdL> or <hdR> is trivial, return the trivial polynomial */
if ( l == 0 || r == 0 ) {
hdP = NewBag( T_LIST, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdP, 0 );
return hdP;
}
/* create a bag for the result */
hdP = NewBag( T_LIST, SIZE_PLEN_PLIST(l+r-1) );
SET_LEN_PLIST( hdP, l+r-1 );
/* fold the product */
TabMultiplyCoeffs[T_LISTX][T_LISTX]( hdP, hdL, l, hdR, r );
/* and return the result */
return hdP;
}
TypHandle ProductCoeffsVecFFEVecFFE ( hdL, hdR )
TypHandle hdL;
TypHandle hdR;
{
TypHandle hdP; /* result */
long l; /* length of <hdL> */
long r; /* length of <hdR> */
/* get the length of <hdL> and hd <hdR> */
l = LEN_VECFFE(hdL);
r = LEN_VECFFE(hdR);
/* if <hdL> or <hdR> is trivial, return the trivial polynomial */
if ( l == 0 || r == 0 ) {
hdP = NewBag( T_LIST, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdP, 0 );
return hdP;
}
/* create a bag for the result */
hdP = NewBag( T_VECFFE, SIZE_PLEN_VECFFE(l+r-1) );
/* fold the product */
TabMultiplyCoeffs[T_VECFFE][T_VECFFE]( hdP, hdL, l, hdR, r );
SET_FLD_VECFFE( hdP, FLD_VECFFE(hdL) );
/* and return the result */
return hdP;
}
/****************************************************************************
**
*F FunProductCoeffsMod( <hdCall> ) . . internal function 'ProductCoeffsMod'
**
** 'FunProductCoeffsMod' implements 'ProductCoeffsMod( <l>, <r>, <p> )'
*/
TypHandle (*TabProductCoeffsMod[T_VAR][T_VAR]) P((
TypHandle, TypHandle, TypHandle ));
TypHandle FunProductCoeffsMod ( hdCall )
TypHandle hdCall;
{
TypHandle hdL;
TypHandle hdR;
TypHandle hdN;
/* check arguments */
if ( SIZE(hdCall) != 4 * SIZE_HD )
return Error( "usage: ProductCoeffsMod( <l>, <r>, <p> )", 0L, 0L );
hdL = EVAL( PTR(hdCall)[1] );
hdR = EVAL( PTR(hdCall)[2] );
hdN = EVAL( PTR(hdCall)[3] );
/* jump through the table */
return TabProductCoeffsMod[XType(hdL)][XType(hdR)]( hdL, hdR, hdN );
}
TypHandle CantProductCoeffsMod ( hdL, hdR, hdN )
TypHandle hdL;
TypHandle hdR;
TypHandle hdN;
{
return Error("<l> and <r> must be vectors over a common field", 0L, 0L);
}
TypHandle ProductCoeffsModListxListx ( hdL, hdR, hdN )
TypHandle hdL;
TypHandle hdR;
TypHandle hdN;
{
TypHandle hdP; /* result */
TypHandle hdLL; /* one element of <hdL> */
TypHandle hdRR; /* one element of <hdR> */
TypHandle hdPP; /* one element of <hdP> */
TypHandle hdTT; /* temp element */
TypHandle hdQ; /* <hdP> / 2 */
long i, u, k; /* loop variables */
long l; /* length of <hdL> */
long r; /* length of <hdR> */
/* get the length of <hdL> and hd <hdR> */
l = LEN_LIST(hdL);
r = LEN_LIST(hdR);
/* if <hdL> or <hdR> is trivial, return the trivial polynomial */
if ( l == 0 || r == 0 || hdN == INT_TO_HD(0) ) {
hdP = NewBag( T_LIST, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdP, 0 );
return hdP;
}
/* create a bag for the result */
hdP = NewBag( T_LIST, SIZE_PLEN_PLIST(l+r-1) );
SET_LEN_PLIST( hdP, l+r-1 );
/* if <hdP> is negative reduce into <hdP>/2 and <hdP> */
if ( LT( hdN, INT_TO_HD(0) ) == HdTrue )
{
hdN = DIFF( INT_TO_HD(0), hdN );
hdQ = SUM( hdN, INT_TO_HD(1) );
hdQ = QuoInt( hdQ, INT_TO_HD(2) );
hdQ = DIFF( hdQ, INT_TO_HD(1) );
}
else
hdQ = 0;
/* fold the product */
for ( i = l+r; 1 < i; i-- )
{
hdPP = INT_TO_HD(0);
u = ( i-1 < l ) ? i-1 : l;
for ( k = ( i-r < 1 ) ? 1 : i-r; k <= u; k++ )
{
hdLL = ELML_LIST( hdL, k );
hdRR = ELMR_LIST( hdR, i-k );
hdTT = PROD( hdLL, hdRR );
hdPP = SUM( hdPP, hdTT );
}
hdPP = MOD( hdPP, hdN );
if ( hdQ != 0 && LT( hdQ, hdPP ) == HdTrue )
hdPP = DIFF( hdPP, hdN );
SET_ELM_PLIST( hdP, i-1, hdPP );
}
/* and return the result */
return hdP;
}
/****************************************************************************
**
*F REDUCE_COEFFS( <hdL>, <l>, <hdR>, <r> ) . . . . . . reduce <hdL> by <hdR>
**
#define REDUCE_COEFFS( hdL, l, hdR, r ) \
(TabReduceCoeffs[XType(hdL)][XType(hdR)]( hdL, l, hdR, r ))
*/
long (*TabReduceCoeffs[T_VAR][T_VAR]) P((
TypHandle, long, TypHandle, long ));
long CantReduceCoeffs ( hdL, l, hdR, r )
TypHandle hdL; /* left polynomial coeffs */
long l; /* degree plus one of left polynomial */
TypHandle hdR; /* right polynomial coeffs */
long r; /* degree plus one of right polynomial */
{
Error( "<l> and <r> must be vectors over a common field", 0L, 0L);
return 0;
}
long ReduceCoeffsListxListx ( hdL, l, hdR, r )
TypHandle hdL; /* left polynomial coeffs */
long l; /* degree plus one of left polynomial */
TypHandle hdR; /* right polynomial coeffs */
long r; /* degree plus one of right polynomial */
{
TypHandle hdLL; /* one element of <hdL> */
TypHandle hdRR; /* one element of <hdR> */
TypHandle hdCC; /* temp element */
TypHandle hdTT; /* temp element */
long i, k; /* loop variables */
/* <r> must be none zero */
if ( r == 0 ) {
Error( "<r> must be non zero", 0L, 0L );
return 0;
}
hdCC = PROD( ELML_LIST( hdR, 1 ), INT_TO_HD(0) );
for ( ; 0 < r; r-- ) {
hdTT = ELMR_LIST( hdR, r );
if ( EQ( hdCC, hdTT ) == HdFalse )
break;
}
if ( r == 0 ) {
Error( "<r> must be non zero", 0L, 0L );
return 0;
}
/* if <l> is trivial return */
if ( l == 0 )
return 0;
/* compute the remainder */
for ( i = l-r; 0 <= i; i-- )
{
hdLL = ELMR_LIST( hdL, i+r );
if ( hdLL != INT_TO_HD(0) ) {
hdRR = ELML_LIST( hdR, r );
hdCC = QUO( hdLL, hdRR );
for ( k = r; 0 < k; k-- )
{
hdRR = ELML_LIST( hdR, k );
hdTT = PROD( hdCC, hdRR );
hdLL = ELMR_LIST( hdL, i+k );
hdLL = DIFF( hdLL, hdTT );
ASS_LIST( hdL, i+k, hdLL );
}
}
}
return ( l < r ) ? l : r-1;
}
long ReduceCoeffsVecFFEVecFFE ( hdL, l, hdR, r )
TypHandle hdL; /* left polynomial coeffs */
long l; /* degree plus one of left polynomial */
TypHandle hdR; /* right polynomial coeffs */
long r; /* degree plus one of right polynomial */
{
TypFFE * ptL; /* coeffs vectors of left polynomial */
TypFFE * ptLL; /* coeffs vectors of left polynomial */
TypFFE * ptR; /* coeffs vectors of right polynomial */
TypFFE * ptRR; /* coeffs vectors of right polynomial */
TypFFE * f; /* the finite field */
TypFFE o; /* size of <f> minus one */
TypFFE c,q,t; /* temps for FFEs */
register long i,k; /* loop variables */
/* <r> must be none zero */
ptR = (TypFFE*)( PTR(hdR) + 1 ) + (r-1);
while ( 0 < r && *ptR == 0 ) {
r--; ptR--;
}
if ( r == 0 )
Error( "<r> must be non zero", 0L, 0L );
/* if <l> is trivial return */
if ( l == 0 )
return 0;
/* get a common field */
f = (TypFFE*) PTR( UnifiedFieldVecFFE( hdL, hdR ) );
o = *f;
/* set up all the pointers */
ptL = (TypFFE*)( PTR(hdL) + 1 );
ptR = (TypFFE*)( PTR(hdR) + 1 ) + (r-1);
/* get the leading coefficient of <hdR> * -1, <c> is never zero */
c = ( o%2 == 1 ? (*ptR) : ( (*ptR) <= o/2 ? (*ptR)+o/2 : (*ptR)-o/2 ) );
/* compute the remainder */
for ( i = l-r; 0 <= i; i-- ) {
/* if <ptLL> already ends with a zero, continue */
ptLL = ptL + (i-1+r);
if ( *ptLL == 0 )
continue;
/* compute quotient of leading coefficients */
q = ( c <= (*ptLL) ? (*ptLL)-c+1 : o-c+1+(*ptLL) );
/* reduce <ptLL> by <q> * <ptRR> */
for ( k = r, ptRR = ptR; 0 < k; k--, ptLL--, ptRR-- ) {
if ( *ptRR == 0 )
continue;
t = ( q-1 <= o-(*ptRR) ) ? q-1+(*ptRR) : q-1-(o-(*ptRR));
if ( *ptLL == 0 )
*ptLL = t;
else if ( *ptLL <= t )
*ptLL = PROD_FF( *ptLL, f[t-(*ptLL)+1], f );
else
*ptLL = PROD_FF( t, f[(*ptLL)-t+1], f );
}
}
return ( l < r ) ? l : r-1;
}
/****************************************************************************
**
*F FunReduceCoeffs( <hdCall> ) . . . . . . internal function 'ReduceCoeffs'
**
** 'FunReduceCoeffs' implements 'ReduceCoeffs( <l>, <r> )'
*/
TypHandle FunReduceCoeffs ( hdCall )
TypHandle hdCall;
{
TypHandle hdL;
long l;
TypHandle hdR;
long r;
/* check arguments */
if ( SIZE( hdCall ) != 3 * SIZE_HD )
return Error( "usage: ReduceCoeffs( <l>, <r> )", 0L, 0L );
hdL = EVAL( PTR(hdCall)[1] );
hdR = EVAL( PTR(hdCall)[2] );
l = LEN_LIST(hdL);
r = LEN_LIST(hdR);
/* jump through the table */
TabReduceCoeffs[XType(hdL)][XType(hdR)]( hdL, l, hdR, r );
return HdVoid;
}
/****************************************************************************
**
*F FunRemainderCoeffs( <hdCall> ) . . . internal function 'RemainderCoeffs'
**
** 'FunRemainderCoeffs' implements 'RemainderCoeffs( <l>, <r> )'
*/
TypHandle FunRemainderCoeffs ( hdCall )
TypHandle hdCall;
{
TypHandle hdL;
long l;
TypHandle hdR;
long r;
/* check arguments */
if ( SIZE( hdCall ) != 3 * SIZE_HD )
return Error( "usage: ReduceCoeffs( <l>, <r> )", 0L, 0L );
hdL = EVAL( PTR(hdCall)[1] );
hdR = EVAL( PTR(hdCall)[2] );
l = LEN_LIST(hdL);
r = LEN_LIST(hdR);
/* jump through the table */
hdL = Copy(hdL);
TabReduceCoeffs[XType(hdL)][XType(hdR)]( hdL, l, hdR, r );
return hdL;
}
/****************************************************************************
**
*F REDUCE_COEFFS_MOD( <hdL>, <l>, <hdR>, <r>, <hdN> ) reduce <hdL> by <hdR>
**
#define REDUCE_COEFFS_MOD( hdL, l, hdR, r ) \
(TabReduceCoeffsMod[XType(hdL)][XType(hdR)]( hdL, l, hdR, r, hdN ))
*/
long (*TabReduceCoeffsMod[T_VAR][T_VAR]) P((
TypHandle, long, TypHandle, long, TypHandle ));
long CantReduceCoeffsMod ( hdL, l, hdR, r, hdP )
TypHandle hdL; /* left polynomial coeffs */
long l; /* degree plus one of left polynomial */
TypHandle hdR; /* right polynomial coeffs */
long r; /* degree plus one of right polynomial */
TypHandle hdP; /* modulo */
{
Error( "<l> and <r> must be vectors over a common field", 0L, 0L);
return 0;
}
long ReduceCoeffsModListxListx ( hdL, l, hdR, r, hdP )
TypHandle hdL; /* left polynomial coeffs */
long l; /* degree plus one of left polynomial */
TypHandle hdR; /* right polynomial coeffs */
long r; /* degree plus one of right polynomial */
TypHandle hdP; /* modulo */
{
TypHandle hdLL; /* one element of <hdL> */
TypHandle hdRR; /* one element of <hdR> */
TypHandle hdCC; /* temp element */
TypHandle hdTT; /* temp element */
TypHandle hdQ; /* <hdP> / 2 */
long i, k; /* loop variables */
/* <r> must be none zero */
if ( r == 0 ) {
Error( "<r> must be non zero", 0L, 0L );
return 0;
}
hdCC = PROD( ELML_LIST( hdR, 1 ), INT_TO_HD(0) );
for ( ; 0 < r; r-- ) {
hdTT = ELMR_LIST( hdR, r );
if ( EQ( hdCC, hdTT ) == HdFalse )
break;
}
if ( r == 0 ) {
Error( "<r> must be non zero", 0L, 0L );
return 0;
}
/* catch the trivial cases (<l> or <hdP> equal zero) */
if ( l == 0 )
return 0;
if ( EQ( hdP, INT_TO_HD(0) ) == HdTrue ) {
for ( i = l; 0 < i; i-- )
ASS_LIST( hdL, i, INT_TO_HD(0) );
return 0;
}
/* if <hdP> is negative reduce into <hdP>/2 and <hdP> */
if ( LT( hdP, INT_TO_HD(0) ) == HdTrue ) {
hdP = DIFF( INT_TO_HD(0), hdP );
hdQ = SUM( hdP, INT_TO_HD(1) );
hdQ = QuoInt( hdQ, INT_TO_HD(2) );
hdQ = DIFF( hdQ, INT_TO_HD(1) );
}
else
hdQ = 0;
/* if <r> is zero or too big reduce modulo <hP> */
if ( l < r ) {
for ( i = l; 0 < i; i-- ) {
hdTT = MOD( ELMF_LIST(hdL,i), hdP );
if ( hdQ != 0 && LT( hdQ, hdTT ) == HdTrue )
hdTT = DIFF( hdTT, hdP );
ASS_LIST( hdL, i, hdTT );
}
r = l+1;
}
/* otherwise, compute the remainder */
else
for ( i = l-r; 0 <= i; i-- ) {
hdLL = ELM_LIST( hdL, i+r );
if ( hdLL != INT_TO_HD(0) ) {
hdRR = ELM_LIST( hdR, r );
hdCC = QUO( hdLL, hdRR );
hdCC = MOD( hdCC, hdP );
for ( k = r; 0 < k; k-- ) {
hdRR = ELM_LIST( hdR, k );
hdTT = PROD( hdCC, hdRR );
hdLL = ELM_LIST( hdL, i+k );
hdLL = DIFF( hdLL, hdTT );
hdLL = MOD( hdLL, hdP );
if ( hdQ != 0 && LT( hdQ, hdLL ) == HdTrue )
hdLL = DIFF( hdLL, hdP );
SET_ELM_PLIST( hdL, i+k, hdLL );
}
}
}
/* and return the new length */
return r-1;
}
long ReduceCoeffsModListx ( hdL, l, hdR, r, hdP )
TypHandle hdL; /* left polynomial coeffs */
long l; /* degree plus one of left polynomial */
TypHandle hdR; /* void */
long r; /* zero */
TypHandle hdP; /* modulo */
{
TypHandle hdTT; /* temp element */
TypHandle hdQ; /* <hdP> / 2 */
long i; /* loop variables */
/* catch the trivial cases (<l> or <hdP> equal zero) */
if ( l == 0 )
return 0;
if ( EQ( hdP, INT_TO_HD(0) ) == HdTrue ) {
for ( i = l; 0 < i; i-- )
ASS_LIST( hdL, i, INT_TO_HD(0) );
return 0;
}
/* if <hdP> is negative reduce into <hdP>/2 and <hdP> */
if ( LT( hdP, INT_TO_HD(0) ) == HdTrue ) {
hdP = DIFF( INT_TO_HD(0), hdP );
hdQ = SUM( hdP, INT_TO_HD(1) );
hdQ = QuoInt( hdQ, INT_TO_HD(2) );
hdQ = DIFF( hdQ, INT_TO_HD(1) );
}
else
hdQ = 0;
/* reduce modulo <hP> */
for ( i = l; 0 < i; i-- ) {
hdTT = MOD( ELMF_LIST(hdL,i), hdP );
if ( hdQ != 0 && LT( hdQ, hdTT ) == HdTrue )
hdTT = DIFF( hdTT, hdP );
ASS_LIST( hdL, i, hdTT );
}
return l;
}
/****************************************************************************
**
*F FunReduceCoeffsMod( <hdCall> ) . . . internal function 'ReduceCoeffsMod'
**
** 'FunReduceCoeffsMod' implements 'ReduceCoeffsMod( <l>, <r>, <p> )'
*/
TypHandle FunReduceCoeffsMod ( hdCall )
TypHandle hdCall;
{
TypHandle hdL;
long l;
TypHandle hdR;
long r;
TypHandle hdN;
/* check arguments */
if ( 4*SIZE_HD < SIZE(hdCall) || SIZE(hdCall) < 3*SIZE_HD )
return Error( "usage: ReduceCoeffsMod( <l>, <r>, <p> )", 0L, 0L );
hdL = EVAL( PTR(hdCall)[1] );
l = LEN_LIST(hdL);
if ( SIZE(hdCall) == 4*SIZE_HD ) {
hdR = EVAL( PTR(hdCall)[2] );
r = LEN_LIST(hdR);
hdN = EVAL( PTR(hdCall)[3] );
}
else {
hdR = HdVoid;
r = 0;
hdN = EVAL( PTR(hdCall)[2] );
}
/* jump through the table */
TabReduceCoeffsMod[XType(hdL)][XType(hdR)]( hdL, l, hdR, r, hdN );
return HdVoid;
}
/****************************************************************************
**
*F FunPowerModCoeffs( <hdCall> ) . . . . internal function 'PowerModCoeffs'
**
** 'FunPowerModCoeffs' implements 'PowerModCoeffs( <g>, <n>, <r> )'
*/
TypHandle (*TabPowerModCoeffsInt[T_VAR][T_VAR]) P((
TypHandle, TypHandle, TypHandle ));
TypHandle (*TabPowerModCoeffsLInt[T_VAR][T_VAR]) P((
TypHandle, TypHandle, TypHandle ));
TypHandle FunPowerModCoeffs ( hdCall )
TypHandle hdCall;
{
TypHandle hdG;
TypHandle hdE;
TypHandle hdR;
/* check arguments */
if ( SIZE( hdCall ) != 4 * SIZE_HD )
return Error( "usage: PowerModCoeffs( <g>, <exp>, <r> )", 0L, 0L );
hdG = EVAL( PTR(hdCall)[1] );
hdE = EVAL( PTR(hdCall)[2] );
hdR = EVAL( PTR(hdCall)[3] );
if ( TYPE(hdE)!=T_INTPOS && ( TYPE(hdE)!=T_INT || HD_TO_INT(hdE)<1 ) )
return Error( "<exp> must be a positive integer", 0L, 0L );
/* jump through the table */
if ( TYPE(hdE) == T_INT )
return TabPowerModCoeffsInt [XType(hdG)][XType(hdR)](hdG, hdE, hdR);
else
return TabPowerModCoeffsLInt[XType(hdG)][XType(hdR)](hdG, hdE, hdR);
}
TypHandle PowerModListxIntListx ( hdG, hdE, hdR )
TypHandle hdG; /* polynomial coeffs */
TypHandle hdE; /* exponent */
TypHandle hdR; /* modulus */
{
TypHandle hdP; /* result */
TypHandle hdR1; /* temporary storage for multiplication */
TypHandle hdR2; /* temporary storage for multiplication */
long g; /* length of <hdG> */
long r; /* length of <hdR> */
long p; /* length of <hdP> */
unsigned long exp; /* value of <hdE> */
unsigned long i; /* loop variable */
/* <hdR> must be none zero */
r = LEN_LIST(hdR);
if ( r == 0 ) {
Error( "<r> must be non zero", 0L, 0L );
return 0;
}
hdR1 = PROD( ELML_LIST( hdR, 1 ), INT_TO_HD(0) );
for ( ; 0 < r; r-- ) {
hdR2 = ELMR_LIST( hdR, r );
if ( EQ( hdR1, hdR2 ) == HdFalse )
break;
}
if ( r == 0 ) {
Error( "<r> must be non zero", 0L, 0L );
return 0;
}
/* copy <hdG> and reduce it modulo <hdR> */
hdG = Copy(hdG);
g = REDUCE_COEFFS( hdG, LEN_LIST(hdG), hdR, r );
/* if <hdG> is already trivial, return */
for ( ; 0 < g; g-- ) {
hdR2 = ELMR_LIST( hdG, g );
if ( EQ( hdR1, hdR2 ) == HdFalse )
break;
}
if ( g == 0 ) {
hdG = NewBag( T_LIST, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdG, 0 );
return hdG;
}
/* allocate storage for multiplication */
hdR1 = Copy(hdG);
hdR2 = NewBag( T_LIST, SIZE_PLEN_PLIST(2*r) );
/* we need at most two times the <r> */
PLAIN_LIST(hdG);
PLAIN_LIST(hdR1);
Resize( hdR1, SIZE_PLEN_PLIST(2*r) );
SET_LEN_PLIST( hdR1, 2*r );
/* compute the power using left to right repeated squaring */
i = 1 << 31;
p = 0;
hdP = 0;
exp = HD_TO_INT(hdE);
while ( 1 < i ) {
if ( hdP ) {
/* use table directly in order to avoid changing the types */
p = TabMultiplyCoeffs[T_LISTX][T_LISTX]( hdR2, hdP, p, hdP, p );
p = TabReduceCoeffs[T_LISTX][T_LISTX]( hdR2, p, hdR, r );
hdR1 = hdP; hdP = hdR2; hdR2 = hdR1;
}
i = i / 2;
if ( i <= exp ) {
if ( hdP ) {
/* use table directly in order to avoid changing the types */
p = TabMultiplyCoeffs[T_LISTX][T_LISTX](hdR2,hdP,p,hdG,g);
p = TabReduceCoeffs[T_LISTX][T_LISTX](hdR2,p,hdR,r);
hdR1 = hdP; hdP = hdR2; hdR2 = hdR1;
}
else {
hdP = hdR1;
p = g;
}
exp = exp - i;
}
}
/* resize result and return */
SET_LEN_PLIST( hdP, p );
return hdP;
}
TypHandle PowerModVecFFEIntVecFFE ( hdG, hdE, hdR )
TypHandle hdG; /* polynomial coeffs */
TypHandle hdE; /* exponent */
TypHandle hdR; /* modulus */
{
TypHandle hdP; /* result */
TypHandle hdR1; /* temporary storage for multiplication */
TypHandle hdR2; /* temporary storage for multiplication */
long g; /* length of <hdG> */
long r; /* length of <hdR> */
long p; /* length of <hdP> */
unsigned long exp; /* value of <hdE> */
unsigned long i; /* loop variable */
/* <hdR> must be none zero */
r = LEN_VECFFE(hdR);
if ( r == 0 ) {
Error( "<r> must be non zero", 0L, 0L );
return 0;
}
for ( ; 0 < r; r-- ) {
if ( VAL_VECFFE( hdR, r ) != 0 )
break;
}
if ( r == 0 ) {
Error( "<r> must be non zero", 0L, 0L );
return 0;
}
/* copy <hdG> and reduce it modulo <hdR> */
hdG = Copy(hdG);
g = REDUCE_COEFFS( hdG, LEN_LIST(hdG), hdR, r );
/* if <hdG> is already trivial, return */
for ( ; 0 < g; g-- ) {
if ( VAL_VECFFE( hdG, g ) != 0 )
break;
}
if ( g == 0 ) {
hdG = NewBag( T_LIST, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdG, 0 );
return hdG;
}
/* allocate storage for multiplication */
hdR1 = Copy(hdG);
hdR2 = NewBag( T_VECFFE, SIZE_PLEN_VECFFE(2*r) );
SET_FLD_VECFFE( hdR2, FLD_VECFFE(hdR1) );
/* we need at most two times the <r> */
Resize( hdR1, SIZE_PLEN_VECFFE(2*r) );
/* compute the power using left to right repeated squaring */
i = 1 << 31;
p = 0;
hdP = 0;
exp = HD_TO_INT(hdE);
while ( 1 < i ) {
if ( hdP ) {
/* use table directly in order to avoid changing the types */
p = TabMultiplyCoeffs[T_VECFFE][T_VECFFE](hdR2,hdP,p,hdP,p);
p = TabReduceCoeffs[T_VECFFE][T_VECFFE]( hdR2, p, hdR, r );
hdR1 = hdP; hdP = hdR2; hdR2 = hdR1;
}
i = i / 2;
if ( i <= exp ) {
if ( hdP ) {
/* use table directly in order to avoid changing the types */
p = TabMultiplyCoeffs[T_VECFFE][T_VECFFE](hdR2,hdP,p,hdG,g);
p = TabReduceCoeffs[T_VECFFE][T_VECFFE](hdR2,p,hdR,r);
hdR1 = hdP; hdP = hdR2; hdR2 = hdR1;
}
else {
hdP = hdR1;
p = g;
}
exp = exp - i;
}
}
/* resize result and return */
SET_LEN_VECFFE( hdP, p );
return hdP;
}
TypHandle PowerModListxLIntListx ( hdG, hdE, hdR )
TypHandle hdG; /* polynomial coeffs */
TypHandle hdE; /* exponent */
TypHandle hdR; /* modulus polynomial coeffs */
{
TypHandle hdP; /* result */
TypHandle hdR1; /* temporary storage for multiplication */
TypHandle hdR2; /* temporary storage for multiplication */
TypDigit e; /* one digit of <hdE> */
long g; /* length of <hdG> */
long r; /* length of <hdR> */
long p; /* length of <hdP> */
unsigned long i; /* loop variable */
long l; /* loop variable */
/* <hdR> must be none zero */
r = LEN_LIST(hdR);
if ( r == 0 ) {
Error( "<r> must be non zero", 0L, 0L );
return 0;
}
hdR1 = PROD( ELML_LIST( hdR, 1 ), INT_TO_HD(0) );
for ( ; 0 < r; r-- ) {
hdR2 = ELMR_LIST( hdR, r );
if ( EQ( hdR1, hdR2 ) == HdFalse )
break;
}
if ( r == 0 ) {
Error( "<r> must be non zero", 0L, 0L );
return 0;
}
/* copy <hdG> and reduce it modulo <hdR> */
hdG = Copy(hdG);
g = REDUCE_COEFFS( hdG, LEN_LIST(hdG), hdR, r );
/* if <hdG> is already trivial, return */
for ( ; 0 < g; g-- ) {
hdR2 = ELMR_LIST( hdG, g );
if ( EQ( hdR1, hdR2 ) == HdFalse )
break;
}
if ( g == 0 ) {
hdG = NewBag( T_LIST, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdG, 0 );
return hdG;
}
/* allocate storage for multiplication */
hdR1 = Copy(hdG);
hdR2 = NewBag( T_LIST, SIZE_PLEN_PLIST(2*r) );
/* we need at most two times the <r> */
PLAIN_LIST(hdR1);
PLAIN_LIST(hdG);
Resize( hdR1, SIZE_PLEN_PLIST(2*r) );
SET_LEN_PLIST( hdR1, 2*r );
/* compute the power using left to right repeated squaring */
hdP = 0;
p = 0;
for ( l = SIZE(hdE)/sizeof(TypDigit)-1; 0 <= l; l-- ) {
i = 1 << (8*sizeof(TypDigit));
e = ((TypDigit*) PTR(hdE))[l];
while ( 1 < i ) {
if ( hdP ) {
/* use table directly in order to avoid changing the types */
p = TabMultiplyCoeffs[T_LISTX][T_LISTX](hdR2,hdP,p,hdP,p);
p = TabReduceCoeffs[T_LISTX][T_LISTX]( hdR2, p, hdR, r );
hdR1 = hdP; hdP = hdR2; hdR2 = hdR1;
}
i = i / 2;
if ( i <= e ) {
if ( hdP ) {
/* use table directly */
p = TabMultiplyCoeffs[T_LISTX][T_LISTX](hdR2,hdP,p,hdG,g);
p = TabReduceCoeffs[T_LISTX][T_LISTX]( hdR2, p, hdR, r );
hdR1 = hdP; hdP = hdR2; hdR2 = hdR1;
}
else {
hdP = hdR1;
p = g;
}
e = e - i;
}
}
}
/* resize result and return */
SET_LEN_PLIST( hdP, p );
return hdP;
}
TypHandle PowerModVecFFELIntVecFFE ( hdG, hdE, hdR )
TypHandle hdG; /* polynomial coeffs */
TypHandle hdE; /* exponent */
TypHandle hdR; /* modulus */
{
TypHandle hdP; /* result */
TypHandle hdR1; /* temporary storage for multiplication */
TypHandle hdR2; /* temporary storage for multiplication */
TypDigit e; /* one digit of <hdE> */
long g; /* length of <hdG> */
long r; /* length of <hdR> */
long p; /* length of <hdP> */
unsigned long i; /* loop variable */
long l; /* loop variable */
/* <hdR> must be none zero */
r = LEN_VECFFE(hdR);
if ( r == 0 ) {
Error( "<r> must be non zero", 0L, 0L );
return 0;
}
for ( ; 0 < r; r-- ) {
if ( VAL_VECFFE( hdR, r ) != 0 )
break;
}
if ( r == 0 ) {
Error( "<r> must be non zero", 0L, 0L );
return 0;
}
/* copy <hdG> and reduce it modulo <hdR> */
hdG = Copy(hdG);
g = REDUCE_COEFFS( hdG, LEN_LIST(hdG), hdR, r );
/* if <hdG> is already trivial, return */
for ( ; 0 < g; g-- ) {
if ( VAL_VECFFE( hdG, g ) != 0 )
break;
}
if ( g == 0 ) {
hdG = NewBag( T_LIST, SIZE_PLEN_PLIST(0) );
SET_LEN_PLIST( hdG, 0 );
return hdG;
}
/* allocate storage for multiplication */
hdR1 = Copy(hdG);
hdR2 = NewBag( T_VECFFE, SIZE_PLEN_VECFFE(2*r) );
SET_FLD_VECFFE( hdR2, FLD_VECFFE(hdR1) );
/* we need at most two times the <r> */
Resize( hdR1, SIZE_PLEN_VECFFE(2*r) );
/* compute the power using left to right repeated squaring */
hdP = 0;
p = 0;
for ( l = SIZE(hdE)/sizeof(TypDigit)-1; 0 <= l; l-- ) {
i = 1 << (8*sizeof(TypDigit));
e = ((TypDigit*) PTR(hdE))[l];
while ( 1 < i ) {
if ( hdP ) {
/* use table directly in order to avoid changing the types */
p = TabMultiplyCoeffs[T_VECFFE][T_VECFFE](hdR2,hdP,p,hdP,p);
p = TabReduceCoeffs[T_VECFFE][T_VECFFE]( hdR2, p, hdR, r );
hdR1 = hdP; hdP = hdR2; hdR2 = hdR1;
}
i = i / 2;
if ( i <= e ) {
if ( hdP ) {
/* use table directly */
p = TabMultiplyCoeffs[T_VECFFE][T_VECFFE](hdR2,hdP,p,hdG,g);
p = TabReduceCoeffs[T_VECFFE][T_VECFFE]( hdR2, p, hdR, r );
hdR1 = hdP; hdP = hdR2; hdR2 = hdR1;
}
else {
hdP = hdR1;
p = g;
}
e = e - i;
}
}
}
/* resize result and return */
SET_LEN_VECFFE( hdP, p );
return hdP;
}
TypHandle CantPowerModCoeffs ( hdG, hdE, hdR )
TypHandle hdG; /* polynomial coeffs */
TypHandle hdE; /* exponent */
TypHandle hdR; /* modulus polynomial coeffs */
{
Error( "<g> and <r> must be vectors over a common field", 0L, 0L);
return 0;
}
/****************************************************************************
**
*F InitPolynom() . . . . . . . . . . . . . . initialize the polynom package
*/
void InitPolynom ()
{
long type1, type2; /* loop variables */
/* install tables for gap functions */
for ( type1 = T_VOID; type1 < T_VAR; type1++ ) {
TabNormalizeCoeffs[type1] = CantNormalizeCoeffs;
TabShrinkCoeffs [type1] = CantShrinkCoeffs;
TabShiftedCoeffs [type1] = CantShiftedCoeffs;
for ( type2 = T_VOID; type2 < T_VAR; type2++ ) {
TabAddCoeffs [type1][type2] = CantAddCoeffs;
TabMultiplyCoeffs [type1][type2] = CantMultiplyCoeffs;
TabProductCoeffs [type1][type2] = CantProductCoeffs;
TabProductCoeffsMod [type1][type2] = CantProductCoeffsMod;
TabReduceCoeffs [type1][type2] = CantReduceCoeffs;
TabReduceCoeffsMod [type1][type2] = CantReduceCoeffsMod;
TabPowerModCoeffsInt [type1][type2] = CantPowerModCoeffs;
TabPowerModCoeffsLInt[type1][type2] = CantPowerModCoeffs;
}
}
TabNormalizeCoeffs[T_LISTX ] = NormalizeCoeffsListx;
TabNormalizeCoeffs[T_VECTOR] = NormalizeCoeffsListx;
TabNormalizeCoeffs[T_VECFFE] = NormalizeCoeffsVecFFE;
TabShrinkCoeffs[T_LISTX ] = ShrinkCoeffsListx;
TabShrinkCoeffs[T_VECTOR] = ShrinkCoeffsListx;
TabShrinkCoeffs[T_VECFFE] = ShrinkCoeffsVecFFE;
TabShiftedCoeffs [T_LISTX ] = ShiftedCoeffsListx;
TabShiftedCoeffs [T_VECTOR] = ShiftedCoeffsListx;
TabShiftedCoeffs [T_VECFFE] = ShiftedCoeffsVecFFE;
TabAddCoeffs[T_LISTX ][T_LISTX ] = AddCoeffsListxListx;
TabAddCoeffs[T_LISTX ][T_VECTOR] = AddCoeffsListxListx;
TabAddCoeffs[T_LISTX ][T_VECFFE] = AddCoeffsListxVecFFE;
TabAddCoeffs[T_VECTOR][T_LISTX ] = AddCoeffsListxListx;
TabAddCoeffs[T_VECTOR][T_VECTOR] = AddCoeffsListxListx;
TabAddCoeffs[T_VECTOR][T_VECFFE] = AddCoeffsListxListx;
TabAddCoeffs[T_VECFFE][T_LISTX ] = AddCoeffsListxListx;
TabAddCoeffs[T_VECFFE][T_VECTOR] = AddCoeffsListxListx;
TabAddCoeffs[T_VECFFE][T_VECFFE] = AddCoeffsVecFFEVecFFE;
TabMultiplyCoeffs[T_LISTX ][T_LISTX ] = MultiplyCoeffsListxListx;
TabMultiplyCoeffs[T_LISTX ][T_VECTOR] = MultiplyCoeffsListxListx;
TabMultiplyCoeffs[T_LISTX ][T_VECFFE] = MultiplyCoeffsListxListx;
TabMultiplyCoeffs[T_VECTOR][T_LISTX ] = MultiplyCoeffsListxListx;
TabMultiplyCoeffs[T_VECTOR][T_VECTOR] = MultiplyCoeffsListxListx;
TabMultiplyCoeffs[T_VECTOR][T_VECFFE] = MultiplyCoeffsListxListx;
TabMultiplyCoeffs[T_VECFFE][T_LISTX ] = MultiplyCoeffsListxListx;
TabMultiplyCoeffs[T_VECFFE][T_VECTOR] = MultiplyCoeffsListxListx;
TabMultiplyCoeffs[T_VECFFE][T_VECFFE] = MultiplyCoeffsVecFFEVecFFE;
TabProductCoeffs[T_LISTX ][T_LISTX ] = ProductCoeffsListxListx;
TabProductCoeffs[T_LISTX ][T_VECTOR] = ProductCoeffsListxListx;
TabProductCoeffs[T_LISTX ][T_VECFFE] = ProductCoeffsListxListx;
TabProductCoeffs[T_VECTOR][T_LISTX ] = ProductCoeffsListxListx;
TabProductCoeffs[T_VECTOR][T_VECTOR] = ProductCoeffsListxListx;
TabProductCoeffs[T_VECTOR][T_VECFFE] = ProductCoeffsListxListx;
TabProductCoeffs[T_VECFFE][T_LISTX ] = ProductCoeffsListxListx;
TabProductCoeffs[T_VECFFE][T_VECTOR] = ProductCoeffsListxListx;
TabProductCoeffs[T_VECFFE][T_VECFFE] = ProductCoeffsVecFFEVecFFE;
TabProductCoeffsMod[T_LISTX ][T_LISTX ] = ProductCoeffsModListxListx;
TabProductCoeffsMod[T_LISTX ][T_VECTOR] = ProductCoeffsModListxListx;
TabProductCoeffsMod[T_LISTX ][T_VECFFE] = ProductCoeffsModListxListx;
TabProductCoeffsMod[T_VECTOR][T_LISTX ] = ProductCoeffsModListxListx;
TabProductCoeffsMod[T_VECTOR][T_VECTOR] = ProductCoeffsModListxListx;
TabProductCoeffsMod[T_VECTOR][T_VECFFE] = ProductCoeffsModListxListx;
TabProductCoeffsMod[T_VECFFE][T_LISTX ] = ProductCoeffsModListxListx;
TabProductCoeffsMod[T_VECFFE][T_VECTOR] = ProductCoeffsModListxListx;
TabProductCoeffsMod[T_VECFFE][T_VECFFE] = ProductCoeffsModListxListx;
TabReduceCoeffs[T_LISTX ][T_LISTX ] = ReduceCoeffsListxListx;
TabReduceCoeffs[T_LISTX ][T_VECTOR] = ReduceCoeffsListxListx;
TabReduceCoeffs[T_LISTX ][T_VECFFE] = ReduceCoeffsListxListx;
TabReduceCoeffs[T_VECTOR][T_LISTX ] = ReduceCoeffsListxListx;
TabReduceCoeffs[T_VECTOR][T_VECTOR] = ReduceCoeffsListxListx;
TabReduceCoeffs[T_VECTOR][T_VECFFE] = ReduceCoeffsListxListx;
TabReduceCoeffs[T_VECFFE][T_LISTX ] = ReduceCoeffsListxListx;
TabReduceCoeffs[T_VECFFE][T_VECTOR] = ReduceCoeffsListxListx;
TabReduceCoeffs[T_VECFFE][T_VECFFE] = ReduceCoeffsVecFFEVecFFE;
TabReduceCoeffsMod[T_LISTX ][T_LISTX ] = ReduceCoeffsModListxListx;
TabReduceCoeffsMod[T_LISTX ][T_VECTOR] = ReduceCoeffsModListxListx;
TabReduceCoeffsMod[T_LISTX ][T_VECFFE] = ReduceCoeffsModListxListx;
TabReduceCoeffsMod[T_LISTX ][T_VOID ] = ReduceCoeffsModListx;
TabReduceCoeffsMod[T_VECTOR][T_LISTX ] = ReduceCoeffsModListxListx;
TabReduceCoeffsMod[T_VECTOR][T_VECTOR] = ReduceCoeffsModListxListx;
TabReduceCoeffsMod[T_VECTOR][T_VECFFE] = ReduceCoeffsModListxListx;
TabReduceCoeffsMod[T_VECTOR][T_VOID ] = ReduceCoeffsModListx;
TabReduceCoeffsMod[T_VECFFE][T_LISTX ] = ReduceCoeffsModListxListx;
TabReduceCoeffsMod[T_VECFFE][T_VECTOR] = ReduceCoeffsModListxListx;
TabReduceCoeffsMod[T_VECFFE][T_VECFFE] = ReduceCoeffsModListxListx;
TabReduceCoeffsMod[T_VECFFE][T_VOID ] = ReduceCoeffsModListx;
TabPowerModCoeffsInt[T_LISTX ][T_LISTX ] = PowerModListxIntListx;
TabPowerModCoeffsInt[T_LISTX ][T_VECTOR] = PowerModListxIntListx;
TabPowerModCoeffsInt[T_LISTX ][T_VECFFE] = PowerModListxIntListx;
TabPowerModCoeffsInt[T_VECTOR][T_LISTX ] = PowerModListxIntListx;
TabPowerModCoeffsInt[T_VECTOR][T_VECTOR] = PowerModListxIntListx;
TabPowerModCoeffsInt[T_VECTOR][T_VECFFE] = PowerModListxIntListx;
TabPowerModCoeffsInt[T_VECFFE][T_LISTX ] = PowerModListxIntListx;
TabPowerModCoeffsInt[T_VECFFE][T_VECTOR] = PowerModListxIntListx;
TabPowerModCoeffsInt[T_VECFFE][T_VECFFE] = PowerModVecFFEIntVecFFE;
TabPowerModCoeffsLInt[T_LISTX ][T_LISTX ] = PowerModListxLIntListx;
TabPowerModCoeffsLInt[T_LISTX ][T_VECTOR] = PowerModListxLIntListx;
TabPowerModCoeffsLInt[T_LISTX ][T_VECFFE] = PowerModListxLIntListx;
TabPowerModCoeffsLInt[T_VECTOR][T_LISTX ] = PowerModListxLIntListx;
TabPowerModCoeffsLInt[T_VECTOR][T_VECTOR] = PowerModListxLIntListx;
TabPowerModCoeffsLInt[T_VECTOR][T_VECFFE] = PowerModListxLIntListx;
TabPowerModCoeffsLInt[T_VECFFE][T_LISTX ] = PowerModListxLIntListx;
TabPowerModCoeffsLInt[T_VECFFE][T_VECTOR] = PowerModListxLIntListx;
TabPowerModCoeffsLInt[T_VECFFE][T_VECFFE] = PowerModVecFFELIntVecFFE;
/* install the internal functions */
InstIntFunc( "ShiftedCoeffs", FunShiftedCoeffs );
InstIntFunc( "NormalizeCoeffs", FunNormalizeCoeffs );
InstIntFunc( "ShrinkCoeffs", FunShrinkCoeffs );
InstIntFunc( "AddCoeffs", FunAddCoeffs );
InstIntFunc( "SumCoeffs", FunSumCoeffs );
InstIntFunc( "ProductCoeffs", FunProductCoeffs );
InstIntFunc( "ProductCoeffsMod", FunProductCoeffsMod );
InstIntFunc( "ReduceCoeffs", FunReduceCoeffs );
InstIntFunc( "RemainderCoeffs", FunRemainderCoeffs );
InstIntFunc( "ReduceCoeffsMod", FunReduceCoeffsMod );
InstIntFunc( "PowerModCoeffs", FunPowerModCoeffs );
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.