예제 #1
0
static void AddObjSetNew(Obj set, Obj obj)
{
  UInt size = CONST_ADDR_WORD(set)[OBJSET_SIZE];
  UInt hash = ObjHash(set, obj);
  GAP_ASSERT(TNUM_OBJ(set) == T_OBJSET);
  GAP_ASSERT(hash < size);
  for (;;) {
    Obj current;
    current = CONST_ADDR_OBJ(set)[OBJSET_HDRSIZE+hash];
    if (!current) {
      ADDR_OBJ(set)[OBJSET_HDRSIZE+hash] = obj;
      ADDR_WORD(set)[OBJSET_USED]++;
      CHANGED_BAG(set);
      return;
    }
    if (current == Undefined) {
      ADDR_OBJ(set)[OBJSET_HDRSIZE+hash] = obj;
      ADDR_WORD(set)[OBJSET_USED]++;
      GAP_ASSERT(ADDR_WORD(set)[OBJSET_DIRTY] >= 1);
      ADDR_WORD(set)[OBJSET_DIRTY]--;
      CHANGED_BAG(set);
      return;
    }
    hash++;
    if (hash >= size)
      hash = 0;
  }
}
예제 #2
0
파일: vecffe.c 프로젝트: BlairArchibald/gap
/****************************************************************************
**
*F  FuncAddRowVectorVecFFEs( <self>, <vecL>, <vecR> )
**
*/
Obj FuncAddRowVectorVecFFEs( Obj self, Obj vecL, Obj vecR )
{
    Obj *ptrL;
    Obj *ptrR;
    FFV  valS;
    FFV  valL;
    FFV  valR;
    FF  fld;
    FFV *succ;
    UInt len;
    UInt xtype;
    UInt i;

    xtype = KTNumPlist(vecL, (Obj *) 0);
    if (xtype != T_PLIST_FFE && xtype != T_PLIST_FFE + IMMUTABLE)
        return TRY_NEXT_METHOD;

    xtype = KTNumPlist(vecR, (Obj *) 0);
    if (xtype != T_PLIST_FFE && xtype != T_PLIST_FFE + IMMUTABLE)
        return TRY_NEXT_METHOD;

    /* check the lengths                                                   */
    len = LEN_PLIST(vecL);
    if (len != LEN_PLIST(vecR)) {
        vecR = ErrorReturnObj(
            "Vector *: vector lengths differ <left> %d,  <right> %d",
            (Int)len, (Int)LEN_PLIST(vecR),
            "you can replace vector <right> via 'return <right>;'");
        return CALL_2ARGS(AddRowVectorOp, vecL, vecR);
    }

    /* check the fields                                                    */
    fld = FLD_FFE(ELM_PLIST(vecL, 1));
    if (FLD_FFE(ELM_PLIST(vecR, 1)) != fld) {
        /* check the characteristic                                        */
        if (CHAR_FF(fld) == CHAR_FF(FLD_FFE(ELM_PLIST(vecR, 1))))
            return TRY_NEXT_METHOD;

        vecR = ErrorReturnObj(
            "AddRowVector: vectors have different fields",
            0L, 0L,
            "you can replace vector <right> via 'return <right>;'");
        return CALL_2ARGS(AddRowVectorOp, vecL, vecR);
    }

    succ = SUCC_FF(fld);
    ptrL = ADDR_OBJ(vecL);
    ptrR = ADDR_OBJ(vecR);

    for (i = 1; i <= len; i++) {
        valL = VAL_FFE(ptrL[i]);
        valR = VAL_FFE(ptrR[i]);
        valS = SUM_FFV(valL, valR, succ);
        ptrL[i] = NEW_FFE(fld, valS);
    }
    return (Obj) 0;
}
예제 #3
0
파일: vecffe.c 프로젝트: BlairArchibald/gap
/****************************************************************************
**
*F  ProdVecFFEVecFFE(<vecL>,<vecR>) . . . . . . . . .  product of two vectors
**
**  'ProdVecFFEVecFFE'  returns the product  of   the two vectors <vecL>  and
**  <vecR>.  The  product  is the  sum of the   products of the corresponding
**  elements of the two lists.
**
**  'ProdVecFFEVecFFE' is an improved version  of 'ProdListList',  which does
**  not call 'PROD'.
*/
Obj             ProdVecFFEVecFFE (
    Obj                 vecL,
    Obj                 vecR )
{
    FFV                 valP;           /* one product                     */
    FFV                 valS;           /* sum of the products             */
    Obj *               ptrL;           /* pointer into the left operand   */
    FFV                 valL;           /* one element of left operand     */
    Obj *               ptrR;           /* pointer into the right operand  */
    FFV                 valR;           /* one element of right operand    */
    UInt                lenL, lenR, len; /* length                          */
    UInt                i;              /* loop variable                   */
    FF                  fld;            /* finite field                    */
    FF *                succ;           /* successor table                 */

    /* check the lengths                                                   */
    lenL = LEN_PLIST(vecL);
    lenR = LEN_PLIST(vecR);
    len = (lenL < lenR) ? lenL : lenR;

    /* check the fields                                                    */
    fld = FLD_FFE(ELM_PLIST(vecL, 1));
    if (FLD_FFE(ELM_PLIST(vecR, 1)) != fld) {
        /* check the characteristic                                        */
        if (CHAR_FF(fld) == CHAR_FF(FLD_FFE(ELM_PLIST(vecR, 1))))
            return ProdListList(vecL, vecR);

        vecR = ErrorReturnObj(
            "Vector *: vectors have different fields",
            0L, 0L,
            "you can replace vector <right> via 'return <right>;'");
        return PROD(vecL, vecR);
    }

    /* to add we need the successor table                                  */
    succ = SUCC_FF(fld);

    /* loop over the elements and add                                      */
    valS = (FFV)0;
    ptrL = ADDR_OBJ(vecL);
    ptrR = ADDR_OBJ(vecR);
    for (i = 1; i <= len; i++) {
        valL = VAL_FFE(ptrL[i]);
        valR = VAL_FFE(ptrR[i]);
        valP = PROD_FFV(valL, valR, succ);
        valS = SUM_FFV(valS, valP, succ);
    }

    /* return the result                                                   */
    return NEW_FFE(fld, valS);
}
예제 #4
0
파일: vecffe.c 프로젝트: BlairArchibald/gap
/****************************************************************************
**
*F  DiffVecFFEFFE(<vecL>,<elmR>)   difference of a vector and a fin field elm
**
**  'DiffVecFFEFFE' returns   the  difference of the  vector  <vecL>  and the
**  finite field element <elmR>.  The difference   is a list,   where each
**  element  is the difference of <elmR> and the corresponding element of
**  <vecL>. 
**
**  'DiffVecFFEFFE' is an improved  version of 'DiffListScl', which  does not
**  call 'DIFF'.
*/
Obj             DiffVecFFEFFE (
    Obj                 vecL,
    Obj                 elmR )
{
    Obj                 vecD;           /* handle of the difference        */
    Obj *               ptrD;           /* pointer into the difference     */
    FFV                 valD;           /* the value of a difference       */
    Obj *               ptrL;           /* pointer into the left operand   */
    FFV                 valL;           /* the value of an element in vecL */
    UInt                len;            /* length                          */
    UInt                i;              /* loop variable                   */
    FF                  fld;            /* finite field                    */
    FF *                succ;           /* successor table                 */
    FFV                 valR;           /* the value of elmR               */

    /* get the field and check that vecL and elmR have the same field      */
    fld = FLD_FFE(ELM_PLIST(vecL, 1));
    if (FLD_FFE(elmR) != fld) {
        /* check the characteristic                                        */
        if (CHAR_FF(fld) == CHAR_FF(FLD_FFE(elmR)))
            return DiffListScl(vecL, elmR);

        elmR = ErrorReturnObj(
            "<vec>-<elm>: <elm> and <vec> must belong to the same finite field",
            0L, 0L, "you can replace <elm> via 'return <elm>;'");
        return DIFF(vecL, elmR);
    }

    /* make the result list                                                */
    len = LEN_PLIST(vecL);
    vecD = NEW_PLIST(IS_MUTABLE_OBJ(vecL) ?
                T_PLIST_FFE : T_PLIST_FFE + IMMUTABLE, len);
    SET_LEN_PLIST(vecD, len);

    /* to subtract we need the successor table                             */
    succ = SUCC_FF(fld);

    /* loop over the elements and subtract                                 */
    valR = VAL_FFE(elmR);
    valR = NEG_FFV(valR, succ);
    ptrL = ADDR_OBJ(vecL);
    ptrD = ADDR_OBJ(vecD);
    for (i = 1; i <= len; i++) {
        valL = VAL_FFE(ptrL[i]);
        valD = SUM_FFV(valL, valR, succ);
        ptrD[i] = NEW_FFE(fld, valD);
    }

    /* return the result                                                   */
    return vecD;
}
예제 #5
0
파일: vecffe.c 프로젝트: BlairArchibald/gap
/****************************************************************************
**
*F  SumFFEVecFFE(<elmL>,<vecR>) . . . .  sum of an fin field elm and a vector
**
**  'SumFFEVecFFE' returns the sum of the fin field elm <elmL> and the vector
**  <vecR>.  The sum is a  list, where each element is  the sum of <elmL> and
**  the corresponding element of <vecR>.
**
**  'SumFFEVecFFE' is an improved version  of  'SumSclList', which  does  not
**  call 'SUM'.
*/
Obj             SumFFEVecFFE (
    Obj                 elmL,
    Obj                 vecR )
{
    Obj                 vecS;           /* handle of the sum               */
    Obj *               ptrS;           /* pointer into the sum            */
    FFV                 valS;           /* the value of a sum              */
    Obj *               ptrR;           /* pointer into the right operand  */
    FFV                 valR;           /* the value of an element in vecR */
    UInt                len;            /* length                          */
    UInt                i;              /* loop variable                   */
    FF                  fld;            /* finite field                    */
    FF *                succ;           /* successor table                 */
    FFV                 valL;           /* the value of elmL               */

    /* get the field and check that elmL and vecR have the same field      */
    fld = FLD_FFE(ELM_PLIST(vecR, 1));
    if (FLD_FFE(elmL) != fld) {
        /* check the characteristic                                          */
        if (CHAR_FF(fld) == CHAR_FF(FLD_FFE(elmL)))
            return SumSclList(elmL, vecR);

        elmL = ErrorReturnObj(
            "<elm>+<vec>: <elm> and <vec> must belong to the same finite field",
            0L, 0L, "you can replace <elm> via 'return <elm>;'");
        return SUM(elmL, vecR);
    }

    /* make the result list                                                */
    len = LEN_PLIST(vecR);
    vecS = NEW_PLIST(IS_MUTABLE_OBJ(vecR) ?
                T_PLIST_FFE : T_PLIST_FFE + IMMUTABLE, len);
    SET_LEN_PLIST(vecS, len);

    /* to add we need the successor table                                  */
    succ = SUCC_FF(fld);

    /* loop over the elements and add                                      */
    valL = VAL_FFE(elmL);
    ptrR = ADDR_OBJ(vecR);
    ptrS = ADDR_OBJ(vecS);
    for (i = 1; i <= len; i++) {
        valR = VAL_FFE(ptrR[i]);
        valS = SUM_FFV(valL, valR, succ);
        ptrS[i] = NEW_FFE(fld, valS);
    }

    /* return the result                                                   */
    return vecS;
}
Obj NewPolymakeExternalObject(enum polymake_object_type t) {
  Obj o;
  o = NewBag(T_POLYMAKE, 2*sizeof(Obj));
 
  switch(t) {
    case T_POLYMAKE_EXTERNAL_CONE:
      ADDR_OBJ(o)[0] = TheTypeExternalPolymakeCone;
      break;
    case T_POLYMAKE_EXTERNAL_FAN:
      ADDR_OBJ(o)[0] = TheTypeExternalPolymakeFan;
      break;
    case T_POLYMAKE_EXTERNAL_POLYTOPE:
      ADDR_OBJ(o)[0] = TheTypeExternalPolymakePolytope;
      break;
    case T_POLYMAKE_EXTERNAL_TROPICAL_HYPERSURFACE:
      ADDR_OBJ(o)[0] = TheTypeExternalPolymakeTropicalHypersurface;
      break;
    case T_POLYMAKE_EXTERNAL_TROPICAL_POLYTOPE:
      ADDR_OBJ(o)[0] = TheTypeExternalPolymakeTropicalPolytope;
      break;
    case T_POLYMAKE_EXTERNAL_MATROID:
      ADDR_OBJ(o)[0] = TheTypeExternalPolymakeMatroid;
      break;
  }
  ADDR_OBJ(o)[1] = NULL;
  return o;
}
예제 #7
0
void RemoveObjSet(Obj set, Obj obj) {
  Int pos = FindObjSet(set, obj);
  if (pos >= 0) {
    ADDR_OBJ(set)[OBJSET_HDRSIZE+pos] = Undefined;
    ADDR_WORD(set)[OBJSET_USED]--;
    ADDR_WORD(set)[OBJSET_DIRTY]++;
    CHANGED_BAG(set);
    CheckObjSetForCleanUp(set, 0);
  }
}
예제 #8
0
파일: weakptr.c 프로젝트: LiftnLearn/gap
/****************************************************************************
**
*F  CleanObjWPObjCopy( <obj> ) . . . . . . . . . . . . . . clean WPobj copy
*/
void CleanObjWPObjCopy (
    Obj                 obj )
{
    UInt                i;              /* loop variable                   */
    Obj                 elm;            /* subobject                       */

    /* remove the forwarding pointer                                       */
    ADDR_OBJ(obj)[0] = ELM_PLIST( ADDR_OBJ(obj)[0], 1 );
    CHANGED_BAG(obj);

    /* now it is cleaned                                                   */
    RetypeBag( obj, TNUM_OBJ(obj) - COPYING );

    /* clean the subvalues                                                 */
    for ( i = 1; i < SIZE_OBJ(obj)/sizeof(Obj); i++ ) {
        elm = ADDR_OBJ(obj)[i];
        if ( elm != 0  && !IS_WEAK_DEAD_BAG(elm)) 
          CLEAN_OBJ( elm );
    }

}
예제 #9
0
파일: weakptr.c 프로젝트: LiftnLearn/gap
void LoadWPObj( Obj wpobj )
{
  UInt len, i;
  Obj *ptr;
  ptr = ADDR_OBJ(wpobj)+1;
  len =   LoadUInt();
  STORE_LEN_WPOBJ(wpobj, len);
  for (i = 1; i <= len; i++)
    {
      *ptr++ = LoadSubObj();
    }
}
예제 #10
0
파일: boehm_gc.c 프로젝트: phs75/gap
Region * NewRegion(void)
{
    Region *           result;
    pthread_rwlock_t * lock;
    Obj                region_obj;
#ifndef DISABLE_GC
    result = GC_malloc(sizeof(Region) + (MAX_THREADS + 1));
    lock = GC_malloc_atomic(sizeof(*lock));
    GC_register_finalizer(lock, LockFinalizer, NULL, NULL, NULL);
#else
    result = calloc(1, sizeof(Region) + (MAX_THREADS + 1));
    lock = malloc(sizeof(*lock));
#endif
    pthread_rwlock_init(lock, NULL);
    region_obj = NewBag(T_REGION, sizeof(Region *));
    MakeBagPublic(region_obj);
    *(Region **)(ADDR_OBJ(region_obj)) = result;
    result->obj = region_obj;
    result->lock = lock;
    return result;
}
예제 #11
0
파일: weakptr.c 프로젝트: LiftnLearn/gap
void SaveWPObj( Obj wpobj )
{
  UInt len, i;
  Obj *ptr;
  Obj x;
  ptr = ADDR_OBJ(wpobj)+1;
  len = STORED_LEN_WPOBJ(wpobj);
  SaveUInt(len);
  for (i = 1; i <= len; i++)
    {
      x = *ptr;
      if (IS_WEAK_DEAD_BAG(x))
        {
          SaveSubObj(0);
          *ptr = 0;
        }
      else
        SaveSubObj(x);
      ptr++;
    }
}
예제 #12
0
파일: weakptr.c 프로젝트: LiftnLearn/gap
Obj CopyObjWPObj (
    Obj                 obj,
    Int                 mut )
{
    Obj                 copy;           /* copy, result                    */
    Obj                 tmp;            /* temporary variable              */
    Obj                 elm;
    UInt                i;              /* loop variable                   */

    /* make a copy                                                         */
    if ( mut ) {
        copy = NewBag( T_WPOBJ, SIZE_OBJ(obj) );
        ADDR_OBJ(copy)[0] = ADDR_OBJ(obj)[0];
    }
    else {
        copy = NewBag( T_PLIST+IMMUTABLE, SIZE_OBJ(obj) );
        SET_LEN_PLIST(copy,LengthWPObj(obj));
    }

    /* leave a forwarding pointer                                          */
    tmp = NEW_PLIST( T_PLIST, 2 );
    SET_LEN_PLIST( tmp, 2 );
    SET_ELM_PLIST( tmp, 1, ADDR_OBJ(obj)[0] );
    SET_ELM_PLIST( tmp, 2, copy );
    ADDR_OBJ(obj)[0] = tmp;
    CHANGED_BAG(obj);

    /* now it is copied                                                    */
    RetypeBag( obj, T_WPOBJ + COPYING );

    /* copy the subvalues                                                  */
    for ( i =  SIZE_OBJ(obj)/sizeof(Obj)-1; i > 0; i-- ) {
        elm = ADDR_OBJ(obj)[i];
        if ( elm != 0  && !IS_WEAK_DEAD_BAG(elm)) {
            tmp = COPY_OBJ( elm, mut );
            ADDR_OBJ(copy)[i] = tmp;
            CHANGED_BAG( copy );
        }
    }

    /* return the copy                                                     */
    return copy;
}
예제 #13
0
파일: vecffe.c 프로젝트: BlairArchibald/gap
/****************************************************************************
**
*F  DiffVecFFEVecFFE(<vecL>,<vecR>) . . . . . . . . difference of two vectors
**
**  'DiffVecFFEVecFFE'  returns the difference of the  two vectors <vecL> and
**  <vecR>.   The  difference is   a new   list, where  each  element  is the
**  difference of the corresponding elements of <vecL> and <vecR>.
**
**  'DiffVecFFEVecFFE' is an improved  version of  'DiffListList', which does
**  not call 'DIFF'.
*/
Obj             DiffVecFFEVecFFE (
    Obj                 vecL,
    Obj                 vecR )
{
    Obj                 vecD;           /* handle of the difference        */
    Obj *               ptrD;           /* pointer into the difference     */
    FFV                 valD;           /* one element of difference list  */
    Obj *               ptrL;           /* pointer into the left operand   */
    FFV                 valL;           /* one element of left operand     */
    Obj *               ptrR;           /* pointer into the right operand  */
    FFV                 valR;           /* one element of right operand    */
    UInt                len, lenL, lenR; /* length                          */
    UInt                lenmin;
    UInt                i;              /* loop variable                   */
    FF                  fld;            /* finite field                    */
    FF *                succ;           /* successor table                 */

    /* check the lengths                                                   */
    lenL = LEN_PLIST(vecL);
    lenR = LEN_PLIST(vecR);
    if (lenR > lenL) {
        len = lenR;
        lenmin = lenL;
    } else {
        len = lenL;
        lenmin = lenR;
    }

    /* check the fields                                                    */
    fld = FLD_FFE(ELM_PLIST(vecL, 1));
    if (FLD_FFE(ELM_PLIST(vecR, 1)) != fld) {
        /* check the characteristic                                        */
        if (CHAR_FF(fld) == CHAR_FF(FLD_FFE(ELM_PLIST(vecR, 1))))
            return DiffListList(vecL, vecR);

        vecR = ErrorReturnObj(
            "Vector -: vectors have different fields",
            0L, 0L, "you can replace vector <right> via 'return <right>;'");
        return DIFF(vecL, vecR);
    }

    /* make the result list                                                */
    vecD = NEW_PLIST((IS_MUTABLE_OBJ(vecL) || IS_MUTABLE_OBJ(vecR)) ?
                T_PLIST_FFE : T_PLIST_FFE + IMMUTABLE, len);
    SET_LEN_PLIST(vecD, len);

    /* to subtract we need the successor table                             */
    succ = SUCC_FF(fld);

    /* loop over the elements and subtract                                 */
    ptrL = ADDR_OBJ(vecL);
    ptrR = ADDR_OBJ(vecR);
    ptrD = ADDR_OBJ(vecD);
    for (i = 1; i <= lenmin; i++) {
        valL = VAL_FFE(ptrL[i]);
        valR = VAL_FFE(ptrR[i]);
        valR = NEG_FFV(valR, succ);
        valD = SUM_FFV(valL, valR, succ);
        ptrD[i] = NEW_FFE(fld, valD);
    }

    if (lenL < lenR)
        for (; i <= len; i++) {
            valR = VAL_FFE(ptrR[i]);
            valD = NEG_FFV(valR, succ);
            ptrD[i] = NEW_FFE(fld, valD);
        }
    else
        for (; i <= len; i++)
            ptrD[i] = ptrL[i];

    /* return the result                                                   */
    return vecD;
}
예제 #14
0
파일: weakptr.c 프로젝트: LiftnLearn/gap
/****************************************************************************
**
*F  CopyObjWPObjCopy( <obj>, <mut> ) . . . . . . . . . .  . copy a WPobj copy
*/
Obj CopyObjWPObjCopy (
    Obj                 obj,
    Int                 mut )
{
    return ELM_PLIST( ADDR_OBJ(obj)[0], 2 );
}
예제 #15
0
static void MarkObjMap(Obj obj)
{
  UInt size = CONST_ADDR_WORD(obj)[OBJSET_SIZE];
  MarkArrayOfBags( ADDR_OBJ(obj) + OBJSET_HDRSIZE, 2 * size );
}
예제 #16
0
파일: vecffe.c 프로젝트: BlairArchibald/gap
Obj FuncAddRowVectorVecFFEsMult( Obj self, Obj vecL, Obj vecR, Obj mult )
{
    Obj *ptrL;
    Obj *ptrR;
    FFV  valM;
    FFV  valS;
    FFV  valL;
    FFV  valR;
    FF  fld;
    FFV *succ;
    UInt len;
    UInt xtype;
    UInt i;

    if (TNUM_OBJ(mult) != T_FFE)
        return TRY_NEXT_METHOD;

    if (VAL_FFE(mult) == 0)
        return (Obj) 0;

    xtype = KTNumPlist(vecL, (Obj *) 0);
    if (xtype != T_PLIST_FFE && xtype != T_PLIST_FFE + IMMUTABLE)
        return TRY_NEXT_METHOD;

    xtype = KTNumPlist(vecR, (Obj *) 0);
    if (xtype != T_PLIST_FFE && xtype != T_PLIST_FFE + IMMUTABLE)
        return TRY_NEXT_METHOD;


    /* check the lengths                                                   */
    len = LEN_PLIST(vecL);
    if (len != LEN_PLIST(vecR)) {
        vecR = ErrorReturnObj(
            "AddRowVector: vector lengths differ <left> %d,  <right> %d",
            (Int)len, (Int)LEN_PLIST(vecR),
            "you can replace vector <right> via 'return <right>;'");
        return CALL_3ARGS(AddRowVectorOp, vecL, vecR, mult);
    }

    /* check the fields                                                    */
    fld = FLD_FFE(ELM_PLIST(vecL, 1));
    if (FLD_FFE(ELM_PLIST(vecR, 1)) != fld) {
        /* check the characteristic                                        */
        if (CHAR_FF(fld) == CHAR_FF(FLD_FFE(ELM_PLIST(vecR, 1))))
            return TRY_NEXT_METHOD;

        vecR = ErrorReturnObj(
            "AddRowVector: vectors have different fields",
            0L, 0L,
            "you can replace vector <right> via 'return <right>;'");
        return CALL_3ARGS(AddRowVectorOp, vecL, vecR, mult);
    }

    /* Now check the multiplier field */
    if (FLD_FFE(mult) != fld) {
        /* check the characteristic                                        */
        if (CHAR_FF(fld) != CHAR_FF(FLD_FFE(mult))) {
            mult = ErrorReturnObj(
                "AddRowVector: <multiplier> has different field",
                0L, 0L,
                "you can replace <multiplier> via 'return <multiplier>;'");
            return CALL_3ARGS(AddRowVectorOp, vecL, vecR, mult);
        }

        /* if the multiplier is over a non subfield then redispatch */
        if ((DEGR_FF(fld) % DegreeFFE(mult)) != 0)
            return TRY_NEXT_METHOD;

        /* otherwise it's a subfield, so promote it */
        valM = VAL_FFE(mult);
        if (valM != 0)
            valM = 1 + (valM - 1) * (SIZE_FF(fld) - 1) / (SIZE_FF(FLD_FFE(mult)) - 1);
    } else
        valM = VAL_FFE(mult);


    succ = SUCC_FF(fld);
    ptrL = ADDR_OBJ(vecL);
    ptrR = ADDR_OBJ(vecR);

    /* two versions of the loop to avoid multipling by 1 */
    if (valM == 1)
        for (i = 1; i <= len; i++) {
            valL = VAL_FFE(ptrL[i]);
            valR = VAL_FFE(ptrR[i]);
            valS = SUM_FFV(valL, valR, succ);
            ptrL[i] = NEW_FFE(fld, valS);
        }
    else
        for (i = 1; i <= len; i++) {
            valL = VAL_FFE(ptrL[i]);
            valR = VAL_FFE(ptrR[i]);
            valS = PROD_FFV(valR, valM, succ);
            valS = SUM_FFV(valL, valS, succ);
            ptrL[i] = NEW_FFE(fld, valS);
        }
    return (Obj) 0;
}
예제 #17
0
파일: vecffe.c 프로젝트: BlairArchibald/gap
Obj FuncMultRowVectorVecFFEs( Obj self, Obj vec, Obj mult )
{
    Obj *ptr;
    FFV  valM;
    FFV  valS;
    FFV  val;
    FF  fld;
    FFV *succ;
    UInt len;
    UInt xtype;
    UInt i;

    if (TNUM_OBJ(mult) != T_FFE)
        return TRY_NEXT_METHOD;

    if (VAL_FFE(mult) == 1)
        return (Obj) 0;

    xtype = KTNumPlist(vec, (Obj *) 0);
    if (xtype != T_PLIST_FFE &&
    xtype != T_PLIST_FFE + IMMUTABLE)
        return TRY_NEXT_METHOD;

    /* check the lengths                                                   */
    len = LEN_PLIST(vec);

    fld = FLD_FFE(ELM_PLIST(vec, 1));
    /* Now check the multiplier field */
    if (FLD_FFE(mult) != fld) {
        /* check the characteristic                                        */
        if (CHAR_FF(fld) != CHAR_FF(FLD_FFE(mult))) {
            mult = ErrorReturnObj(
                "MultRowVector: <multiplier> has different field",
                0L, 0L,
                "you can replace <multiplier> via 'return <multiplier>;'");
            return CALL_2ARGS(MultRowVectorOp, vec, mult);
        }

        /* if the multiplier is over a non subfield then redispatch */
        if ((DEGR_FF(fld) % DegreeFFE(mult)) != 0)
            return TRY_NEXT_METHOD;

        /* otherwise it's a subfield, so promote it */
        valM = VAL_FFE(mult);
        if (valM != 0)
            valM = 1 + (valM - 1) * (SIZE_FF(fld) - 1) / (SIZE_FF(FLD_FFE(mult)) - 1);
    } else
        valM = VAL_FFE(mult);


    succ = SUCC_FF(fld);
    ptr = ADDR_OBJ(vec);

    /* two versions of the loop to avoid multipling by 0 */
    if (valM == 0) {
        Obj z;
        z = NEW_FFE(fld, 0);
        for (i = 1; i <= len; i++) {
            ptr[i] = z;
        }
    } else
        for (i = 1; i <= len; i++) {
            val = VAL_FFE(ptr[i]);
            valS = PROD_FFV(val, valM, succ);
            ptr[i] = NEW_FFE(fld, valS);
        }
    return (Obj) 0;
}
/* Type object function for the polymake object */
Obj ExternalPolymakeObjectTypeFunc(Obj o) {
  return ADDR_OBJ(o)[0];
}
예제 #19
0
파일: vecffe.c 프로젝트: BlairArchibald/gap
/****************************************************************************
**
*F  ProdVectorMatrix(<vecL>,<vecR>) . . . .  product of a vector and a matrix
**
**  'ProdVectorMatrix' returns the product of the vector <vecL> and the matrix
**  <vecR>.  The product is the sum of the  rows  of <vecR>, each multiplied by
**  the corresponding entry of <vecL>.
**
**  'ProdVectorMatrix'  is an improved version of 'ProdListList',  which does
**  not  call 'PROD' and  also accumulates  the sum into  one  fixed  vector
**  instead of allocating a new for each product and sum.
*/
Obj             ProdVecFFEMatFFE (
				  Obj                 vecL,
				  Obj                 matR )
{
    Obj                 vecP;           /* handle of the product           */
    Obj *               ptrP;           /* pointer into the product        */
    FFV *               ptrV;           /* value pointer into the product  */
    FFV                 valP;           /* one value of the product        */
    FFV                 valL;           /* one value of the left operand   */
    Obj                 vecR;           /* one vector of the right operand */
    Obj *               ptrR;           /* pointer into the right vector   */
    FFV                 valR;           /* one value from the right vector */
    UInt                len;            /* length                          */
    UInt                col;            /* length of the rows in matR      */
    UInt                i, k;           /* loop variables                  */
    FF                  fld;            /* the common finite field         */
    FF *                succ;           /* the successor table             */

    /* check the lengths                                                   */
    len = LEN_PLIST(vecL);
    col = LEN_PLIST(ELM_PLIST(matR, 1));
    if (len != LEN_PLIST(matR)) {
        matR = ErrorReturnObj(
            "<vec>*<mat>: <vec> (%d) must have the same length as <mat> (%d)",
            (Int)len, (Int)col,
            "you can replace matrix <mat> via 'return <mat>;'");
        return PROD(vecL, matR);
    }

    /* check the fields                                                    */
    vecR = ELM_PLIST(matR, 1);
    fld = FLD_FFE(ELM_PLIST(vecL, 1));
    if (FLD_FFE(ELM_PLIST(vecR, 1)) != fld) {
        /* check the characteristic                                        */
        if (CHAR_FF(fld) == CHAR_FF(FLD_FFE(ELM_PLIST(vecR, 1))))
            return ProdListList(vecL, matR);

        matR = ErrorReturnObj(
            "<vec>*<mat>: <vec> and <mat> have different fields",
            0L, 0L,
            "you can replace matrix <mat> via 'return <mat>;'");
        return PROD(vecL, matR);
    }

    /* make the result list by multiplying the first entries               */
    vecP = ProdFFEVecFFE(ELM_PLIST(vecL, 1), vecR);

    /* to add we need the successor table                                  */
    succ = SUCC_FF(fld);

    /* convert vecP into a list of values                                  */
    /*N 5Jul1998 werner: This only works if sizeof(FFV) <= sizeof(Obj)     */
    /*N We have to be careful not to overwrite the length info             */
    ptrP = ADDR_OBJ(vecP);
    ptrV = ((FFV*)(ptrP + 1)) - 1;
    for (k = 1; k <= col; k++)
        ptrV[k] = VAL_FFE(ptrP[k]);

    /* loop over the other entries and multiply                            */
    for (i = 2; i <= len; i++) {
        valL = VAL_FFE(ELM_PLIST(vecL, i));
        vecR = ELM_PLIST(matR, i);
        ptrR = ADDR_OBJ(vecR);
        if (valL == (FFV)1) {
            for (k = 1; k <= col; k++) {
                valR = VAL_FFE(ptrR[k]);
                valP = ptrV[k];
                ptrV[k] = SUM_FFV(valP, valR, succ);
            }
        } else if (valL != (FFV)0) {
            for (k = 1; k <= col; k++) {
                valR = VAL_FFE(ptrR[k]);
                valR = PROD_FFV(valL, valR, succ);
                valP = ptrV[k];
                ptrV[k] = SUM_FFV(valP, valR, succ);
            }
        }
    }

    /* convert vecP back into a list of finite field elements              */
    /*N 5Jul1998 werner: This only works if sizeof(FFV) <= sizeof(Obj)     */
    /*N We have to be careful not to overwrite the length info             */
    for (k = col; k >= 1; k--)
        ptrP[k] = NEW_FFE(fld, ptrV[k]);

    /* return the result                                                   */
    return vecP;
}
예제 #20
0
Obj CollectPolycyc (
    Obj pcp,
    Obj list,
    Obj word )
{
    Int    ngens   = INT_INTOBJ( ADDR_OBJ(pcp)[ PC_NUMBER_OF_GENERATORS ] );
    Obj    commute = ADDR_OBJ(pcp)[ PC_COMMUTE ];

    Obj    gens    = ADDR_OBJ(pcp)[ PC_GENERATORS ];
    Obj    igens   = ADDR_OBJ(pcp)[ PC_INVERSES ];

    Obj    pow     = ADDR_OBJ(pcp)[ PC_POWERS ];
    Obj    ipow    = ADDR_OBJ(pcp)[ PC_INVERSEPOWERS ];
    Obj    exp     = ADDR_OBJ(pcp)[ PC_EXPONENTS ];

    Obj    wst  = ADDR_OBJ(pcp)[ PC_WORD_STACK ];
    Obj    west = ADDR_OBJ(pcp)[ PC_WORD_EXPONENT_STACK ];
    Obj    sst  = ADDR_OBJ(pcp)[ PC_SYLLABLE_STACK ];
    Obj    est  = ADDR_OBJ(pcp)[ PC_EXPONENT_STACK ];

    Obj    conj=0, iconj=0;   /*QQ initialize to please compiler */

    Int    st, bottom = INT_INTOBJ( ADDR_OBJ(pcp)[ PC_STACK_POINTER ] );

    Int    g, syl, h, hh;

    Obj    e, ee, ge, mge, we, s, t;
    Obj    w, x = (Obj)0, y = (Obj)0;


    if( LEN_PLIST(word) == 0 ) return (Obj)0;

    if( LEN_PLIST(list) < ngens ) {
        ErrorQuit( "vector too short", 0L, 0L );
        return (Obj)0;
    }
    if( LEN_PLIST(word) % 2 != 0 ) {
        ErrorQuit( "Length of word odd", 0L, 0L );
        return (Obj)0;
    }

    st = bottom;
    PUSH_STACK( word, INTOBJ_INT(1) );

    while( st > bottom ) {

      w   = ELM_PLIST( wst, st );
      syl = INT_INTOBJ( ELM_PLIST( sst, st ) );
      g   = INT_INTOBJ( ELM_PLIST( w, syl )  );

      if( st > bottom+1 && syl==1 && g == GET_COMMUTE(g) ) {
        /* Collect word^exponent in one go. */

        e = ELM_PLIST( west, st );

        /* Add in. */
        AddIn( list, w, e );

        /* Reduce. */
        for( h = g; h <= ngens; h++ ) {
          s = ELM_PLIST( list, h );
          if( IS_INT_ZERO( s ) ) continue;

          y = (Obj)0;
          if( (e = GET_EXPONENT( h )) != (Obj)0 ) {
              if( !LtInt( s, e ) ) {
                  t = ModInt( s, e );
                  SET_ELM_PLIST( list, h, t ); CHANGED_BAG( list );
                  if( (y = GET_POWER( h )) ) e = QuoInt( s, e );
              }
              else if( LtInt( s, INTOBJ_INT(0) ) ) {
                  t = ModInt( s, e );
                  SET_ELM_PLIST( list, h, t ); CHANGED_BAG( list );
              
                  if( (y = GET_IPOWER( h )) ) {
                      e = QuoInt( s, e );
                      if( !IS_INT_ZERO( t ) ) e = DiffInt( e, INTOBJ_INT(1) );
                      e = AInvInt(e);
                  }
              }
          }
          if( y != (Obj)0 ) AddIn( list, y, e );

        }

        st--;

      }
      else {
        if( g == GET_COMMUTE( g ) ) {
          s = ELM_PLIST( list, g ); 
          t = ELM_PLIST( est, st ); 
          C_SUM_FIA( ge, s, t );
          SET_ELM_PLIST( est, st, INTOBJ_INT(0) );
        }
        else {
          /* Assume that the top of the exponent stack is non-zero. */
          e = ELM_PLIST( est, st );
          
          if( LtInt( INTOBJ_INT(0), e ) ) {
            C_DIFF_FIA( ee, e, INTOBJ_INT(1) );  e = ee;
            SET_ELM_PLIST( est, st, e );
            conj  = ADDR_OBJ(pcp)[PC_CONJUGATES];
            iconj = ADDR_OBJ(pcp)[PC_INVERSECONJUGATES];
            
            C_SUM_FIA( ge, ELM_PLIST( list, g ), INTOBJ_INT(1) );
          }
          else {
            C_SUM_FIA( ee, e, INTOBJ_INT(1) );  e = ee;
            SET_ELM_PLIST( est, st, e );
            conj  = ADDR_OBJ(pcp)[PC_CONJUGATESINVERSE];
            iconj = ADDR_OBJ(pcp)[PC_INVERSECONJUGATESINVERSE];
            
            C_DIFF_FIA( ge, ELM_PLIST( list, g ), INTOBJ_INT(1) );
          }
        }
        SET_ELM_PLIST( list, g, ge );  CHANGED_BAG( list );


        /* Reduce the exponent.  We delay putting the power onto the 
           stack until all the conjugates are on the stack.  The power is
           stored in  y, its exponent in ge.  */
        y = (Obj)0;
        if( (e = GET_EXPONENT( g )) ) {
            if( !LtInt( ge, e ) ) {
                mge = ModInt( ge, e );
                SET_ELM_PLIST( list, g, mge ); CHANGED_BAG( list );
            
                if( (y = GET_POWER( g )) ) ge = QuoInt( ge, e );
            }
            else if( LtInt( ge, INTOBJ_INT(0) ) ) {
                mge = ModInt( ge, e );
                SET_ELM_PLIST( list, g, mge ); CHANGED_BAG( list );
            
                if( (y = GET_IPOWER( g )) ) {
                    ge = QuoInt( ge, e );
                    if( !IS_INT_ZERO( mge ) ) 
                        ge = DiffInt( ge, INTOBJ_INT(1) );
                    ge = AInvInt(ge);
                }
            }
        }
        
        hh = h = GET_COMMUTE( g );
        
        /* Find the place where we start to collect. */
        for( ; h > g; h-- ) {
            e = ELM_PLIST( list, h );
            if( !IS_INT_ZERO(e) ) {
            
                if( LtInt( INTOBJ_INT(0), e ) ) {
                    if( GET_CONJ( h, g ) ) break;
                }
                else {
                    if( GET_ICONJ( h, g ) ) break;
                }
            }
        }

        /* Put those onto the stack, if necessary. */
        if( h > g || y != (Obj)0 ) 
          for( ; hh > h; hh-- ) {
            e = ELM_PLIST( list, hh );
            if( !IS_INT_ZERO(e) ) {
              SET_ELM_PLIST( list, hh, INTOBJ_INT(0) );
              
              if( LtInt( INTOBJ_INT(0), e ) ) {
                  x = ELM_PLIST(  gens, hh );
              }
              else {
                  x = ELM_PLIST( igens, hh );
                  C_PROD_FIA( ee, e, INTOBJ_INT(-1) );  e = ee;
              }
              
              PUSH_STACK( x, e );
            }
          }
        
        
        for( ; h > g; h-- ) {
          e = ELM_PLIST( list, h );
          if( !IS_INT_ZERO(e) ) {
            SET_ELM_PLIST( list, h, INTOBJ_INT(0) );
            
            x = (Obj)0;
            if( LtInt( INTOBJ_INT(0), e ) ) x = GET_CONJ( h, g );
            else                            x = GET_ICONJ( h, g );
            
            if( x == (Obj)0 )  {
              if( LtInt( INTOBJ_INT(0), e ) ) x = ELM_PLIST(  gens, h );
              else                            x = ELM_PLIST( igens, h );
            
            }
            if( LtInt( e, INTOBJ_INT(0) ) ) {
              C_PROD_FIA( ee, e, INTOBJ_INT(-1) );  e = ee;
            }
            PUSH_STACK( x, e );
          }
        }
        
        if( y != (Obj)0 ) PUSH_STACK( y, ge );
      }

      while( st > bottom && IS_INT_ZERO( ELM_PLIST( est, st ) ) ) {
        w   = ELM_PLIST( wst, st );
        syl = INT_INTOBJ( ELM_PLIST( sst, st ) ) + 2;
        if( syl > LEN_PLIST( w ) ) {
          we = DiffInt( ELM_PLIST( west, st ), INTOBJ_INT(1) );
          if( EqInt( we, INTOBJ_INT(0) ) ) { st--; }
          else {
            SET_ELM_PLIST( west, st, we );
            SET_ELM_PLIST( sst,  st, INTOBJ_INT(1) );
            SET_ELM_PLIST( est,  st, ELM_PLIST( w, 2 ) );
            CHANGED_BAG( west ); CHANGED_BAG( est );
          }
        }
        else {
          SET_ELM_PLIST( sst, st, INTOBJ_INT(syl) );
          SET_ELM_PLIST( est, st, ELM_PLIST( w, syl+1 ));
          CHANGED_BAG( est );
        }
      }
    }

    ADDR_OBJ(pcp)[ PC_STACK_POINTER ] = INTOBJ_INT( bottom );
    return (Obj)0;
}