⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pi.c

📁 calc大数库
💻 C
📖 第 1 页 / 共 2 页
字号:
				Cptr = GCD(Cptr, (CURSOR->NEXT)->COEF);
				FREEMPI(TempI);
				CURSOR = CURSOR->NEXT;
			}
			while (CURSOR->NEXT != NULL);
		}
		return (Cptr);
	}
}

MPI *CONTENTPI2(POLYI Pptr)
/* Returns content of Pptr such that content(Pptr)*primitive(Pptr) = Pptr */
{
  MPI *C, *C2, *L, *Z=ZEROI();
  C = CONTENTPI(Pptr);
  L=LEADPI(Pptr);
  if (COMPAREI(L,Z) < 0 && COMPAREI(C,Z) > 0) {
    C2 = MINUSI(C);
    FREEMPI(C);
    FREEMPI(L);
    FREEMPI(Z);
    return C2;
  } else {
    FREEMPI(L);
    FREEMPI(Z);
    return C;
  }
}
    
    
POLYI PRIMITIVEPI(POLYI Pptr)
/*
 * returns the primitive part of the polynomial Pptr.
 * leading coefficient is positive.
 */
{
	POLYI Tmp, Sptr, CURSOR;
	MPI *C, *TempI;

	if (Pptr == NULL)
		return (NULL);
	else
	{
		Sptr = COPYPI(Pptr);
		C = CONTENTPI(Sptr);
		if ((Sptr->COEF)->S == -1)
		{
			Tmp = Sptr;
			TempI = MINUS_ONEI();
			Sptr = SCALARPI(TempI, Tmp);
			FREEMPI(TempI);
			DELETEPI(Tmp);
		}
		CURSOR = Sptr;
		while (CURSOR != NULL)
		{
			TempI = CURSOR->COEF;
			CURSOR->COEF = INT(CURSOR->COEF, C);
			FREEMPI(TempI);
			CURSOR = CURSOR->NEXT;
		}
		FREEMPI(C);
		return (Sptr);
	}
}

POLYI GCDPI(POLYI Pptr, POLYI Qptr)
/*
 * returns the gcd of polynomials Pptr and Qptr.
 * see Knuth, Vol 2, p.403-408 and H. Flanders, Scientific Pascal, p.510.
 */
{
	POLYI Ptmp, Qtmp, Rtmp, Sptr;
	MPI *D, *P, *Q, *TempI;
	int j;
	
	if (Qptr == NULL)
	{
		if (Pptr == NULL)
			return (NULL);
		else
			return (COPYPI(Pptr));
	}
	if (Pptr == NULL)
	{
		if (Qptr == NULL)
			return (NULL);
		else
			return (COPYPI(Qptr));
	}
	P = CONTENTPI(Pptr);
	Q = CONTENTPI(Qptr);
	D = GCD(P, Q);
	FREEMPI(P);
	FREEMPI(Q);
	Ptmp = PRIMITIVEPI(Pptr);
	Qtmp = PRIMITIVEPI(Qptr);
        j = DEGREEPI(Qtmp);
	while ((Qtmp != NULL) && ((j = DEGREEPI(Qtmp)) != 0))
	{
		Rtmp =	MODPI(Ptmp, Qtmp);
		DELETEPI(Ptmp);
		Ptmp = Qtmp;
		Qtmp = PRIMITIVEPI(Rtmp);
		DELETEPI(Rtmp);
	}
	if (j == 0)
	{
		TempI = Qtmp->COEF;
		Qtmp->COEF = ONEI();
		FREEMPI(TempI);
	}
	else/* Qtmp = NULL*/
		Qtmp = COPYPI(Ptmp);
	Sptr = SCALARPI(D, Qtmp);
	FREEMPI(D);
	DELETEPI(Ptmp);
	DELETEPI(Qtmp);
	return (Sptr);
}

POLYI DERIVPI(POLYI Pptr)
/*
 * returns the derivative of a polynomial.
 */
{
	POLYI CURSOR, Sptr;
	MPI *TempI;

	if (DEGREEPI(Pptr) == 0)
		return (NULL);
	else
	{
		Sptr = COPYPI(Pptr);
  		CURSOR = Sptr;
		while (CURSOR != NULL)
		{
			TempI = CURSOR->COEF;
			CURSOR->COEF = MULT_I(CURSOR->COEF, CURSOR->DEG);
			FREEMPI(TempI);
			CURSOR->DEG = CURSOR->DEG - 1;
			if (CURSOR->NEXT == NULL)
				break;
			else if ((CURSOR->NEXT)->DEG == 0)
			{
				DELETEPI(CURSOR->NEXT);
				CURSOR->NEXT = NULL;
				break;
			}
			else
				CURSOR = CURSOR->NEXT;
		}
		return (Sptr);
	}
}

POLYI *SQUAREFREEPI(POLYI Pptr, USI **D, USI *tptr)
/*
 * returns the "squarefree decomposition" of Pptr, a non-constant polynomial:
 * Pptr = G[0]^D[0]...G[*tpr - 1]^D[*tptr - 1],
 * where G[i] is squarefree and is the product of the irreducible factors of
 * multiplicity D[i]. See L. Childs, Introduction to Higher Algebra, p.159.
 */
{
	POLYI Ttmp, Ttmp1, Dtmp, Ftmp, Gtmp, Htmp, Ptmp, *G;
	unsigned int i = 1, j = 0, n;

	n = (unsigned int)(Pptr->DEG);
	Ptmp = PRIMITIVEPI(Pptr);
	Ftmp = DERIVPI(Ptmp);
	Dtmp = GCDPI(Ptmp, Ftmp);
	G = (POLYI *)mmalloc(n * sizeof(POLYI));
	*D = (unsigned int *)mmalloc(n * sizeof(unsigned int));
	if (DEGREEPI(Dtmp) == 0)
	{
		G[j] = Ptmp;
		(*D)[j] = i;
		j++;
		DELETEPI(Ftmp);
		DELETEPI(Dtmp);
		*tptr = j;
		return (G);
	}
	else
	{
		Gtmp = DIVPI(Ptmp, Dtmp);
		while (DEGREEPI(Dtmp))
		{
			DELETEPI(Ptmp);
			DELETEPI(Ftmp);
			Htmp = Gtmp;
			Ptmp = Dtmp;
			Ftmp = DERIVPI(Ptmp);
			Dtmp = GCDPI(Ptmp, Ftmp);
			Gtmp = DIVPI(Ptmp, Dtmp);
			Ttmp = DIVPI(Htmp, Gtmp);
			DELETEPI(Htmp);
			Ttmp1 = PRIMITIVEPI(Ttmp);
			if (Ttmp1->DEG > 0)
			{
				G[j] = COPYPI(Ttmp1);
				(*D)[j] = i;
				j++;
			}
			DELETEPI(Ttmp);
			DELETEPI(Ttmp1);
			i++;
		}
		DELETEPI(Ptmp);
		DELETEPI(Ftmp);
		G[j] = PRIMITIVEPI(Gtmp);
		(*D)[j] = i;
		j++;
		DELETEPI(Gtmp);
		DELETEPI(Dtmp);
		*tptr = j;
		return (G);
	}
}

POLYI POWERPI(POLYI Pptr, USI n)
/*
 * returns Pptr ^ n, where 0 <= n < R0 * R0.
 */
{
	POLYI B, Eptr, Tmp;

	Eptr = ONEPI();
	if (n == 0)
		return (Eptr);
	B = COPYPI(Pptr);
	while (1)
        {
		if (n & 1) 
		{
			Tmp = Eptr;
			Eptr = MULTPI(Tmp, B);
			DELETEPI(Tmp);
			if (n == 1)
			{
				DELETEPI(B);
				return (Eptr);
			}
		}
		Tmp = B;
		B = MULTPI(Tmp, Tmp);
		DELETEPI(Tmp);
		n = n >> 1;
	}
}

POLYI ONEPI()
/*
 * returns the constant polynomial 1.
 */
{
	POLYI Pptr;

	Pptr = CREATEPI();
	Pptr->DEG = 0;
	Pptr->COEF = ONEI();
	Pptr->NEXT = NULL;
	return (Pptr);
}
POLYI ZEROPI()
     /* returns the zero polynomial */
{
  POLYI Pptr;
  Pptr= CREATEPI();
  Pptr->DEG=0;
  Pptr->COEF=ZEROI();
  Pptr->NEXT=NULL;
  return (Pptr);
}
POLYI CONSTANTPI(MPI *Aptr)
/*
 * returns the constant polynomial whose constant term is *Aptr.
 */
{
	POLYI Pptr;	

	if (Aptr->S == 0)
		return (NULL);
	else
	{
		Pptr = CREATEPI();
		Pptr->DEG = 0;
		Pptr->COEF = COPYI(Aptr);
		Pptr->NEXT = NULL;
		return (Pptr);
	}
}

MPI *SUBRESULTANT(POLYI Pptr, POLYI Qptr)
/*
 * *Aptr is the resultant of Pptr and Qptr, found using the subresultant
 * algorithm, p. 130. E. Kaltofen, G. E. Collins etc, Algorithm 4.5.
 * similar to Knuth, Algorithm C, p. 410.
 */
{
	unsigned delta;
	MPI *G, *G1, *H1, *H2, *Aptr, *TempI;
	POLYI Utmp, Vtmp, Rtmp, CURSOR;

	G = ONEI();
	Aptr = ONEI();
	Utmp = COPYPI(Pptr);
	Vtmp = COPYPI(Qptr);
	while (Vtmp != NULL)
	{
		Rtmp = MODPI(Utmp, Vtmp);
		if (Rtmp == NULL && DEGREEPI(Vtmp) > 0)
		{
			FREEMPI(G);
			FREEMPI(Aptr);
			DELETEPI(Utmp);
			DELETEPI(Vtmp);
			return (ZEROI());
		}
		delta = DEGREEPI(Utmp) - DEGREEPI(Vtmp);
		DELETEPI(Utmp);
		Utmp = Vtmp;
		G1 = MINUSI(G);
		H1 = MINUSI(Aptr);
		TempI = H1;
		H1 = POWERI(H1, delta);
		FREEMPI(TempI);
		TempI = H1;
		H1 = MULTI(H1, G1);
		FREEMPI(TempI);
		CURSOR = Rtmp;
		while (CURSOR != NULL)
		{
			TempI = CURSOR->COEF;
			CURSOR->COEF = INTI(CURSOR->COEF, H1);
			FREEMPI(TempI);
			CURSOR = CURSOR->NEXT;
		}
		Vtmp = Rtmp;
		TempI = G;
		G = LEADPI(Utmp);
		FREEMPI(TempI);
		TempI = G1;
		G1 = POWERI(G, delta);
		FREEMPI(TempI);
		TempI = H1;
		H1 = MULTI(Aptr, G1);
		FREEMPI(TempI);
		H2 = POWERI(Aptr, delta);
		TempI = Aptr;
		Aptr = INTI(H1, H2);
		FREEMPI(TempI);
		FREEMPI(H1);
		FREEMPI(H2);
		FREEMPI(G1);
	}
	DELETEPI(Utmp);
	FREEMPI(G);
	return (Aptr);
}

MPI *DISCRIMINANTPI(POLYI Pptr)
/*
 * *Dptr = Discriminant of Pptr = (1/a[n])*(-1)^{n*(n-1)/2 * Res(Pptr, Pptr').
 * See O. Perron, Algebra, Vol 1, p.212.
 */
{
	POLYI P;
	MPI *A, *Dptr, *TempI;
	int n;

	P = DERIVPI(Pptr);
	Dptr = SUBRESULTANT(Pptr, P);
	A = LEADPI(Pptr);
	TempI = Dptr;
	Dptr = INTI(Dptr, A);
	FREEMPI(TempI);
	FREEMPI(A);
	DELETEPI(P);
	n = (DEGREEPI(Pptr)) % 4;
	if (n == 2 || n == 3)
		Dptr->S = -(Dptr->S);
	return (Dptr);
}

MPI *LENGTHSQPI(POLYI Pptr)
/*
 * *Cptr is the sum of the squares of the coefficients of Pptr.
 */
{
	POLYI CURSOR;
	MPI *C, *Cptr, *TempI;

	Cptr = ZEROI();
	if (Pptr == NULL)
		return (Cptr);
	CURSOR = Pptr;
	while (CURSOR != NULL)
	{
		C = MULTI(CURSOR->COEF, CURSOR->COEF);
		TempI =  Cptr;
		Cptr = ADDI(C, Cptr);
		FREEMPI(C);
		FREEMPI(TempI);
		CURSOR = CURSOR->NEXT;
	}
	return (Cptr);
}

MPI *VAL0PI(POLYI Pptr)
/*
 * *Mptr = Pptr(0)
 */
{
	POLYI CURSOR;

	if (Pptr == NULL)
		return ZEROI();
	CURSOR = Pptr;
	while (CURSOR->NEXT != NULL)
		CURSOR = CURSOR->NEXT;
	if (DEGREEPI(CURSOR) != 0)
		return ZEROI();
	else
		return COPYI(CURSOR->COEF);	
}

/* Returns respectively positive, or negative if the sign of the polynomial 
 * evaluated at the supplied rational number is positive or negative.
 * Returns zero if polynomial has a root at the supplied rational */
int SIGN_AT_R_PI(POLYI P, MPR *R)
{
  MPI *TMPI, *RESULT=ZEROI(), *X_TO_I, *TERM;
  MPI *A=COPYI(R->N), *D=COPYI(R->D);
  POLYI CURSOR=P;
  unsigned int n=DEGREEPI(P), i;

  if (P == NULL) 
    i=0;
  else while (CURSOR) {
    i = DEGREEPI(CURSOR);
    TERM=POWERI(A, i);
    
    TMPI=TERM;
    TERM=MULTI(CURSOR->COEF, TERM);
    FREEMPI(TMPI);
    
    X_TO_I=POWERI(D, n-i);
    
    TMPI=TERM;
    TERM=MULTI(TERM, X_TO_I);
    FREEMPI(TMPI);
    FREEMPI(X_TO_I);

    TMPI=RESULT;
    RESULT=ADDI(RESULT, TERM);
    FREEMPI(TMPI);
    FREEMPI(TERM);

    CURSOR=CURSOR->NEXT;
  }
  i = SIGNI(RESULT); /* shouldn't really use this as return val but it works */
  FREEMPI(RESULT);
  FREEMPI(A);
  FREEMPI(D);
  return i;
}

/* If P = p(x) then this function returns p(-x) */
POLYI P_OF_NEG_X(POLYI P)
{
  POLYI Q=COPYPI(P);
  POLYI CURSOR=Q;
  while (CURSOR) {
    if (DEGREEPI(CURSOR)%2 == 1) /* if odd degree */
      CURSOR->COEF->S = - CURSOR->COEF->S;
    CURSOR=CURSOR->NEXT;
  }
  return Q;
}

/* Returns -1*P(x) */
POLYI MINUSPI(POLYI P)
{
  POLYI Q=COPYPI(P);
  POLYI CURSOR=Q;
  while (CURSOR) {
    CURSOR->COEF->S = -CURSOR->COEF->S;
    CURSOR=CURSOR->NEXT;
  }
  return Q;
}

/* Modifies the supplied polynomial so that p(x) = p(x+A) */

void P_OF_X_PLUS(POLYI *P, MPI *A)
{
  MPI *ZERO = ZEROI();
  MPIA COEF = BUILDMPIA();
  POLYI CURSOR = *P;
  int i, j,  n = DEGREEPI(*P);

  for (i=n; i >=0; i--) {
	ADD_TO_MPIA(COEF, ZERO, i);
  }
  while (CURSOR) {
    ADD_TO_MPIA(COEF, CURSOR->COEF, DEGREEPI(CURSOR));
    CURSOR=CURSOR->NEXT;
  }

  for (i=0; i <= n-1; i++)
    for (j = n-1;j >= i; j--) {
      MPI *TMP, *MUL;
      MUL = MULTI(A, COEF->A[j+1]);
      TMP = COEF->A[j];
      COEF->A[j] = ADDI(MUL, COEF->A[j]);
      FREEMPI(TMP);
      FREEMPI(MUL);
    }
  
  DELETEPI(*P);
  *P = NULL;
  for (i=0; i <= n; i++)
    PINSERTPI(i, COEF->A[i], P, 0);
  PURGEPI(P);
  FREEMPIA(COEF);
  FREEMPI(ZERO);
}
    
POLYI PRIMITIVEPI_(POLYI Pptr)
/*
 * returns the primitive part of the polynomial Pptr.
 * retaining the sign of the leading coefficient.
 */
{
	POLYI Sptr, CURSOR;
	MPI *C, *TempI;

	if (Pptr == NULL)
		return (NULL);
	else
	{
		Sptr = COPYPI(Pptr);
		C = CONTENTPI(Sptr);
		CURSOR = Sptr;
		while (CURSOR != NULL)
		{
			TempI = CURSOR->COEF;
			CURSOR->COEF = INT(CURSOR->COEF, C);
			FREEMPI(TempI);
			CURSOR = CURSOR->NEXT;
		}
		FREEMPI(C);
		return (Sptr);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -