www.pudn.com > calc.rar > reduce.c


/* reduce.c */ 
#include  
#include  
#include "integer.h" 
#include "fun.h" 
 
/* 
MPI *FACTORQ(Q, factored, base, M1, FBASE, x, r1, r2, r, SCAN) 
*/ 
/* 
 * produces an exponent vector (mod 2) which updates M2[factored][*] 
 * and returns a cofactor. 
 */ 
/* 
unsigned int factored, base[], **M1, FBASE, r1[], r2[], r; 
MPI *Q; 
int x, SCAN[]; 
{ 
	unsigned int i, s, R; 
	int t, j; 
	MPI *T, *Tmp; 
 
	 
	INTSETUI(M1[factored], 2 + (USL)FBASE, 0); 
	Tmp = ABSI(Q); 
	t = x % 2; 
	R = (x < 0 && t) ? (unsigned int)t + 2 : (unsigned int)t; 
	if (R == r) 
	{ 
		s = 0; 
		while (((Tmp->V[0]) & 1) == 0) 
		{ 
			s++; 
			T = INT0_(Tmp, UL2); 
			FREEMPI(Tmp); 
			Tmp = T; 
		} 
		M1[factored][0] = s & 1;	 
		if (M1[factored][0]) 
			SCAN[factored] = 0; 
	} 
	for (i = 1; i <= FBASE; i++) 
	{ 
		t = x % (int)(base[i]);	 
		R = (x < 0 && t) ? (unsigned int)t + base[i] : (unsigned int)t; 
		if (R == r1[i] || R == r2[i]) 
		{ 
			s = 0; 
			while (MODINT0_(Tmp, base[i], &T) == 0) 
			{ 
				s++; 
				FREEMPI(Tmp); 
				Tmp = T; 
			} 
			FREEMPI(T); 
			M1[factored][i] = s & 1;	 
			if (M1[factored][i]) 
				SCAN[factored] = i; 
		} 
	} 
	if (Q->S == -1) 
	{ 
		M1[factored][1 + FBASE] = 1; 
		SCAN[factored] = 1 + FBASE; 
	} 
	return (Tmp); 
} 
*/ 
 
MPI *FACTORQ1(MPI *Q, USI factored, USL base[], USL **M1, USI FBASE, long x, USL r1[], USL r2[], USL r, int INDEX[], USI CTR[]) 
/* 
 * produces an exponent vector (mod 2) which updates M2[factored][*] 
 * and returns a cofactor. Used in Peter Adams' version MPQS1(). 
 */ 
{ 
	unsigned int i; 
	long t; 
	MPI *T, *Tmp; 
	unsigned long *m1ptr, word, R, sp2, s; 
	unsigned int ctr, index; 
 
	m1ptr=M1[factored]; 
	ctr=0; 
	word=0; 
	index=0; 
	Tmp = ABSI(Q); 
	t = x % 2L; 
	R = (x < 0 && (USL)t) ? (USL)(t + 2) : (USL)t; 
	if (R == r) 
	{ 
		s = 0; 
		while (((Tmp->V[0]) & (USL)1) == 0) 
		{ 
			s++; 
			T = INT0_(Tmp, (USL)2); 
			FREEMPI(Tmp); 
			Tmp = T; 
		} 
		word=(s & (USL)1); 
		if (word) 
		{ 
			INDEX[factored] = (int)index; 
			CTR[factored] = ctr; 
		} 
		ctr++; 
	} 
	else 
	  	ctr++; 
	for (i = 1; i <= FBASE; i++) 
	{ 
		t = x % (long)(base[i]);	 
		R = (x < 0 && (USL)t) ? (USL)(t + base[i]) : (USL)t; 
		s = 0; 
		if (R == r1[i] || R == r2[i]) 
		{ 
			while (MODINT0_(Tmp, base[i], &T) == 0) 
			{ 
				s++; 
				FREEMPI(Tmp); 
				Tmp = T; 
			} 
			FREEMPI(T); 
		} 
		sp2=s&1; 
		word=(word<<1)+sp2; 
		if (sp2) 
		{ 
			INDEX[factored] = (int)index; 
			CTR[factored] = ctr; 
		} 
		ctr++; 
		if(ctr==O32) 
		{ 
		  m1ptr[index]=word; 
		  index++; 
		  ctr=0; 
		  word=0; 
		} 
	} 
	word=(word<<1) + ((Q->S == 1) ? (USL)0 : (USL)1); 
	if (Q->S == -1) 
	{ 
		INDEX[factored] = (FBASE + 1)>>O5; 
		CTR[factored] = (FBASE + 1) & O31; 
	} 
	ctr++; 
	word=word<<(O32-ctr); 
	m1ptr[index]=word; 
	return (Tmp); 
} 
 
unsigned long **idim2(USI row, USI col) 
/* 
 * Builds an array of row * col unsigned longs. 
 * From page 182, Advanced C - tips and techniques, by P Anderson and  
 * G. Anderson. 
 */ 
{ 
	register unsigned int i; 
	unsigned long **prow, *pdata; 
 
	pdata = (unsigned long *)ccalloc(row * col, sizeof(unsigned long)); 
	prow =  (unsigned long **)mmalloc((USL)(row * sizeof(unsigned long *))); 
	for (i = 0; i < row; i++) 
	{ 
		prow[i] = pdata; 
		pdata += col; 
	} 
	return (prow); 
} 
 
void ifree2(USL **pa, USI row, USI col) 
/* 
 * Frees the 2-dimensional array of unsigned ints pa. 
 * From page 183, Advanced C - tips and techniques, by P Anderson and  
 * G. Anderson. 
 */ 
{ 
	ffree((char *)*pa, row * col * sizeof(unsigned long)); /* free the data */ 
	ffree((char *)pa, row * sizeof(unsigned long *)); /* free the row pointers */ 
} 
/*void REDUCTION();*/ 
/* this test the function REDUCTION() */ 
/* 
main() 
{ 
	unsigned int i, j, m, n; 
	register int l; 
	register int k; 
	unsigned int M1[rows][cols], M2[rows][cols]; 
 
	printf(" enter the number of rows and columns (<= 20) :"); 
	scanf("%u%u", &m, &n); 
	for (i = 0; i < m; i++) 
	{ 
		printf("enter row %u: ", i); 
		for (j = 0; j < n; j++) 
			scanf("%u", &M1[i][j]); 
	} 
	printf("matrix M1 entered = \n"); 
	for (i = 0; i < m; i++) 
	{ 
		for (j = 0; j < n; j++) 
			printf("%u", M1[i][j]); 
		printf("\n"); 
	} 
	for (k = 0; k <= m; k++) 
		for (l = 0; l <= m; l++) 
			M2[k][l] = 0; 
	for (k = 0; k <= m; k++) 
		M2[k][k] = 1; 
	printf("identity matrix = \n"); 
	for (i= 0; i < m; i++) 
	{ 
		for (j= 0; j < n; j++) 
			printf("%u", M2[i][j]); 
		printf("\n"); 
	} 
	REDUCTION(M1, M2, m, n); 
	printf("reduced M1  = \n"); 
	for (i= 0; i < m; i++) 
	{ 
		for (j= 0; j < n; j++) 
			printf("%u", M1[i][j]); 
		printf("\n"); 
	} 
	printf("identity matrix changed to = \n"); 
	for (i= 0; i < m; i++) 
	{ 
		for (j= 0; j < n; j++) 
			printf("%u", M2[i][j]); 
		printf("\n"); 
	} 
	exit (0); 
} 
 
*/ 
void REDUCTION(USI **M1, USI **M2, USI m, USI n, int SCAN[]) 
/* 
 * A form of right-to-left gaussian reduction on M1[m,n] over Z_2, doing the  
 * same operations on M2[m,m], where M2 is the unit matrix of same size  
 * as M1. 
 * From page 188, "A method of factoring and the factorization of F_7", 
 * M.A. Morrison and J. Brillhart, Math. Comp. 1975, 183-205. 
 */ 
{ 
	register int l; 
	register int k; 
	register int i; 
	register int j; 
 
	for (j = n - 1; j >= 0; j--) 
	{ 
	   for (i = 0; i < m; i++) 
	   { 
		if (SCAN[i] == j) 
		{ 
		    for (k = i + 1; k < m; k++) 
		    { 
			if (SCAN[k] == j) 
			{ 
			    for (l = 0; l <= j; l++) 
				M1[k][l] ^= M1[i][l]; 
			    for (l = 0; l < m; l++) 
				M2[k][l] ^= M2[i][l]; 
			    for (l = n - 1; l >= 0 && M1[k][l] == 0; l--) 
				    ; 
			    SCAN[k] = l; 
			} 
		    } 
		} 
	   } 
      } 
} 
 
void REDUCTION1(USL **M1, USL **M2, USI m, USI n, USI m1bitcols, USI m2bitcols, int INDEX[], USI CTR[]) 
/* 
 * A form of right-to-left gaussian reduction on M1[m,n] over Z_2, doing the  
 * same operations on M2[m,m], where M2 is the unit matrix of same size  
 * as M1. 
 * From page 188, "A method of factoring and the factorization of F_7", 
 * Math. Comp. 1975, 183-205. Used by Peter Adams in MPQS1(). 
 */ 
{ 
	unsigned long *p3, *p4; 
	unsigned long *p1, *p2; 
	register int j, l; 
	register int i, k; 
	int jword, jbit; 
 
	for (j = n - 1; j >= 0; j--) 
	{ 
	  jword = j >> O5; 
	  jbit = j & O31; 
	  for (i = 0; i < m; i++) 
	  { 
	    p3 = M1[i]; 
	    p4 = M2[i]; 
	    if (INDEX[i] == jword && CTR[i] == jbit) 
	    { 
	      for (k = i + 1; k < m; k++) 
	      { 
		p1 = M1[k]; 
		p2 = M2[k]; 
	      	if (INDEX[k] == jword && CTR[k] == jbit) 
	      	{ 
	      		for (l = 0; l < m1bitcols; l++) 
	      			p1[l] ^= p3[l]; 
	      		for (l = 0; l < m2bitcols; l++) 
	      			p2[l] ^= p4[l]; 
			for (l = m1bitcols - 1; l >= 0 && p1[l] == 0; l--) 
				; 
			if ((INDEX[k] = l) >= 0) 
				CTR[k] = O31 - BINARY(p1[l]);	 
	      	} 
	      } 
	    } 
	  } 
	} 
} 
 
void EXP_UPDATE(MPI *Q, USL base[], USI FBASE, USI exponents[]) 
/* 
 * updates the exponent vector exponent[], where Q is in S. 
 */ 
{ 
	unsigned int i, s; 
	MPI *Tmp, *T; 
 
	Tmp = ABSI(Q); 
	for (i = 0; i <= FBASE; i++) 
	{ 
		s = 0; 
		while (MODINT0_(Tmp, base[i], &T) == 0) 
		{ 
			s++; 
			FREEMPI(Tmp); 
			Tmp = T; 
		} 
		FREEMPI(T); 
		exponents[i] += s; 
/* 
		if (s) 
			printf(".%lu^%u", base[i], s); 
*/ 
	} 
	FREEMPI(Tmp); 
	return; 
} 
 
void print_array(USL **M, int rows, int cols) 
/* 
	Prints the contents of the given array. 
*/ 
{ 
	unsigned long i,j; 
	int elmt; 
 
	for(i=0; i