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

📄 cyclo.c

📁 calc大数库
💻 C
字号:
/* cyclo.c */

#include <stdio.h>
#include <stdlib.h>
#include "integer.h"
#include "fun.h"
#define S0 65536

void NEXTPHI(USL p, USL *gptr, MPIA *b, MPIA *coef)
{
	USL cycle, grad, t, lastgrad;
        int i, j, next;
	MPI *l, *ZERO, *TEMP, *w;

	ZERO = ZEROI();
	cycle=p;
	grad = *gptr;
	next=grad;
	
	for(i=grad; i>=0; i--){
		  if(cycle==p)
		  {
		    cycle=1;
		    TEMP = COPYI(((*coef)->A)[next]);
		    ADD_TO_MPIA(*b, TEMP, i);
		    FREEMPI(TEMP);
		    next=next-1;
		  }else{
		    cycle++;
		    ADD_TO_MPIA(*b, ZERO, i);
		  }
	}
	lastgrad=grad;
	grad=grad*(p-1);

	t=grad/2;
	for(i=grad; i>=t; i--){
		  /* PHI = PHI(x^p)/PHI.  First half of the coefficients. */
		  l = COPYI(((*b)->A)[lastgrad]);
		  ADD_TO_MPIA(*coef, l, i);
		  for(j=lastgrad-1; j>=0; j--)
		  {
		    w = MULTI(l, ((*coef)->A)[j]);
		    TEMP = SUBI(((*b)->A)[j], w);
		    FREEMPI(w);
		    ADD_TO_MPIA(*b, TEMP, j+1);
		    FREEMPI(TEMP);
		  }
		  FREEMPI(l);
		  if(cycle==p)
		  {
		    cycle=1;
		    TEMP = COPYI(((*coef)->A)[next]);
		    ADD_TO_MPIA(*b, TEMP, 0);
		    FREEMPI(TEMP);
	/*	    next--;*/ /*commented out by KRM on 1h26/9/02 */
		  }
		  else
		  {
		    cycle++;
		    ADD_TO_MPIA(*b, ZERO, 0);
		  }
	}
	FREEMPI(ZERO);

	t=grad/2 - 1;
	for(j = 0; j <= t; j++){
            TEMP=COPYI(((*coef)->A)[grad-j]);
            ADD_TO_MPIA(*coef, TEMP, j);
            FREEMPI(TEMP);
	}
	*gptr = grad;
}

int NOTYET(USL n, USL i, USL *qptr)
{
	USL q;

	q = n / i;
	*qptr = q;
	if ((n > q * i) && (i <= q))
		return 1;
	else
		return 0;
}

int LPF(USL n)
{
	USL c, i, q;

	if (n % 2 == 0) return (2);
	if (n % 3 == 0) return (3);
	else
	{
		i = 5;
		c = 0;
		while (NOTYET(n, i, &q))
		{
			i = (c == 0) ? i + 2 : i + 4;
			c = 1 - c;
		}
		if (q < i)
			return (n);
		else
			return (i);	
	}
}

POLYI CYCLOTOMIC(MPI *N)
/* This algorithm is from Heinz Luneburg's book Galoisfelder, Kreisteilungs
 * korper and Schieberegisterfolgen. It was originally coded in CMAT by perhaps Peter Adams.
 * I imported the code to CALC on 25-26 Seotember 2002, tightening up the code.
 */

{
	USL n, n1, socn, p, grad;
	int i;
	POLYI P;
	MPI *H, *TEMP, *MINUSONE, *ONE, *ZERO;
	MPIA b, coef;

	if(N->D){
		printf("N >= 65536\n");
		return (POLYI)NULL;
	}
	MINUSONE = MINUS_ONEI();
	ONE = ONEI();
	ZERO = ZEROI();

	n = CONVERTI(N);
	b = BUILDMPIA();
        coef = BUILDMPIA();
	n1 = n;
	if (n1 == 1)
	{
		grad = 1;
		ADD_TO_MPIA(coef, MINUSONE, 0);
		ADD_TO_MPIA(coef, ONE, 1);
	}
	else
	{
		p = LPF(n1);
		socn = p;
		while (n1 % p == 0)
			n1 = n1 / p;
		grad = p - 1;
		for (i = 0; i <= grad; i++){
			ADD_TO_MPIA(coef, ONE, i);
		}
		/* PHI is the pth cyclotomic polynomial. */
			
		while (n1 > 1)
		{
			p = LPF(n1);
			socn = socn * p;
			while (n1 % p == 0)
				n1 = n1 / p;
			NEXTPHI(p, &grad, &b, &coef);
		/* PHI is the socnth cyclotomic polynomial. */		
		}
		n1 = n / socn;
		if (n1 > 1)
		{
		/* PHI = PHI(x^n). */
			grad = n1 * grad;
			for (i = grad; i >= 0; i--)
			{
				if (i % n1 == 0){
					TEMP = COPYI((coef->A)[i/n1]);
					ADD_TO_MPIA(coef, TEMP, i);
					FREEMPI(TEMP);
				}
				else{
					ADD_TO_MPIA(coef, ZERO, i);
				}
			}
		}	
	}
	FREEMPIA(b);
	P = NULL;
	for (i = 0; i <= grad; i++)
	{
		if (((coef->A)[i])->S)
		{
			H = COPYI((coef->A)[i]);
			PINSERTPI((int)i, H, &P, 0);
			FREEMPI(H);
		}
	}
	FREEMPIA(coef);
	FREEMPI(MINUSONE);
	FREEMPI(ONE);
	FREEMPI(ZERO);
	return (P);
}

⌨️ 快捷键说明

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