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

📄 reductio.c

📁 calc大数库
💻 C
📖 第 1 页 / 共 3 页
字号:
				        FREEMPI(TEMP);
					TEMP = MULT_I(C, 2);
					x = CHECK_UVARRAYS(B, TEMP);
					if(x){
					    class_number=class_number+1;
					    z=PERIOD(DD,B,TEMP);
					    if(z % 2){
					       parity_flag = 1;
					    }
					}
				        FREEMPI(TEMP);
				        FREEMPI(C);
				    }
				    FREEMPI(R);
				}
			}
			FREEMPI(H); 
			FREEMPI(B);
		}
		FREEMPI(A);
		FREEMPI(I);
		FREEMPI(J);
	}
	if(e==2){
		d = d / 4;
	}
	if(parity_flag){
             *norm = -1;
        }else{
	     *norm = 1;
        }
        /*printf("h(%lu)=%u, N(eta)=%d\n", d, class_number, *norm);*/
	FREEMPI(ONE);
	FREEMPI(F);
	FREEMPI(G);
	FREEMPI(DD);
	FREEMPIA(GLOBALARRAY_U);
        FREEMPIA(GLOBALARRAY_V);
        return(class_number);
}

USL TABLEPOS(MPI *M, MPI *N){
/* The following gives a table of h(d) for all squarefree d
 * in the range 2<=M<=d<=N<10^6. 
 * The number of squarefree d encountered is returned.
 */
	MPI *DD;
	USL count, m, n, d;
	USI h;
	char buff[20];
	FILE *outfile;
	int norm;

	count = 0;
	m = CONVERTI(M);
	n = CONVERTI(N);

        strcpy(buff, "tablepos.out");
	if(access(buff, R_OK) == 0)
	  unlink(buff);
	outfile = fopen(buff, "a");

	for(d = m; d <= n; d++){
            h = SQUAREFREE_TEST1000(d);
	    if(h == 0){
		continue;
	    }else{
		DD = CHANGE(d);
                h = POS1(DD, &norm);
		FREEMPI(DD);
		count++;
                printf("h(%lu) = %u, N(eta)= %d\n",d, h, norm);
                fprintf(outfile, "h(%lu) = %u, N(eta)= %d\n",d, h, norm);
            }
	}
	if(count==0){
		printf("no squarefree d in the range [%lu,%lu]\n",m,n);
	}
	fclose(outfile);
	return (count);
}

MPI *TABLEPOSX(MPI *M, MPI *N){
	MPI *LIMIT, *COUNT, *ONE;
	USL count;
	int t;

	LIMIT = POWER_I(10, 6);

	if(COMPAREI(M, N) > 0){
		printf("M > N\n");
		FREEMPI(LIMIT);
		return (NULL);
	}
	if(COMPAREI(N, LIMIT) >= 0){
		printf("N >= 10^6\n");
		FREEMPI(LIMIT);
		return (NULL);
	}
	FREEMPI(LIMIT);
	ONE = ONEI();
	t = COMPAREI(M, ONE);
	FREEMPI(ONE);
	if(t <= 0){
		printf("M <= 1\n");
		return (NULL);
	}
	count = TABLEPOS(M, N);
	COUNT = CHANGE(count);
	return(COUNT);
}

USI REDUCE_NEG0(MPI *A, MPI *B, MPI *C, MPI **AA, MPI **BB, MPI **CC, MPI **alpha, MPI **beta, MPI **gamma, MPI **delta, USI print_flag){
/* This is Gauss' algorithm for reducing a positive definite binary
 * quadratic form (A,B,C). 
 * See L.E. Dickson, Introduction to the theory of numbers,
 * page 69. Here d=B^2-4AC <0, A>0,C>0, while the reduced form (AA,BB,CC)
 * satisfies -AA<BB<=AA, CC>=AA, with BB>=0 if CC=AA.
 * The number of steps taken in the reduction is returned.
 */
	MPI *D, *X, *Y, *U, *V, *TEMP1, *TEMP2, *TEMP3;
	MPI *a, *b, *c, *TEMPX, *TEMPY, *TEMPU, *TEMPV, *MINUSD, *DELTA;
	MPI *TEMPB;
	USI i;
	int r, s, t;

	i = 0;
	TEMP1 = MULTI(B, B);
	TEMP2 = MULTI(A, C);
	TEMP3 = MULT_I(TEMP2, 4);
	D = SUBI(TEMP1, TEMP3);
	FREEMPI(TEMP1);
	FREEMPI(TEMP2);
	FREEMPI(TEMP3);
	TEMP1 = MINUSI(A);
	r = COMPAREI(TEMP1, B);
	FREEMPI(TEMP1);
	s = COMPAREI(B, A);
	t = COMPAREI(A, C);
	if(r < 0 && s <= 0 && t <= 0){
		r = COMPAREI(A, C);
		if(t < 0 || (r == 0 && B->S >= 0)){
                   if(print_flag){
			printf("(");
			PRINTI(A);
			printf(",");
			PRINTI(B);
			printf(",");
			PRINTI(C);
			printf(") is reduced\n");
                	printf("Transforming matrix:1,0,0,1\n");
                    }
                    FREEMPI(D);
                    *alpha = ONEI();
                    *beta = ZEROI();
                    *gamma = ZEROI();
                    *delta = ONEI();
                    *AA = COPYI(A);
                    *BB = COPYI(B);
                    *CC = COPYI(C);
                    return (0);
		}
	}
	X = ONEI();
	Y = ZEROI();
	U = ZEROI();
	V = ONEI();
	MINUSD = MINUSI(D);
	a=COPYI(A);
	b=COPYI(B);
	c=COPYI(C);
	while(1){
		TEMPB = b;
		TEMP1 = MINUSI(b);
		TEMP2 = MULT_I(c, 2);
		b = HALFMOD(TEMP1, TEMP2);
		FREEMPI(TEMP1);
		TEMP1 = ADDI(TEMPB, b);
		FREEMPI(TEMPB);
		TEMP3 = MINUSI(TEMP1);
		FREEMPI(TEMP1);
		DELTA = INT(TEMP3, TEMP2);
		FREEMPI(TEMP2);
		FREEMPI(TEMP3);
		TEMPU = U;
		TEMPX = X;
		TEMPY = Y;
		TEMPV = V;
		X = MINUSI(Y);
		Y = MULTABC(TEMPX, Y, DELTA);
		FREEMPI(TEMPX);
		FREEMPI(TEMPY);
		U = MINUSI(V);
		V = MULTABC(TEMPU, V, DELTA);
		FREEMPI(TEMPU);
		FREEMPI(TEMPV);
		FREEMPI(DELTA);
		TEMP1 = a;
		a = COPYI(c);
		FREEMPI(TEMP1);
		TEMP1 = c;
		TEMP2 = MULTABC(MINUSD, b, b);
		TEMP3 = MULT_I(a, 4);
		c = INT(TEMP2, TEMP3);
		FREEMPI(TEMP1);
		FREEMPI(TEMP2);
		FREEMPI(TEMP3);
		i++;
		if(print_flag){
		   printf("(");
		   PRINTI(a);
		   printf(",");
		   PRINTI(b);
		   printf(",");
		   PRINTI(c);
		   printf(")\n");
		}
		if(COMPAREI(c, a) >= 0){
			break;
		}
	}
	if(COMPAREI(a, c) == 0 && b->S < 0){
		TEMP1 = b;
		b = MINUSI(b);
		FREEMPI(TEMP1);
		TEMPX = X;
		TEMPY = Y;
		X = COPYI(Y);
		Y = MINUSI(TEMPX);
		FREEMPI(TEMPX);
		FREEMPI(TEMPY);
		TEMPU = U;
		TEMPV = V;
		U = COPYI(V);
		V = MINUSI(TEMPU);
		FREEMPI(TEMPU);
		FREEMPI(TEMPV);
	}
	*alpha = COPYI(X);
	*beta = COPYI(Y);
	*gamma = COPYI(U);
	*delta = COPYI(V);
	*AA = COPYI(a);
	*BB = COPYI(b);
	*CC = COPYI(c);
	if(print_flag){
           printf("(");
	   PRINTI(a);
	   printf(",");
	   PRINTI(b);
	   printf(",");
	   PRINTI(c);
	   printf(") is reduced\n");
	   printf("Transforming matrix: ");
	   PRINTI(X);
	   printf(",");
	   PRINTI(Y);
	   printf(",");
	   PRINTI(U);
	   printf(",");
	   PRINTI(V);
	   printf("\n");
	}
        FREEMPI(MINUSD);
	FREEMPI(D);
	FREEMPI(X);
	FREEMPI(Y);
	FREEMPI(U);
	FREEMPI(V);
	FREEMPI(a);
	FREEMPI(b);
	FREEMPI(c);
	return(i);
}

USI REP_DEFINITE(MPI *A, MPI *B, MPI *C, MPI *M, USI print_flag){
/* Given a positive definite binary quadratic form Ax^2+Bxy+Cy^2, 
 * we use an algorithm of Gauss to determine if a given positive integer M
 * is expressible as M = AX^2+BXY+CY^2, X and Y integers, gcd(X,Y) = 1.
 * Note: Here D = B^2 - 4AC < 0, A > 0, C > 0.
 * See L.E. Dickson, Introduction to the theory of numbers, pages 74-75.
 */
   USI solution_number;
   MPI *AA1, *BB1, *CC1, *R1, *S1, *T1, *U1, *D;
   MPI *AA2, *BB2, *CC2, *R2, *S2, *T2, *U2;
   MPI *TEMP0, *TEMP1, *TEMP2, *FOURM, *S, *MODULUS, *TWOM;
   MPI *L, *X, *Y, *XX, *YY, *T, *U;
   MPI *ALPHA1, *BETA1, *GAMMA1, *DELTA1, *N, *M0, *TEMP3, *TEMP;
   MPIA SOLUTION, SOL;
   USI l, i, r, s, t, numbr, m0, j, k;
   FILE *outfile;
   char buff[20];

   solution_number = 0;
   REDUCE_NEG0(A, B, C, &AA1, &BB1, &CC1, &R1, &S1, &T1, &U1, 0);
   TEMP0 = MULTI(B, B);
   TEMP1 = MULTI(A, C);
   TEMP2 = MULT_I(TEMP1, 4);
   D = SUBI(TEMP0, TEMP2);
   FREEMPI(TEMP0);
   FREEMPI(TEMP1);
   FREEMPI(TEMP2);
   FOURM = MULT_I(M, 4);
/* First solve x^2=D (mod FOURM). */ 
	S = SQROOT(D, FOURM, &SOLUTION, &MODULUS, &l);
	if(EQMINUSONEI(S)){ /* cleanup of nettbytes */
		FREEMPI(S);
		FREEMPIA(SOLUTION);
		FREEMPI(MODULUS);
		printf("x^2=");
		PRINTI(D);
		FREEMPI(D);
		printf("(mod ");
		PRINTI(FOURM);
		FREEMPI(FOURM);
		printf(") not soluble.\n");
		printf("Hence no primitive solutions.\n");
		return(0);
	}
	FREEMPI(S);
	M0 = INT0(FOURM, MODULUS);
	if(M0->D > 1){
		execerror("M0 >= 2^32", "");
	}
	m0 = CONVERTI(M0); /* valid, as 0 < M0 < 2^32 */
	TEMP = MULT_I(M0, l);
	FREEMPI(M0);
	TEMP1 = INT0_(TEMP, 100);
	FREEMPI(TEMP);
	t = TEMP1->D;
	FREEMPI(TEMP1);
	if(t){
           execerror("number of positive solutions of X^2=N(mod FOURM) > 100", "");
	}
	numbr = 0;
        SOL = BUILDMPIA(); 
	ADD_TO_MPIA(SOL, NULL, 0);
	for(j=0;j<l;j++){
	   for(k=0;k<m0;k++){
		   TEMP1=MULT_I(MODULUS, k);
		   TEMP2=ADD0I(SOLUTION->A[j],TEMP1);
		   TEMP3 = MULT_I(TEMP2, 2);
		   if(COMPAREI(TEMP3, FOURM) <= 0){
                      ADD_TO_MPIA(SOL, TEMP2, numbr);
                      numbr++;
		   }else{
		      TEMP0 = SUB0I(FOURM, TEMP2);
                      ADD_TO_MPIA(SOL, TEMP0, numbr);
	              FREEMPI(TEMP0);
                      numbr++;
		   }
	           FREEMPI(TEMP2);
	           FREEMPI(TEMP3);
	           FREEMPI(TEMP1);
	   }
           
        }
	FREEMPI(MODULUS);
	FREEMPIA(SOLUTION);

	strcpy(buff, "repdefinite.out");
	outfile = fopen(buff, "w");

	TWOM = MULT_I(M, 2);
	for(i = 0; i < numbr; i++){
           N = COPYI(SOL->A[i]);
	   /*if(RSV(N, TWOM) > 0){
		   TEMP = N;
		   N = SUBI(FOURM, N);
		   FREEMPI(TEMP);
	   }*/
	   fprintf(outfile, "N = ");
	   FPRINTI(outfile, N);
	   fprintf(outfile, "\n");
	   if(EQUALI(N, TWOM)){
              FREEMPI(N);
              continue;
           }
	   /* now calculate L, where N^2-4ML=D */
	   TEMP1 = MULTI(N, N);
	   TEMP2 = SUBI(TEMP1, D);
	   L = INT0(TEMP2, FOURM);
	   FREEMPI(TEMP1);
	   FREEMPI(TEMP2);
           REDUCE_NEG0(M, N, L, &AA2, &BB2, &CC2, &R2, &S2, &T2, &U2, 0);
           r = EQUALI(AA1, AA2);
	   s = EQUALI(BB1, BB2);
           t = EQUALI(CC1, CC2);
	   FREEMPI(AA2);
	   FREEMPI(BB2);
	   FREEMPI(CC2);
	   if(r && s && t){
              TEMP1 = MULTI(R1, U2);
              TEMP2 = MULTI(S1, T2);
              ALPHA1 = SUBI(TEMP1, TEMP2);
	      FREEMPI(TEMP1);
	      FREEMPI(TEMP2);

              TEMP1 = MULTI(S1, R2);
              TEMP2 = MULTI(S2, R1);
              BETA1 = SUBI(TEMP1, TEMP2);
	      FREEMPI(TEMP1);
	      FREEMPI(TEMP2);

              TEMP1 = MULTI(U2, T1);
              TEMP2 = MULTI(U1, T2);
              GAMMA1 = SUBI(TEMP1, TEMP2);
	      FREEMPI(TEMP1);
	      FREEMPI(TEMP2);

              TEMP1 = MULTI(U1, R2);
              TEMP2 = MULTI(S2, T1);
              DELTA1 = SUBI(TEMP1, TEMP2);
	      FREEMPI(TEMP1);
	      FREEMPI(TEMP2);

	      FREEMPI(R2);
	      FREEMPI(S2);
	      FREEMPI(T2);
	      FREEMPI(U2);
	      if(print_flag){
                fprintf(outfile, "The unimodular transformation\n");
                fprintf(outfile, "x = ");
		FPRINTI(outfile, ALPHA1);
                fprintf(outfile, "X + ");
		FPRINTI(outfile, BETA1);
                fprintf(outfile, "Y\n");
                fprintf(outfile, "y = ");
		FPRINTI(outfile, GAMMA1);
                fprintf(outfile, "X + ");
		FPRINTI(outfile, DELTA1);
                fprintf(outfile, "Y\n");
                fprintf(outfile, "converts (");
		FPRINTI(outfile, A);
		fprintf(outfile, ",");
		FPRINTI(outfile, B);
		fprintf(outfile, ",");
		FPRINTI(outfile, C);
                fprintf(outfile, ") to ");
                fprintf(outfile, "(");
		FPRINTI(outfile, M);
		fprintf(outfile, ",");
		FPRINTI(outfile, N);
		fprintf(outfile, ",");
		FPRINTI(outfile, L);
		fprintf(outfile, ")\n");
	      }
	      FREEMPI(N);
	      FREEMPI(L);
	      fprintf(outfile, "solution: (");
	      FPRINTI(outfile, ALPHA1);
	      fprintf(outfile, ",");
	      FPRINTI(outfile, GAMMA1);
	      fprintf(outfile, ")\n");

	      X = MINUSI(ALPHA1);
	      Y = MINUSI(GAMMA1);
	      fprintf(outfile, "solution: (");
	      FPRINTI(outfile, X);
	      fprintf(outfile, ",");
	      FPRINTI(outfile, Y);
	      fprintf(outfile, ")\n");
	      solution_number = solution_number + 2;

	      if(D->D == 0 && D->S == -1 && D->V[0] == 4){ /* D = -4 */
                 T = ZEROI();
                 U = ONEI();
		 AUTOMORPH(A, B, D, T, U, X, Y, &XX, &YY);
	         fprintf(outfile, "solution: (");
	         FPRINTI(outfile, XX);
	         fprintf(outfile, ",");
	         FPRINTI(outfile, YY);
	         fprintf(outfile, ")\n");
		 FREEMPI(XX);
		 FREEMPI(YY);
		 AUTOMORPH(A, B, D, T, U, ALPHA1, GAMMA1, &XX, &YY);
	         fprintf(outfile, "solution: (");
	         FPRINTI(outfile, XX);
	         fprintf(outfile, ",");
	         FPRINTI(outfile, YY);
	         fprintf(outfile, ")\n");
		 FREEMPI(XX);
		 FREEMPI(YY);
		 FREEMPI(T);
		 FREEMPI(U);
	         solution_number = solution_number + 2;
              }
	      if(D->D == 0 && D->S == -1 && D->V[0] == 3){ /* D = -3 */
                 T = ONEI();
                 U = ONEI();
		 AUTOMORPH(A, B, D, T, U, X, Y, &XX, &YY);
	         fprintf(outfile, "solution: (");
	         FPRINTI(outfile, XX);
	         fprintf(outfile, ",");
	         FPRINTI(outfile, YY);
	         fprintf(outfile, ")\n");
		 FREEMPI(XX);
		 FREEMPI(YY);
		 AUTOMORPH(A, B, D, T, U, ALPHA1, GAMMA1, &XX, &YY);
		 FREEMPI(T);
	         fprintf(outfile, "solution: (");
	         FPRINTI(outfile, XX);
	         fprintf(outfile, ",");
	         FPRINTI(outfile, YY);
	         fprintf(outfile, ")\n");
		 FREEMPI(XX);
		 FREEMPI(YY);
                 T = MINUS_ONEI();
		 AUTOMORPH(A, B, D, T, U, X, Y, &XX, &YY);
	         fprintf(outfile, "solution: (");
	         FPRINTI(outfile, XX);
	         fprintf(outfile, ",");
	         FPRINTI(outfile, YY);
	         fprintf(outfile, ")\n");
		 FREEMPI(XX);
		 FREEMPI(YY);
		 AUTOMORPH(A, B, D, T, U, ALPHA1, GAMMA1, &XX, &YY);
	         fprintf(outfile, "solution: (");
	         FPRINTI(outfile, XX);
	         fprintf(outfile, ",");
	         FPRINTI(outfile, YY);
	         fprintf(outfile, ")\n");
                 FREEMPI(XX);
	         FREEMPI(YY);
		 FREEMPI(T);
		 FREEMPI(U);
		 solution_number = solution_number + 4;
	      }
              FREEMPI(X);
	      FREEMPI(Y);
	      fprintf(outfile, "\n");
	      FREEMPI(ALPHA1);
	      FREEMPI(BETA1);
	      FREEMPI(GAMMA1);
	      FREEMPI(DELTA1);
	   }else{
		continue;
	   }
        }
	FREEMPI(R1);
	FREEMPI(S1);
        FREEMPI(T1);
        FREEMPI(U1);
	FREEMPI(AA1);
	FREEMPI(BB1);
        FREEMPI(CC1);
	FREEMPI(TWOM);
	FREEMPI(FOURM);
	FREEMPI(D);
	FREEMPIA(SOL);
	fclose(outfile);
        return(solution_number);
}

void AUTOMORPH(MPI *A, MPI *B, MPI *D, MPI *T, MPI *U, MPI *X, MPI *Y, MPI **XX, MPI **YY){
	/* From Loo-Keng Hua, Introduction to Number Theory, 
	 * Theorem 4.2, pages 279-281 */
	MPI *TEMP0, *TEMP1, *TEMP2, *TEMP3, *TEMP4, *TEMP5, *TEMP6;
	MPI *T1, *T2, *T3, *T4, *T5, *T6, *TEMP;

	TEMP1 = MULT_I(A, 2);
	TEMP2 = MULTI(TEMP1, X);
	TEMP0 = MULTI(Y, B);
	TEMP3 = ADDI(TEMP2, TEMP0);
	TEMP4 = MULTI(TEMP3, U);
	TEMP5 = MULTI(Y, T);
	TEMP6 = ADDI(TEMP4, TEMP5);
	*YY = INT_(TEMP6, 2);

	T1 = MULTI(TEMP3, T);
	T2 = MULTI(D, Y);
	TEMP = T2;
	T2 = MULTI(T2, U);
	FREEMPI(TEMP);
	T3 = ADDI(T1, T2);
	TEMP = T3;
	T3 = INT_(T3, 2);
	FREEMPI(TEMP);
	T4 = MULTI(B, *YY);
	T5 = SUBI(T3, T4);
	T6 = MULT_I(A, 2);
	*XX = INT(T5, T6);

	FREEMPI(TEMP0);
	FREEMPI(TEMP1);
	FREEMPI(TEMP2);
	FREEMPI(TEMP3);
	FREEMPI(TEMP4);
	FREEMPI(TEMP5);
	FREEMPI(TEMP6);
	FREEMPI(T1);
	FREEMPI(T2);
	FREEMPI(T3);
	FREEMPI(T4);
	FREEMPI(T5);
	FREEMPI(T6);
}

MPI *REP_DEFINITEX(MPI *A, MPI *B, MPI *C, MPI *M, MPI *PRINT_FLAG){
	MPI *D, *TEMP1, *TEMP2, *TEMP3;
	USI i, print_flag;

	if(M->S <= 0){
		printf("M <= 0\n");
		return(NULL);
	}
	if(A->S <= 0){
		printf("A <= 0\n");
		return(NULL);
	}
	if(C->S <= 0){
		printf("C <= 0\n");
		return(NULL);
	}
	TEMP1 = MULTI(B, B);
	TEMP2 = MULTI(A, C);
	TEMP3 = MULT_I(TEMP2, 4);
	D = SUBI(TEMP1, TEMP3);
	FREEMPI(TEMP1);
	FREEMPI(TEMP2);
	FREEMPI(TEMP3);
	if(D->S >= 0){
		printf("B^2-4*A*C >= 0\n");
		FREEMPI(D);
		return(NULL);
	}
	print_flag = (USI)CONVERTI(PRINT_FLAG);
	if(print_flag != 0 && print_flag != 1){
		printf("print_flag != 0 or 1\n");
		FREEMPI(D);
		return(NULL);
	}
	i = REP_DEFINITE(A, B, C, M, print_flag);
	FREEMPI(D);
	return(CHANGE(i));
}

⌨️ 快捷键说明

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