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

📄 lllgcd.c

📁 calc大数库
💻 C
📖 第 1 页 / 共 5 页
字号:
/* lllgcd.c */
#ifdef _WIN32
#include "unistd_DOS.h"
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "integer.h"
#include "fun.h"
extern MPI *MAXI, *PMAXI;

extern unsigned int MLLLVERBOSE;
extern unsigned int GCDVERBOSE;
USI GCD3FLAG;
extern unsigned int GCD_MAX;

MPMATI *LLLGCD(MPMATI *DD, MPI **Aptr, USI m, USI m1, USI n1)
/* 
 * Input: an m x 1 vector of positive MPI's.
 * Output: *Aptr = gcd of the vector of MPI's. Also we return a small set of
 * multipliers using the LLL method of Havas and Matthews.
 * Normally m1=1,n1=1.
 * matrix B of the LLL extended gcd algorithm of 
 * Havas-Majewski-Matthews is returned.
 * 30/1/97.
 */
{
	unsigned int i, k, l;
	MPI **A, **D, *X, *Y, *Z, *Tmp, *R, *M1, *N1;
	MPMATI *L, *B;

	B = IDENTITYI(m);
	A = (MPI **)mmalloc(m * sizeof(MPI *));
	for (i = 0; i < m; i++)
		A[i] = COPYI(DD->V[i][0]);
	D = (MPI **)mmalloc((1 + m) * sizeof(MPI *));
	for (i = 0; i <= m; i++)
		D[i] = ONEI();

	L = ZEROMNI(m, m);
	M1 = CHANGE(m1);
	N1 = CHANGE(n1);

	k = 2;
	while (k <= m)
	{
		REDUCE(k, k - 1, &L, &B, D, A);
		X = MULTI(D[k - 2], D[k]);
		Y = MULTI(D[k - 1], D[k - 1]);
		Tmp = Y;
		Y = MULTI(Y, M1);
		FREEMPI(Tmp);
		R = MULTI(L->V[k - 1][k - 2], L->V[k - 1][k - 2]);
		Z = ADD0I(X, R);
		FREEMPI(R);
		Tmp = Z;
		Z = MULTI(Z, N1);
		FREEMPI(Tmp);
		if (!EQZEROI(A[k-2]) || (EQZEROI(A[k-1]) && (RSV(Y, Z) == 1)))
		{
			for (i = k + 1; i <= m; i++)
				SWAP1(i, k, &L, D);
			SWAP2(k, &B, &L, A);
			FREEMPI(Y);
			Y = MULTI(L->V[k - 1][k - 2], L->V[k - 1][k - 2]);
			Tmp = Y;
			Y = ADD0I(Y, X);
			FREEMPI(X);
			FREEMPI(Tmp);
			Tmp = D[k - 1];
			D[k - 1] = INT0(Y, D[k - 1]);
			FREEMPI(Tmp);
			FREEMPI(Y);
			if (k > 2)
				k--;
		}
		else
		{ 
			FREEMPI(X);
			FREEMPI(Y);
			for (l = k - 2; l >= 1; l--)
				REDUCE(k, l, &L, &B, D, A);
			k++;
		}
		FREEMPI(Z);		
	}
	FREEMPI(M1);
	FREEMPI(N1);
	*Aptr = COPYI(A[m - 1]);
	if ((*Aptr)->S == -1)
	{	
		LLLGCDMINUS(&B, &L, m - 1);
		(*Aptr)->S = -((*Aptr)->S);
	}
/*
	if (GCDVERBOSE)
	{
		printf("L = \n");
		PRINTMATI(0,L->R-1,0,L->C-1,L);
		for (i = 0; i <= m; i++)
		{
			printf("D[%u] = ", i);PRINTI(D[i]);printf(", ");
		}
		printf("\n");
		temp1  = MULTI(D[1], D[1]);
		printf("a = "); PRINTI(temp1); printf(", ");
		FREEMPI(temp1);
		temp1 = MULTI(D[1], L->V[1][0]);
		temp2 = MULT_I(temp1, 2);
		printf("2h = "); PRINTI(temp2); printf(", ");
		FREEMPI(temp1);
		FREEMPI(temp2);
		temp1 = MULTI(L->V[1][0], L->V[1][0]);
		temp2 = ADD0I(D[2], temp1);
		printf("b = "); PRINTI(temp2); printf(", ");
		FREEMPI(temp1);
		FREEMPI(temp2);
		temp1 = MULTI(D[1], L->V[2][0]);
		temp2 = MULT_I(temp1, 2);
		printf("2g = "); PRINTI(temp2); printf(", ");
		FREEMPI(temp1);
		FREEMPI(temp2);
		temp1 = MULTI(L->V[1][0], L->V[2][0]);
		FREEMPI(temp1);
		temp2 = ADDI(temp1, L->V[2][1]);
		temp1 = MULT_I(temp2, 2);
		printf("2f = "); PRINTI(temp1); printf(", ");
		FREEMPI(temp1);
		FREEMPI(temp2);
	}
*/
/*
	printf("L = \n");
	PRINTMATI(0,L->R-1,0,L->C-1,L);
	for (i = 0; i <= m; i++)
	{
		printf("D[%u] = ", i);PRINTI(D[i]);printf(", ");
	}
	printf("\n");
*/
	FREEMATI(L);
	for (i = 0; i <= m; i++)
		FREEMPI(D[i]);
	for (i = 0; i < m; i++)
		FREEMPI(A[i]);
	ffree((char *)D, (1 + m) * sizeof(MPI *));
	ffree((char *)A, m * sizeof(MPI *));
	return (B);
}

void SWAP1(USI i, USI k, MPMATI **Lptr, MPI *D[])
{
	MPI *X1, *X2, *X3, *Y1, *Y2, *Tmp;

	X1 = MULTI((*Lptr)->V[i - 1][k - 2], (*Lptr)->V[k - 1][k - 2]);
	Y1 = MULTI((*Lptr)->V[i - 1][k - 1], D[k - 2]);
	Tmp = Y1;
	Y1 = ADDI(Y1, X1);
	FREEMPI(Tmp);
	FREEMPI(X1);
	X2 = MULTI((*Lptr)->V[i - 1][k - 2], D[k]);
	X3 = MINUSI((*Lptr)->V[k - 1][k - 2]);
	Y2 = MULTI((*Lptr)->V[i - 1][k - 1], X3);
	FREEMPI(X3);
	Tmp = Y2;
	Y2 = ADDI(Y2, X2);
	FREEMPI(Tmp);
	FREEMPI(X2);
	FREEMPI((*Lptr)->V[i - 1][k - 2]);
	(*Lptr)->V[i - 1][k - 2] = INT(Y1, D[k - 1]);
	FREEMPI((*Lptr)->V[i - 1][k - 1]);
	(*Lptr)->V[i - 1][k - 1] = INT(Y2, D[k - 1]);
	FREEMPI(Y1);
	FREEMPI(Y2);
	return;
}


void REDUCE(USI k, USI l, MPMATI **Lptr, MPMATI **Bptr, MPI *D[], MPI *A[])
/*
 * updates *Lptr, *Bptr.
 */
{
	unsigned int i, j, m, n;
	MPI *X, *Y, *Q, *Tmp, *Z;
	MPMATI *TmpMATI, *TempMAT;

	m = (*Bptr)->C;
	n = (*Bptr)->R;
	if (A[l - 1]->S)
	{
		Q = NEAREST_INTI(A[k - 1], A[l - 1]);
		if (Q->S)
		{
			Tmp = A[k - 1];
			Z = MULTI(A[l - 1], Q);
			A[k - 1] = SUBI(A[k - 1],Z);
			FREEMPI(Tmp);
			FREEMPI(Z);
		}
	}
	else
	{
		Y = MULT_I((*Lptr)->V[k - 1][l - 1], 2);
		if (RSV(Y, D[l]) == 1)
			Q = NEAREST_INTI((*Lptr)->V[k - 1][l - 1], D[l]);
		else
			Q = ZEROI();
		FREEMPI(Y);
	}
	if (Q->S == 0)
	{
		FREEMPI(Q);
		return;
	}
	X = MINUSI(Q);
	TmpMATI = *Bptr;
	*Bptr = ADD_MULT_ROWI(l - 1, k - 1, X, *Bptr);
	FREEMATI(TmpMATI);
	if (MLLLVERBOSE)
	{
		printf("Row %u -> Row %u + ", k,k);PRINTI(X);printf(" x Row %u\n", l);
		PRINTMATI(0,(*Bptr)->R-1,0,(*Bptr)->C-1,*Bptr);
	}
	if(GCDVERBOSE)
	{
		printf("Row %u -> Row %u + ", k,k);PRINTI(X);printf(" x Row %u\n", l);
		TempMAT = BUILDMATI(n, n + 1);
		for (i = 0; i < n; i++)
		{
			for (j = 0; j <= n; j++)
			{		
				if (j == n)
					TempMAT->V[i][j] = COPYI(A[i]);
				else
					TempMAT->V[i][j] = COPYI((*Bptr)->V[i][j]);
			}
		}
		PRINTMATI(0,TempMAT->R-1,0,TempMAT->C-1,TempMAT);
		printf("\n");
		FREEMATI(TempMAT);
	}

	FREEMPI(X);
	for (j = 1; j < l; j++)
	{
		X = MULTI((*Lptr)->V[l - 1][j - 1], Q);
		Tmp = (*Lptr)->V[k - 1][j - 1];
		(*Lptr)->V[k - 1][j - 1] = SUBI((*Lptr)->V[k - 1][j - 1], X);
		FREEMPI(Tmp);
		FREEMPI(X);
	}
	X = MULTI(D[l], Q);
	Tmp = (*Lptr)->V[k - 1][l - 1];
	(*Lptr)->V[k - 1][l - 1] = SUBI((*Lptr)->V[k - 1][l - 1], X);
	FREEMPI(Tmp);
	FREEMPI(X);
	FREEMPI(Q);
}


void SWAP2(USI k, MPMATI **B1ptr, MPMATI **Lptr, MPI *A[])
{
	MPI *T, *S;
	unsigned int i, j, n;
	MPMATI *TempMAT;

	n = (*B1ptr)->R;
	S = A[k - 2];
	A[k - 2] = A[k - 1];
	A[k - 1] = S;
	
	*B1ptr = SWAP_ROWSI1(k - 2, k - 1, *B1ptr);
	T = COPYI((*Lptr)->V[k - 1][k - 2]);
	*Lptr = SWAP_ROWSI1(k - 2, k - 1, *Lptr);
	FREEMPI((*Lptr)->V[k - 1][k - 2]);
	(*Lptr)->V[k - 1][k - 2] = T;
	FREEMPI((*Lptr)->V[k - 2][k - 2]);
	(*Lptr)->V[k - 2][k - 2] = ZEROI();
	if(GCDVERBOSE)
	{
		printf("Swapping Rows %u and %u\n", k-1,k);
		TempMAT = BUILDMATI(n, n + 1);
		for (i = 0; i < n; i++)
		{
			for (j = 0; j <= n; j++)
			{		
				if (j == n)
					TempMAT->V[i][j] = COPYI(A[i]);
				else
					TempMAT->V[i][j] = COPYI((*B1ptr)->V[i][j]);
			}
		}
		PRINTMATI(0,TempMAT->R-1,0,TempMAT->C-1,TempMAT);
		printf("\n");
		GetReturn();
		FREEMATI(TempMAT);
	}
	if (MLLLVERBOSE)
	{
		printf("Swapping Rows %u and %u\n", k-1,k);
		PRINTMATI(0,(*B1ptr)->R-1,0,(*B1ptr)->C-1,*B1ptr);
	}
	return;
}

MPMATI *JACOBIGCD(MPMATI *DD, MPI **Aptr, USI m)
/* 
 * Input: an m x 1 vector of positive MPI's.
 * Output: *Aptr = gcd of the vector of MPI's. Also we return a small set of
 * multipliers using a version of a method of Jacobi
 * A unimodular transforming matrix B is returned.
 * 31/1/97.
 */
{
	unsigned int i, z;
	int k;
	MPI **A, *Q, *X, *Tmp, **temp;
	MPMATI *L, *B;

	B = IDENTITYI(m);
	A = (MPI **)mmalloc(m * sizeof(MPI *));
	for (i = 0; i < m; i++)
		A[i] = COPYI(DD->V[i][0]);
	z = 0;
	while (1)
	{
 		/* A[i] = 0 for i = 0,...,z-1, but A[z] != 0. */
		for (i = z + 1; i < m; i++)
		{
			Q = INT0(A[i], A[z]);
			X = MINUSI(Q);
			FREEMPI(Q);
			L = B;
			B = ADD_MULT_ROWI(z, i, X, B);
			FREEMPI(X);
			FREEMATI(L);
			Tmp = A[i];
			A[i] = MOD0(A[i], A[z]);
			FREEMPI(Tmp);
		}
	if (MLLLVERBOSE)
	{
			printf("After the reduction: B = \n");
			PRINTMATI(0,B->R-1,0,B->C-1,B);
			printf("\n");
			for (i = 0; i < m; i++)
			{
				printf("A[%u] = ", i); PRINTI(A[i]); printf("\n");
			}
				GetReturn();
	}
		Tmp = A[z];
		temp = B->V[z];
		for (k = z; k <= m - 2; k++)
		{
			A[k] = A[k + 1];
			B->V[k] = B->V[k + 1];
		}
		A[m - 1] = Tmp;
		B->V[m - 1] = temp;
	if (MLLLVERBOSE)
	{
		printf("After the rearrangement: B = \n");
		PRINTMATI(0,B->R-1,0,B->C-1,B);
		printf("\n");
			for (i = 0; i < m; i++)
			{
				printf("A[%i] = ", i); PRINTI(A[i]); printf("\n");
			}
			GetReturn();
	}
		while (A[z]->S  == 0)
			z++;
		if (z == m - 1)
			break;
	}
	
	*Aptr = COPYI(A[m - 1]);
	if ((*Aptr)->S == -1)
	{
		(*Aptr)->S = 1;	
		for (i = 0; i < m; i++)
			 (B->V[m - 1][i])->S = -((B->V[m - 1][i])->S);	
	}
	for (i = 0; i < m; i++)
		FREEMPI(A[i]);
	ffree((char *)A, m * sizeof(MPI *));
	return (B);
}

void GCD4()
/* We compute an optimal multipliers for a[1],a[2],a[3],a[4]
 * in the range p1<=a[1]<=q1 etc. and rel prime.
 */
{
	USI l, m, p1, q1, p2, q2, p3, q3, p4, q4, m1, n1, t;
	USI i1, i2, i3, i4, p;
	int e;
	USL x, y, z;
	MPI *GCD, *T1, *T2, **XX, **X, *Temp, *DIFF;
	MPMATI *MATI1, *BB, *MATI3, *Q, *M;
	char buff[20];
	FILE *outfile;


	printf("Enter alpha=m/n,  1/4 < m/n <= 1:  (ie enter  m  and n)");
	scanf("%u%u", &m1, &n1);
	strcpy(buff, "gcd4.out");
	if(access(buff, R_OK) == 0)
	  unlink(buff);
	printf("Enter  the ranges pi,qi; 2 <= pi < qi < 2^32, i = 1,...,5: ");
	scanf("%u%u%u%u%u%u%u%u", &p1, &q1, &p2, &q2, &p3, &q3, &p4, &q4);
	Flush();
	m = 4;
	p = m - 1;
	for (i1 = p1; i1 <= q1; i1++)
	{
	/*for (i2 = (i1+1 > p2 ? i1+1: p2); i2 <= q2; i2++)*/
	for (i2 = p2; i2 <= q2; i2++)
	{
	/*for (i3 = (i2+1 > p3 ? i2+1: p3); i3 <= q3; i3++)*/
	for (i3 = p3; i3 <= q3; i3++)
	{
	/*for (i4 = (i3+1 > p4 ? i3+1: p4); i4 <= q4; i4++)*/
	for (i4 = p4; i4 <= q4; i4++)
	{
		x = GCDm((USL)i1, (USL)i2);
		y = GCDm(x, (USL)i3);
		z = GCDm(y, (USL)i4);
		if (z == 1)
		{
		printf("(i1,i2,i3,i4)=(%u,%u,%u,%u)\n", i1,i2,i3,i4);
		MATI1 = BUILDMATI(m, 1);
		MATI1->V[0][0] = CHANGE((USL) i1);
		MATI1->V[1][0] = CHANGE((USL) i2);
		MATI1->V[2][0] = CHANGE((USL) i3);
		MATI1->V[3][0] = CHANGE((USL) i4);
		BB = LLLGCD0M(MATI1, &GCD, m, m1, n1);
		FREEMATI(MATI1);
		FREEMPI(GCD);
		MATI3 = BUILDMATI(1, m);
		for (l = 0; l < m; l++)
			MATI3->V[0][l] = COPYI(BB->V[m - 1][l]); 
		T1 = LENGTHSQRI(MATI3, 0);
		Q = BB;
		XX = (MPI **)mmalloc((USL)(p * sizeof(MPI *)));
		for (t = 0; t < p; t++)
			XX[t] = ZEROI();
		while (1)
		{
			M = SHORTESTT0(Q, &X);
			for (t = 0; t < p; t++)
			{
				Temp = XX[t];
				XX[t] = ADDI(XX[t], X[t]);
				FREEMPI(Temp);
				FREEMPI(X[t]);
			}
			ffree((char *)X, p * sizeof(MPI *));
			if (M == NULL)
				break;
			else
			{
				for (l = 0; l < Q->C; l++)
				{
					FREEMPI(Q->V[m - 1][l]);
					Q->V[m - 1][l] = COPYI(M->V[0][l]);
				}
				FREEMATI(MATI3);
				MATI3 = M;
			}
		}
		T2 = LENGTHSQRI(MATI3, 0);
		if (RSV(T2, T1) == -1)
		{
			outfile = fopen(buff, "a");
			fprintf(outfile, "(%u,%u,%u,%u): ", i1,i2,i3,i4);
			fprintf(outfile, "b[%u]", m);
			for (t = 0; t < p; t++)
			{
				e = XX[t]->S;
				if (e == -1)
				{
					fprintf(outfile, "+");
					Temp = MINUSI(XX[t]);
					if (!EQONEI(Temp))
						FPRINTI(outfile, Temp);
					fprintf(outfile, "b[%u]", t + 1);
					FREEMPI(Temp);
				}
				if (e == 1)
				{
					fprintf(outfile, "-");
					if (!EQONEI(XX[t]))
						FPRINTI(outfile, XX[t]);
					fprintf(outfile, "b[%u]", t + 1);
				}
			}
			fprintf(outfile, ": ");
			DIFF = SUB0I(T1, T2);
			FPRINTI(outfile, DIFF); 
			FREEMPI(DIFF);
			fprintf(outfile, "\n");
			fclose(outfile);
		}
		for (t = 0; t < p; t++)
			FREEMPI(XX[t]);
		ffree((char *)XX, p * sizeof(MPI *));
		FREEMATI(BB);
		FREEMATI(MATI3);
		FREEMPI(T1);
		FREEMPI(T2);
		}
	}
	}
	}
	}
	return;
}

void GCD5()
/* We compute an multipliers for a[1],a[2],a[3],a[4],a[5] 
 * in the range p1<=a[1]<=q1 etc. and rel prime.
 */
{
	USI l, m, p1, q1, p2, q2, p3, q3, p4, q4, p5, q5, m1, n1;
	USI i1, i2, i3, i4, i5, p, t;
	int e;
	USL x, y, z, u;
	MPI *GCD, *T1, *T2, **XX, **X, *Temp, *DIFF;
	MPMATI *MATI1, *BB, *MATI3, *Q, *M;
	char buff[20];
	FILE *outfile;

	/*for (i2 = (i1+1 > p2 ? i1+1: p2); i2 <= q2; i2++)*/
	/*for (i3 = (i2+1 > p3 ? i2+1: p3); i3 <= q3; i3++)*/
	/*for (i4 = (i3+1 > p4 ? i3+1: p4); i4 <= q4; i4++)*/
	/*for (i5 = (i4+1 > p5 ? i4+1: p5); i5 <= q5; i5++)*/

	printf("Enter alpha=m/n,  1/4 < m/n <= 1:  (ie enter  m  and n)");
	scanf("%u%u", &m1, &n1);
	strcpy(buff, "gcd5.out");
	if(access(buff, R_OK) == 0)
	  unlink(buff);
	printf("Enter  the ranges pi,qi; 2 <= pi < qi < 2^32, i = 1,...,5: ");
	scanf("%u%u%u%u%u%u%u%u%u%u", &p1, &q1, &p2, &q2, &p3, &q3, &p4, &q4, &p5, &q5);
	Flush();
	m = 5;
	p = m - 1;
	for (i1 = p1; i1 <= q1; i1++)
	{
	for (i2 = p2; i2 <= q2; i2++)
	{
	for (i3 = p3; i3 <= q3; i3++)

⌨️ 快捷键说明

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