예제 #1
0
파일: berlekmp.c 프로젝트: momtx/meataxe
static Matrix_t *makekernel(const Poly_t *pol)
{
    Matrix_t *materg;
    PTR rowptr;
    FEL *xbuf, *pbuf = pol->Data;
    long pdeg = pol->Degree;
    int k, xshift;
    long fl = pol->Field;

    materg = MatAlloc(fl,pdeg,pdeg);
    rowptr = materg->Data;

    xbuf = NALLOC(FEL,pdeg+1);
    for (k = 0; k <= pdeg; ++k) 
	xbuf[k] = FF_ZERO;
    xbuf[0] = FF_ONE;

    for (k = 0; k < pdeg; ++k)
    {
	int l;
	for (l = 0; l < pdeg; ++l) 
	    FfInsert(rowptr,l,xbuf[l]);
	FfInsert(rowptr,k,FfSub(xbuf[k],FF_ONE));
	FfStepPtr(&rowptr);
        for (xshift = (int) fl; xshift > 0; )
	{
	    FEL f;
	    int d;

	    /* Find leading pos */
	    for (l = pdeg-1; xbuf[l] == FF_ZERO && l >= 0; --l);

	    /* Shift left as much as possible */
	    if ((d = pdeg - l) > xshift) d = xshift;
	    for (; l >= 0; l--) xbuf[l+d] = xbuf[l];
	    for (l = d-1; l >= 0; --l) xbuf[l] = FF_ZERO;
	    xshift -= d;
	    if (xbuf[pdeg] == FF_ZERO) continue;

	    /* Reduce with pol */
	    f = FfNeg(FfDiv(xbuf[pdeg],pbuf[pdeg]));
	    for (l = pdeg-1; l >= 0; --l)
		xbuf[l] = FfAdd(xbuf[l],FfMul(pbuf[l],f));
	    xbuf[pdeg] = FF_ZERO;
	}
    }
    SysFree(xbuf);
    return MatNullSpace__(materg);
 } 
예제 #2
0
파일: kernel-1.c 프로젝트: momtx/meataxe
int FfSetField(int field)
{
   static char filename[50];
   FILE *fd;
   unsigned short info[5];

   if (field != FfOrder)
   {
       Ff1MakeTables(field);

      sprintf(filename,"p%5.5d.zzz",field);
      if ((fd = SysFopen(filename,FM_READ|FM_LIB)) == NULL ||
	    fread((char *)info,sizeof(short),5,fd) != 5)
      {	perror(filename);
	 MTX_ERROR("Error opening table file");
	 return -1;
      }
      P = info[1];
      Q = info[2];
      N = info[3];
      Q1 = Q - 1;
      Gen = info[4];
      FfOrder = (long) Q;
      FfChar = (long) P;
      if (Q == 2) FfGen = 0; else FfGen = 1;
      if ((info[0]) != ZZZVERSION || N >= MAXPWR || Q < 2 || P < 2 || P > Q || Q % P != 0) {
	 MTX_ERROR("ERROR IN TABLE FILE HEADER");
	 return -1;
      }
      if (inc != NULL) free(inc);
      inc = NALLOC(FEL,Q-1);
      if (
	    fread(poly,sizeof(short),(size_t) N+1,fd) != (size_t)N+1 ||
	    fread(ppwr,sizeof(short),(size_t) N,fd) != (size_t)N ||
	    fread(ppindex,sizeof(short),(size_t) N,fd) != (size_t)N ||
	    fread(&minusone,sizeof(short),1,fd) != 1 ||
	    fread(inc,sizeof(short),(size_t)(Q-1),fd) != (int) Q-1
	 )
      {	perror(filename);
	 exit(EXIT_ERR);
      }
      if (poly[N] != 1) MTX_ERROR("ERROR IN TABLE FILE");
      fclose(fd);
   }
   return 0;
}
예제 #3
0
파일: berlekmp.c 프로젝트: momtx/meataxe
static factor_t *factorsquarefree(const Poly_t *pol)
{
    long int e,j,k,ltmp,tdeg,exp;
    Poly_t *t0, *t, *w, *v;
    FEL *tbuf, *t0buf;
    factor_t *list;
    int nfactors = 0;

    /* Initialize variables
       -------------------- */
    FfSetField(pol->Field);
    for (exp = 0, ltmp = FfOrder; ltmp % FfChar == 0; ++exp, ltmp /= FfChar);
    t0 = PolDup(pol);
    e = 1;

    /* Allocate the list of factors. The can be at most <pol->Degree>
       factors, but we need one extra entry to terminate the list.
       ----------------------------------------------------------- */
    list = NALLOC(factor_t,pol->Degree + 1);

    /* Main loop
       --------- */
    while (t0->Degree > 0)
    {
	Poly_t *der = PolDerive(PolDup(t0));
        t = PolGcd(t0,der);
	PolFree(der);
        v = PolDivMod(t0,t);
        PolFree(t0); 
        for (k = 0; v->Degree > 0; )
	{
	    Poly_t *tmp;
	    if ( ++k % FfChar == 0 )
	    {
		tmp = PolDivMod(t,v);
              	PolFree(t);
              	t = tmp;
	      	k++;
	    }
	    w = PolGcd(t,v);
	    list[nfactors].p = PolDivMod(v,w);
	    list[nfactors].n = e * k;
	    if (list[nfactors].p->Degree > 0)
	       	++nfactors;			/* add to output */
	    else
	    	PolFree(list[nfactors].p);	/* discard const. */
            PolFree(v);
	    v = w;
	    tmp = PolDivMod(t,v);
            PolFree(t); 
            t = tmp; 
	} 
	PolFree(v);

	/* shrink the polynomial */
      	tdeg = t->Degree;
      	e *= FfChar;
      	if ( tdeg % FfChar != 0 )
	    printf("error in t, degree not div. by prime \n");
      	t0 = PolAlloc(FfOrder,tdeg/FfChar);
      	t0buf = t0->Data;
      	tbuf = t->Data;
      	for (j = t0->Degree; j >= 0; --j)
	{
	    FEL el, el1;
	    long lexp;

	    el = *tbuf;
	    tbuf += FfChar;
	    el1 = el;
	    /* this is a bug, it should apply the e-1 power of the
	        frobenius K. Lux 16th 11 1996 */

	    /* replace el1 by el1^(FfChar^(exp-1)) */
	    for ( lexp = 0; lexp < exp-1; lexp++ )
	    {
		long n;
		/* replace el1 by el1^FfChar */
		el = el1;
		for ( n = FfChar-1;  0 < n;  n-- ) {
		    el1 = FfMul(el1,el);
		}
	    }
	    *t0buf = el1;
	    ++t0buf;
	}
        PolFree(t); 
    }
    PolFree(t0);

    /* Terminate the list
       ------------------ */
    list[nfactors].p = NULL;
    list[nfactors].n = 0;
    return list;
}
예제 #4
0
파일: tn.c 프로젝트: Brucegx/Appstore719
TNPtr*
tn_detachmany (TNPtr n, int len)
{
    /* Detaches the node n and its 'len -1' right siblings from the tree
     * by removing them from their parent node. In toto 'len' nodes are
     * removed. The sibling relationships are squashed as well, and the
     * index information for all right siblings is adjusted. The nodes
     * retain their children. After this function is called thes node
     * and their children are ready for tn_delete'. Or reinsertion in a
     * different place.
   *
   * The operation fails with a panic if there are less children we
   * can cut than requested. It also panics when trying to cut
   * nothing.
   *
   * Note: This function does not reset the parent reference in the
   * cut nodes.
   */

    TNPtr* ch;
    TNPtr  p   = n->parent;
    int	   at  = n->index;
    int	   end = at + len;

    ASSERT (end <= p->nchildren, "tn_detachmany - tried to cut too many children");
    ASSERT (len > 0,		 "tn_detachmany - tried to cut nothing");

    if ((at == 0) && (end == p->nchildren)) {
	/* All children are taken. There is no need to copy anything, we
	 * can use the whole array, and reset the other information in the
	 * parent. Note that the condition above implies 'at == 0'. The
	 * parent node becomes a leaf again.
	 */
    
	ch = p->child;

	p->child       = NULL;
	p->maxchildren = 0;
	p->nchildren   = 0;

	tn_leaf (p);

    } else {
	/* Copies the cut nodes into a result array. Shifts the right
     * siblings down, if there are any.
     */

	int i, k;

	ch = NALLOC (len, TNPtr);

    /* Examples. We always have nchildren = 10.
     *
     * _______________________________
     * at  = 2, len = 3.
     * 
     * 01 234 56789 i = 0, k = 2
     *	  012	    i = 3, k = 5
     *
     * 01 234 56789 i = 2, k = 5
     * 01 567 89    i = 7, k = 10
     *
     * _______________________________
     * at  = 7, len = 3.
     * 
     * 0123456 789 i = 0, k = 7
     *	       012 i = 3, k = 10
     *
     * 0123456 789 i = 7, k = 10
     * 0123456	   nothing
     *
     * _______________________________
     * at  = 6, len = 3.
     * 
     * 012345 678 9 i = 0, k = 6
     *	      012   i = 3, k = 9
     *
     * 012345 678 9 i = 6, k = 9
     * 012345 9	    i = 7, k = 10
     *
     * _______________________________
     * at  = 6, len = 1.
     * 
     * 012345 6 789 i = 0, k = 6
     *	      0	    i = 1, k = 7
     *
     * 012345 6 789 i = 6, k = 7
     * 012345 7 89  i = 9, k = 10
     */

	for (i = 0, k = at; i < len; i++, k++) {

	    ASSERT_BOUNDS (k, p->nchildren);
	    ASSERT_BOUNDS (i, len);

	    ch [i] = p->child [k];
	}

	for (i = at, k = end; k < p->nchildren; i++, k++) {

	    ASSERT_BOUNDS (k, p->nchildren);
	    ASSERT_BOUNDS (i, p->nchildren);

	    p->child [i] = p->child [k];
	    p->child [i]->index -= len;
	}

	p->nchildren -= len;

	if (ch [0]->left) {
	    ch [0]->left->right = ch [len-1]->right;
	}
	if (ch [len-1]->right) {
	    ch [len-1]->right->left = ch [0]->left;
	}

	ch [0]->left	  = NULL;
	ch [len-1]->right = NULL;
    }

    n->tree->structure = 0;
    return ch;
}