/**************************************************************************** ** *FEqListList(<listL>,<listR>).........testiftwolistsareequal ** **'EqListList'returns'true'ifthetwolists<listL>and<listR>are **equaland'false'otherwise.Thisisagenericfunction,whichworksfor **alltypesoflists.
*/ Int EqListList (
Obj listL,
Obj listR )
{ Int lenL; // length of the left operand Int lenR; // length of the right operand
Obj elmL; // element of the left operand
Obj elmR; // element of the right operand Int i; // loop variable
// get the lengths of the lists and compare them
lenL = LEN_LIST( listL );
lenR = LEN_LIST( listR ); if ( lenL != lenR ) { return0;
}
// loop over the elements and compare them for ( i = 1; i <= lenL; i++ ) {
elmL = ELMV0_LIST( listL, i );
elmR = ELMV0_LIST( listR, i ); if ( elmL == 0 && elmR != 0 ) { return0;
} elseif ( elmR == 0 && elmL != 0 ) { return0;
} elseif ( ! EQ( elmL, elmR ) ) { return0;
}
}
// no differences found, the lists are equal return1;
}
/**************************************************************************** ** *FLtListList(<listL>,<listR>).........testiftwolistsareequal ** **'LtListList'returns'true'ifthelist<listL>islessthanthelist **<listR>and'false'otherwise.Thisisagenericfunction,whichworks **foralltypesoflists.
*/ Int LtListList (
Obj listL,
Obj listR )
{ Int lenL; // length of the left operand Int lenR; // length of the right operand
Obj elmL; // element of the left operand
Obj elmR; // element of the right operand Int i; // loop variable
// get the lengths of the lists and compare them
lenL = LEN_LIST( listL );
lenR = LEN_LIST( listR );
// loop over the elements and compare them for ( i = 1; i <= lenL && i <= lenR; i++ ) {
elmL = ELMV0_LIST( listL, i );
elmR = ELMV0_LIST( listR, i ); if ( elmL == 0 && elmR != 0 ) { return1;
} elseif ( elmR == 0 && elmL != 0 ) { return0;
} elseif ( ! EQ( elmL, elmR ) ) { return LT( elmL, elmR );
}
}
// reached the end of at least one list return (lenL < lenR);
}
Obj SumSclList (
Obj listL,
Obj listR )
{
Obj listS; // sum, result
Obj elmS; // one element of sum list
Obj elmR; // one element of right operand Int len; // length Int i; // loop variable
// make the result list
len = LEN_LIST( listR );
listS = NEW_PLIST_WITH_MUTABILITY( IS_MUTABLE_OBJ(listL) || IS_MUTABLE_OBJ(listR),
T_PLIST, len );
SET_LEN_PLIST( listS, len );
// loop over the entries and add for ( i = 1; i <= len; i++ ) {
elmR = ELMV0_LIST( listR, i ); if (elmR)
{
elmS = SUM( listL, elmR );
SET_ELM_PLIST( listS, i, elmS );
CHANGED_BAG( listS );
}
}
return listS;
}
Obj SumListScl (
Obj listL,
Obj listR )
{
Obj listS; // sum, result
Obj elmS; // one element of sum list
Obj elmL; // one element of left operand Int len; // length Int i; // loop variable
// make the result list
len = LEN_LIST( listL );
listS = NEW_PLIST_WITH_MUTABILITY( IS_MUTABLE_OBJ(listR) || IS_MUTABLE_OBJ(listL),
T_PLIST, len );
SET_LEN_PLIST( listS, len );
// loop over the entries and add for ( i = 1; i <= len; i++ ) {
elmL = ELMV0_LIST( listL, i ); if (elmL)
{
elmS = SUM( elmL, listR );
SET_ELM_PLIST( listS, i, elmS );
CHANGED_BAG( listS );
}
}
return listS;
}
Obj SumListList (
Obj listL,
Obj listR )
{
Obj listS; // sum, result
Obj elmS; // one element of the sum
Obj elmL; // one element of the left list
Obj elmR; // one element of the right list Int lenL,lenR, lenS;// lengths Int i; // loop variable
UInt mutS;
// make the result list -- same mutability as argument
len = LEN_LIST( list ); if (len == 0) { return NEW_PLIST_WITH_MUTABILITY(IS_MUTABLE_OBJ(list), T_PLIST_EMPTY, 0);
}
res = NEW_PLIST_WITH_MUTABILITY( IS_MUTABLE_OBJ(list), T_PLIST, len );
SET_LEN_PLIST( res, len );
// enter zeroes everywhere // For now, lets just do the simplest and safest thing for (i = 1; i <= len; i++ )
{
Obj tmp = ELM0_LIST( list, i); if (tmp) {
tmp = ZERO_SAMEMUT(tmp);
SET_ELM_PLIST( res, i,tmp );
CHANGED_BAG( res);
}
} // Now adjust the result TNUM info
static Obj ZeroListMutDefault(Obj list)
{
Obj res; // Obj elm; Int len; Int i;
// make the result list -- always mutable
len = LEN_LIST( list ); if (len == 0) { return NewEmptyPlist();
}
res = NEW_PLIST( T_PLIST ,len );
SET_LEN_PLIST( res, len );
// enter zeroes everywhere // For now, lets just do the simplest and safest thing for (i = 1; i <= len; i++ )
{
Obj tmp = ELM0_LIST( list, i); if (tmp) {
tmp = ZERO_MUT(tmp);
SET_ELM_PLIST( res, i,tmp );
CHANGED_BAG( res);
}
} // Now adjust the result TNUM info
/* This is intended to be installed as a method for the Attribute Zero, for rectangularmatrices ratherthantheOperationZeroOp.Thisisusefulbecause,knowingthat wewantanimmutableresult,wecan(a)reuseasinglerowofzeros
(b) record that the result is a rectangular table */
static Obj FuncZERO_ATTR_MAT(Obj self, Obj mat)
{
Obj zrow;
UInt len;
UInt i;
Obj res;
len = LEN_LIST(mat); if (len == 0) return NewImmutableEmptyPlist();
zrow = ZERO_SAMEMUT(ELM_LIST(mat,1));
CheckedMakeImmutable(zrow);
res = NEW_PLIST_IMM(T_PLIST_TAB_RECT, len);
SET_LEN_PLIST(res,len); for (i = 1; i <= len; i++)
SET_ELM_PLIST(res,i,zrow); return res;
}
static Obj AInvMutListDefault(Obj list)
{
Obj res;
Obj elm; Int len; Int i;
/* make the result list -- always mutable, since this might be a method for
AdditiveInverseOp */
len = LEN_LIST( list ); if (len == 0) { return NewEmptyPlist();
}
res = NEW_PLIST( T_PLIST , len );
SET_LEN_PLIST( res, len );
// enter the additive inverses everywhere for ( i = 1; i <= len; i++ ) {
elm = ELM0_LIST( list, i ); if (elm) {
elm = AINV_MUT( elm );
SET_ELM_PLIST( res, i, elm );
CHANGED_BAG( res );
}
}
static Obj AInvListDefault(Obj list)
{
Obj res;
Obj elm; Int len; Int i;
// make the result list -- same mutability as input
len = LEN_LIST( list ); if (len == 0) { return NEW_PLIST_WITH_MUTABILITY(IS_MUTABLE_OBJ(list), T_PLIST_EMPTY, 0);
}
res = NEW_PLIST_WITH_MUTABILITY( IS_MUTABLE_OBJ(list), T_PLIST, len );
SET_LEN_PLIST( res, len );
// enter the additive inverses everywhere for ( i = 1; i <= len; i++ ) {
elm = ELM0_LIST( list, i ); if (elm) {
elm = AINV_SAMEMUT( elm );
SET_ELM_PLIST( res, i, elm );
CHANGED_BAG( res );
}
}
Obj DiffSclList (
Obj listL,
Obj listR )
{
Obj listD; // difference, result
Obj elmD; // one element of difference list
Obj elmR; // one element of right operand Int len; // length Int i; // loop variable Int mut;
// make the result list
len = LEN_LIST( listR );
mut = IS_MUTABLE_OBJ(listL) || IS_MUTABLE_OBJ(listR); if (len == 0) { return NEW_PLIST_WITH_MUTABILITY(mut, T_PLIST_EMPTY, 0);
}
listD = NEW_PLIST_WITH_MUTABILITY(mut, T_PLIST, len);
SET_LEN_PLIST( listD, len );
// loop over the entries and subtract for ( i = 1; i <= len; i++ ) {
elmR = ELMV0_LIST( listR, i ); if (elmR)
{
elmD = DIFF( listL, elmR );
SET_ELM_PLIST( listD, i, elmD );
CHANGED_BAG( listD );
}
}
Obj DiffListScl (
Obj listL,
Obj listR )
{
Obj listD; // difference, result
Obj elmD; // one element of difference list
Obj elmL; // one element of left operand Int len; // length Int i; // loop variable Int mut;
// make the result list
len = LEN_LIST( listL );
mut = IS_MUTABLE_OBJ(listL) || IS_MUTABLE_OBJ(listR); if (len == 0) { return NEW_PLIST_WITH_MUTABILITY(mut, T_PLIST_EMPTY, 0);
}
listD = NEW_PLIST_WITH_MUTABILITY(mut, T_PLIST, len);
SET_LEN_PLIST( listD, len );
// loop over the entries and subtract for ( i = 1; i <= len; i++ ) {
elmL = ELMV0_LIST( listL, i ); if (elmL)
{
elmD = DIFF( elmL, listR );
SET_ELM_PLIST( listD, i, elmD );
CHANGED_BAG( listD );
}
Obj DiffListList (
Obj listL,
Obj listR )
{
Obj listD; // difference, result
Obj elmD; // one element of the difference
Obj elmL; // one element of the left list
Obj elmR; // one element of the right list Int i; // loop variable
UInt mutD; Int mut;
// Sort out mutability
mutD = 0; for (i = 1; i <= lenL; i++) if ((elmL = ELM0_LIST( listL, i)))
{
mutD = IS_MUTABLE_OBJ(elmL); break;
} for (i = 1; i <= lenR; i++) if ((elmR = ELM0_LIST( listR, i)))
{
mutD = mutD || IS_MUTABLE_OBJ(elmR); break;
}
// loop over the entries and subtract for ( i = 1; i <= lenD; i++ ) {
elmL = ELM0_LIST( listL, i );
elmR = ELM0_LIST( listR, i );
// Now compute the result 6 different cases! if (elmL)
{ if (elmR)
elmD= DIFF(elmL,elmR); elseif ( mutD)
elmD = SHALLOW_COPY_OBJ(elmL); else
elmD = elmL;
} elseif (elmR)
{ if (mutD)
elmD = AINV_MUT(elmR); else
elmD = AINV_SAMEMUT(elmR);
} else
elmD = 0;
if (elmD)
{
SET_ELM_PLIST( listD, i, elmD );
CHANGED_BAG( listD );
}
} // Now adjust the result TNUM info. There's not so much we can say // here with total reliability
Obj ProdSclList (
Obj listL,
Obj listR )
{
Obj listP; // product, result
Obj elmP; // one element of product list
Obj elmR; // one element of right operand Int len; // length Int i; // loop variable Int mut;
// make the result list
len = LEN_LIST( listR );
mut = IS_MUTABLE_OBJ(listL) || IS_MUTABLE_OBJ(listR); if (len == 0) { return NEW_PLIST_WITH_MUTABILITY(mut, T_PLIST_EMPTY, 0);
}
listP = NEW_PLIST_WITH_MUTABILITY(mut, T_PLIST, len);
SET_LEN_PLIST( listP, len );
// loop over the entries and multiply for ( i = 1; i <= len; i++ ) {
elmR = ELMV0_LIST( listR, i ); if (elmR)
{
elmP = PROD( listL, elmR );
SET_ELM_PLIST( listP, i, elmP );
CHANGED_BAG( listP );
}
} if (IS_PLIST( listR ))
{ if (HAS_FILT_LIST(listR, FN_IS_DENSE))
SET_FILT_LIST( listP, FN_IS_DENSE ); elseif (HAS_FILT_LIST(listR, FN_IS_NDENSE))
SET_FILT_LIST( listP, FN_IS_NDENSE );
}
return listP;
}
Obj ProdListScl (
Obj listL,
Obj listR )
{
Obj listP; // product, result
Obj elmP; // one element of product list
Obj elmL; // one element of left operand Int len; // length Int i; // loop variable Int mut;
// make the result list
len = LEN_LIST( listL );
mut = IS_MUTABLE_OBJ(listL) || IS_MUTABLE_OBJ(listR); if (len == 0) { return NEW_PLIST_WITH_MUTABILITY(mut, T_PLIST_EMPTY, 0);
}
listP = NEW_PLIST_WITH_MUTABILITY(mut, T_PLIST, len);
SET_LEN_PLIST( listP, len );
// loop over the entries and multiply for ( i = 1; i <= len; i++ ) {
elmL = ELMV0_LIST( listL, i ); if (elmL) {
elmP = PROD( elmL, listR );
SET_ELM_PLIST( listP, i, elmP );
CHANGED_BAG( listP );
}
}
Obj ProdListList (
Obj listL,
Obj listR )
{
Obj listP; // product, result
Obj elmP; // one summand of the product
Obj elmL; // one element of the left list
Obj elmR; // one element of the right list Int lenL,lenR,len; // length Int i; // loop variable Int imm;
// get and check the length
lenL = LEN_LIST( listL );
lenR = LEN_LIST( listR );
len = (lenL < lenR) ? lenL : lenR; // loop over the entries and multiply and accumulate
listP = 0;
imm = 0; for (i = 1; i <= len; i++)
{
elmL = ELM0_LIST( listL, i );
elmR = ELM0_LIST( listR, i ); if (elmL && elmR)
{
elmP = PROD( elmL, elmR ); if (listP)
listP = SUM( listP, elmP ); else
{
listP = elmP;
imm = !IS_MUTABLE_OBJ(listP);
}
}
}
// TODO: This is possible expensive, we may be able to settle for // a cheaper check and call MakeImmutable() instead. if (imm && IS_MUTABLE_OBJ(listP))
CheckedMakeImmutable(listP);
if (!listP)
ErrorMayQuit("Inner product multiplication of lists: no summands", 0, 0);
static Obj OneMatrix(Obj mat, UInt mut)
{
Obj res = 0; // one, result
Obj row; // one row of the result
Obj zero = 0; // zero element
Obj one = 0; // one element
UInt len; // length (and width) of matrix
UInt i, k; // loop variables BOOL rmut; // rows of result mutable? BOOL cmut; // result mutable?
GAP_ASSERT(mut <= 2);
// check that the operand is a *square* matrix
len = LEN_LIST( mat ); if ( len != LEN_LIST( ELM_LIST( mat, 1 ) ) ) {
ErrorMayQuit("Matrix ONE: <mat> must be square (not %d by %d)",
(Int)len, (Int)LEN_LIST(ELM_LIST(mat, 1)));
}
// get the zero and the one switch (mut) { case0:
zero = ZERO_MUT( ELM_LIST( ELM_LIST( mat, 1 ), 1 ) );
one = ONE_SAMEMUT(zero);
CheckedMakeImmutable(zero);
CheckedMakeImmutable(one);
cmut = rmut = FALSE; break;
case2:
zero = ZERO_SAMEMUT( ELM_LIST( ELM_LIST( mat, 1 ), 1 ) );
one = ONE( zero );
cmut = rmut = TRUE; break;
}
// make the identity matrix
res = NEW_PLIST(T_PLIST, len);
SET_LEN_PLIST( res, len ); for ( i = 1; i <= len; i++ ) {
row = NEW_PLIST(T_PLIST, len);
SET_LEN_PLIST( row, len ); for ( k = 1; k <= len; k++ )
SET_ELM_PLIST( row, k, zero );
SET_ELM_PLIST( row, i, one ); if (!rmut)
MakeImmutableNoRecurse(row);
SET_ELM_PLIST( res, i, row );
CHANGED_BAG( res );
} if (!cmut)
MakeImmutableNoRecurse(res);
static Obj InvMatrix(Obj mat, UInt mut)
{
Obj res = 0; // power, result
Obj row; // one row of the matrix
Obj row2; // another row of the matrix
Obj elm; // one element of the matrix
Obj elm2; // another element of the matrix
Obj zero = 0; // zero element
Obj one = 0; // one element
UInt len; // length (and width) of matrix
UInt i, k, l; // loop variables BOOL rmut; // rows of result mutable? BOOL cmut; // result mutable?
GAP_ASSERT(mut <= 2);
// check that the operand is a *square* matrix
len = LEN_LIST( mat ); if ( len != LEN_LIST( ELM_LIST( mat, 1 ) ) ) {
ErrorMayQuit("Matrix INV: <mat> must be square (not %d by %d)",
(Int)len, (Int)LEN_LIST(ELM_LIST(mat, 1)));
}
// get the zero and the one switch (mut) { case0:
zero = ZERO_MUT( ELM_LIST( ELM_LIST( mat, 1 ), 1 ) );
one = ONE_SAMEMUT(zero);
CheckedMakeImmutable(zero);
CheckedMakeImmutable(one);
cmut = rmut = FALSE; break;
case2:
zero = ZERO_SAMEMUT( ELM_LIST( ELM_LIST( mat, 1 ), 1 ) );
one = ONE( zero );
cmut = rmut = TRUE; break;
}
// make a matrix of the form $ ( Id_<len> | <mat> ) $
res = NEW_PLIST(T_PLIST, len);
SET_LEN_PLIST(res, len); for (i = 1; i <= len; i++) {
row = NEW_PLIST(T_PLIST, 2 * len);
SET_LEN_PLIST(row, 2 * len);
SET_ELM_PLIST(res, i, row);
CHANGED_BAG(res);
} for ( i = 1; i <= len; i++ ) {
row = ELM_PLIST( res, i ); for ( k = 1; k <= len; k++ )
SET_ELM_PLIST( row, k, zero );
SET_ELM_PLIST( row, i, one );
} for ( i = 1; i <= len; i++ ) {
row = ELM_PLIST( res, i );
row2 = ELM_LIST( mat, i ); for ( k = 1; k <= len; k++ ) {
SET_ELM_PLIST( row, k + len, ELM_LIST( row2, k ) );
CHANGED_BAG( row );
}
}
// make row operations to reach form $ ( <inv> | Id_<len> ) $ // loop over the columns of <mat> for ( k = len+1; k <= 2*len; k++ ) {
// find a nonzero entry in this column for ( i = k-len; i <= len; i++ ) { if ( ! EQ( ELM_PLIST( ELM_PLIST(res,i), k ), zero ) ) break;
} if ( len < i ) { return Fail;
}
// make the row the <k>-th row and normalize it
row = ELM_PLIST( res, i );
SET_ELM_PLIST( res, i, ELM_PLIST( res, k-len ) );
SET_ELM_PLIST( res, k-len, row ); if (mut < 2)
elm2 = INV_SAMEMUT( ELM_PLIST( row, k ) ); else
elm2 = INV( ELM_PLIST( row, k ) ); for ( l = 1; l <= 2*len; l++ ) {
elm = PROD( elm2, ELM_PLIST( row, l ) );
SET_ELM_PLIST( row, l, elm );
CHANGED_BAG( row );
}
// clear all entries in this column for ( i = 1; i <= len; i++ ) {
row2 = ELM_PLIST( res, i ); if (mut < 2)
elm = AINV_MUT( ELM_PLIST( row2, k ) ); else
elm = AINV_SAMEMUT( ELM_PLIST( row2, k ) ); if ( i != k-len && ! EQ(elm,zero) ) { for ( l = 1; l <= 2*len; l++ ) {
elm2 = PROD( elm, ELM_PLIST( row, l ) );
elm2 = SUM( ELM_PLIST( row2, l ), elm2 );
SET_ELM_PLIST( row2, l, elm2 );
CHANGED_BAG( row2 );
}
}
}
}
// throw away the right halves of each row for ( i = 1; i <= len; i++ ) {
row = ELM_PLIST(res, i);
SET_LEN_PLIST(row, len);
SHRINK_PLIST(row, len); if (!rmut)
MakeImmutableNoRecurse(row);
} if (!cmut)
MakeImmutableNoRecurse(res);
static Obj InvMatWithRowVecs(Obj mat, UInt mut)
{
Obj res; // result
Obj matcopy; // copy of mat
Obj row = 0; // one row of matcopy
Obj row2; // corresponding row of res
Obj row3; // another row of matcopy
Obj x = 0; // one element of the matrix
Obj xi; // 1/x
Obj y; // another element of the matrix
Obj yi; // -y
Obj zero; // zero element
Obj zerov; // zero vector
Obj one; // one element
UInt len; // length (and width) of matrix
UInt i, k, j; // loop variables
// check that the operand is a *square* matrix
len = LEN_LIST( mat ); if ( len != LEN_LIST( ELM_LIST( mat, 1 ) ) ) {
ErrorMayQuit("Matrix INV: <mat> must be square (not %d by %d)",
(Int)len, (Int)LEN_LIST(ELM_LIST(mat, 1)));
}
// get the zero and the one
zerov = ZERO_SAMEMUT(ELMW_LIST(mat, 1));
zero = ZERO_SAMEMUT(ELMW_LIST(ELMW_LIST(mat, 1), 1));
one = ONE( zero );
// set up res (initially the identity) and matcopy
res = NEW_PLIST(T_PLIST,len);
matcopy = NEW_PLIST(T_PLIST,len);
SET_LEN_PLIST(res,len);
SET_LEN_PLIST(matcopy,len); for (i = 1; i <= len; i++)
{
row = SHALLOW_COPY_OBJ(zerov);
ASS_LIST(row,i,one);
SET_ELM_PLIST(res,i,row);
CHANGED_BAG(res);
row = SHALLOW_COPY_OBJ(ELM_LIST(mat,i));
SET_ELM_PLIST(matcopy,i,row);
CHANGED_BAG(matcopy);
}
/* Now to work, make matcopy an identity by row operations and
do the same row operations to res */
// outer loop over columns of matcopy for (i = 1; i <= len; i++)
{ // Find a non-zero leading entry that is in that column for (j = i; j <= len; j++)
{
row = ELM_PLIST(matcopy,j);
x = ELMW_LIST(row,i); if (!EQ(x,zero)) break;
}
// if there isn't one then the matrix is not invertible if (j > len) return Fail;
// Maybe swap two rows // But I will want this value anyway
row2 = ELM_PLIST(res,j); if (j != i)
{
SET_ELM_PLIST(matcopy,j,ELM_PLIST(matcopy,i));
SET_ELM_PLIST(res,j,ELM_PLIST(res,i));
SET_ELM_PLIST(matcopy,i,row);
SET_ELM_PLIST(res,i,row2);
}
/*Maybe rescale the row */ if (!EQ(x, one))
{
xi = INV(x);
CALL_2ARGS(MultVectorLeftOp, row, xi);
CALL_2ARGS(MultVectorLeftOp, row2, xi);
}
// Clear the entries. We know that we can ignore the entries in rows i..j for (k = 1; k < i; k++)
{
row3 = ELM_PLIST(matcopy,k);
y = ELMW_LIST(row3,i); if (!EQ(y,zero))
{
yi = AINV_SAMEMUT(y);
CALL_3ARGS(AddRowVectorOp, row3, row, yi);
CALL_3ARGS(AddRowVectorOp, ELM_PLIST(res,k), row2, yi);
}
} for (k = j+1; k <= len; k++)
{
row3 = ELM_PLIST(matcopy,k);
y = ELMW_LIST(row3,i); if (!EQ(y,zero))
{
yi = AINV_SAMEMUT(y);
CALL_3ARGS(AddRowVectorOp, row3, row, yi);
CALL_3ARGS(AddRowVectorOp, ELM_PLIST(res,k), row2, yi);
}
}
}
// Now we adjust mutability. Couldn't do it earlier, because AddRowVector, // etc. needs mutable target vectors switch (mut)
{ case0:
CheckedMakeImmutable(res); break;
case1: if (IS_MUTABLE_OBJ(mat))
{ if (!IS_MUTABLE_OBJ(ELM_LIST(mat,1))) for (i = 1; i <= len; i++)
CheckedMakeImmutable(ELM_LIST(res,i));
} else
CheckedMakeImmutable(res); break; case2: break;
}
if (!IS_PLIST(u) || !IS_DENSE_LIST(u)) {
RequireArgument(SELF_NAME, u, "must be a dense plain list");
} if (!IS_PLIST(v) || !IS_DENSE_LIST(v)) {
RequireArgument(SELF_NAME, v, "must be a dense plain list");
}
lu = LEN_PLIST( u );
lv = LEN_PLIST( v );
// strip off common prefixes
i = 1; while ( i <= lu && i <= lv && EQ(ELM_PLIST( u,i ), ELM_PLIST( v,i )) )
i++;
// Is u a prefix of v ? Return true if u is a proper prefix. if ( i > lu ) return (lu < lv) ? True : False;
// Is v a prefix of u ? if ( i > lv ) returnFalse;
// Now determine the lexicographic order. The monomial is interpreted // as a string of indeterminates. if ( i % 2 == 1 ) { // The first difference between u and v is an indeterminate.
lexico = LT(ELM_PLIST( u, i ), ELM_PLIST( v, i )) ? True : False;
i++;
} else { // The first difference between u and v is an exponent.
lexico = LT(ELM_PLIST( v, i ), ELM_PLIST( u, i )) ? True : False;
}
// Now add up the remaining exponents in order to compare the total // degrees.
total = INTOBJ_INT(0); while ( i <= lu && i <= lv ) {
C_SUM_FIA( total, total, ELM_PLIST( u, i ) );
C_DIFF_FIA( total, total, ELM_PLIST( v, i ) );
i += 2;
}
// Only one of the following while loops is executed while ( i <= lu ) {
C_SUM_FIA( total, total, ELM_PLIST( u, i ) );
i += 2;
} while ( i <= lv ) {
C_DIFF_FIA( total, total, ELM_PLIST( v, i ) );
i += 2;
}
if (!IS_PLIST(u) || !IS_DENSE_LIST(u)) {
RequireArgument(SELF_NAME, u, "must be a dense plain list");
} if (!IS_PLIST(v) || !IS_DENSE_LIST(v)) {
RequireArgument(SELF_NAME, v, "must be a dense plain list");
}
lu = LEN_PLIST( u );
lv = LEN_PLIST( v );
// compare the total degrees
total = INTOBJ_INT(0); for (i=2;i<=lu;i+=2) {
C_SUM_FIA( total, total, ELM_PLIST( u, i ) );
}
for (i=2;i<=lv;i+=2) {
C_DIFF_FIA( total, total, ELM_PLIST( v, i ) );
}
if ( ! (EQ( total, INTOBJ_INT(0))) ) { // degrees differ, use these return LT( total, INTOBJ_INT(0)) ? True : False;
}
// now use lexicographic ordering
i=1; while (i<=lu && i<=lv) {
ai=ELM_PLIST(u,i);
bi=ELM_PLIST(v,i); if (LT(bi,ai)) { returnTrue;
} if (LT(ai,bi)) { returnFalse;
}
ai=ELM_PLIST(u,i+1);
bi=ELM_PLIST(v,i+1); if (LT(ai,bi)) { returnTrue;
} if (LT(bi,ai)) { returnFalse;
}
i+=2;
} if (i<lv) { returnTrue;
} returnFalse;
}
// init filters and functions
InitGVarFuncsFromTable( GVarFuncs );
return0;
}
/**************************************************************************** ** *FInitInfoListOper()...............tableofinitfunctions
*/ static StructInitInfo module = { // init struct using C99 designated initializers; for a full list of // fields, please refer to the definition of StructInitInfo
.type = MODULE_BUILTIN,
.name = "listoper",
.initKernel = InitKernel,
.initLibrary = InitLibrary,
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.