//V35 #define DEBUG 0 #define M_INT long long int #define LONG long long int #define ULONG unsigned long long int #define UINT32 unsigned int #define UINT64 unsigned long long #include #include #include #include #include "polybivar1.c" #define WORDSIZE 64 ULONG seed, mult; LONG rand64s(LONG p); LONG * extendSpace(LONG *A, LONG ** H, LONG * Space, LONG d1, LONG d2, LONG k){ LONG * B,a; int i; B = A; //printf("in here\n"); if (d1 + 1 > *Space){ //printf("got here againbbb\n"); B = *H; a=1; for(i=0;i1){ np += t; t = ceil2(t); } size = (n-1)*n*du/2 + n + (dx+2)*(dz+1) + 6*n*(du+1) + 3*(dx+2) + (dx+2)*(dx+2) + (du+1)*(dx/2 + 2) + (2*n+1)*(dx+2) + 2*n*(dz+1) + 4*(dx+2)*(DZ+n)*(log2N(n)+1) + 2*np*(dx+2) + 32*(dz+1) + (dx+2)*((dx+4)/2+1); return size; } //Evaluates polynomials at x = 0,+-1,+-2,+-3,... void FastEval(LONG **G, LONG **H, LONG* Space, LONG* degrees, LONG *F, LONG *EvalPoints, int iter, int n, int numPolys, int *degsX, int *degsY, int du, int DX, int dz, LONG p){ int i,j,k,m,ndz,dxdz, dx; LONG *p1,*p2,e,o,t; LONG *shift1, *shift2; ULONG z1[2],z2[2]; dx = DX; if(DX%2==1){dx += 1;} ndz = n*(dz+1); dxdz = 2*(DX+1)*(dz+1); //deal with easy case (x=0, store just constants) p1 = &F[iter*(DX+1)]; for(i=0;i=p ) z1[1] -= p; zfma(z2,p1[k+1],p2[m]); if( z2[1]>=p ) z2[1] -= p; } } zmod(z1,p); e = z1[0]; zmod(z2,p); o = mul64s(z2[0],i,p); G[(2*i-1)*(numPolys)+j][iter] = add64s(e,o,p); G[(2*i)*(numPolys)+j][iter] = sub64s(e,o,p); } p1 = p1 + dxdz; } p2 = p2 + du+1; i++; /*printf("after Eval\n"); for(j=0;j= 0){ da = polgcd64s(cont,W,da,db,p); } i++; } return da; }*/ void Dionvar(LONG *U, int n, int d, LONG *c, int dx, LONG *M, LONG *S, int *sDeg, LONG *W, LONG *Sigmas, LONG p, LONG *numMuls){ //Enter list of polynomials U of size (n*(d+1)), solution C of size at most (d+1), and polynomial M <- U[2]*U[3]...U[n] //local variables int i,j,k,du,dm,dg,ds,dt,mPos,dck,drem,point; LONG t,*u,*uTemp,*m,*mTemp,*g,*s,*ck,*Wptr,*V; cleanArray64s(W,2*(d+1) + 4*(n*d+1) + 2*(dx+1)); cleanArray64s(Sigmas,n*(d+1)); for(i=0;i1){ i=0; while(i=k){ G[s+t+i][k] = G[s+2*i][k]; } } s += t; t = ceil2(t); } //printf("here we go again\n"); if(degrees[s] >= k){return G[s][k];} else{ return 0;} } void createProblem(LONG *A, LONG *F0, int n, int dx, int dz, int dxA, int dzA, LONG alpha, LONG p, LONG *W){ //Note: dxA = dx*n, dzA = dz*n LONG *TEMP,*TEMP2,*TEMP3,t1,t2,alpha2,r; int i,j,k,l,m,p1,p2,p3,MIN,MAX,da,db,dc,w; ULONG z[2]; //return the degree of dxA,dzA //TEMP = W; //TEMP2 = W + (dxA+1)*(dzA+1); //TEMP3 = W + 2*(dxA+1)*(dzA+1); TEMP = array((dxA+1)*(dzA+1)); TEMP2 = array((dxA+1)*(dzA+1)); TEMP3 = array((dxA+1)*(dzA+1)); cleanArray64s(TEMP,(dxA+1)*(dzA+1)); cleanArray64s(TEMP2,(dxA+1)*(dzA+1)); cleanArray64s(TEMP3,(dxA+1)*(dzA+1)); cleanArray64s(A,(dzA+1)*(dxA+1)); //generate the polynomials of F (A = f_1*f_2*...*f_n) for(i=0;i=0;l--){ MIN = max32s(0,l-db); MAX = min32s(l,da); z[0] = convol64s(&TEMP3[p3], &TEMP[p1+p2],MIN,MAX,l,p); //for(m=MIN;m<=MAX;m++){ //t1 = big polynomial //t2 = small polynomial //zfma(z,TEMP3[p3+m],TEMP[p1+p2+l-m]); //} //zmod(z,p); TEMP2[(k+j)*((i+1)*dx+1)+l] = add64s(z[0],TEMP2[(k+j)*((i+1)*dx+1)+l],p); } } } //move current polynomial back to TEMP1 for(j=0;j<=(i+1)*dz;j++){ p2 = j*((i+1)*dx+1); for(k=0;k<=(i+1)*dx;k++){ t1 = TEMP2[p2+k]; TEMP3[p2+k] = t1; } } } //move to A for(i=0;i<=dzA;i++){ p1 = i*(dxA+1); for(j=0;j<=dxA;j++){ t1 = TEMP3[p1+j]; A[p1+j] = t1; } } for(i=0;i= 2"); return -1; } //printf("gammaTay=");polprint64s(gammaTay,gdeg); printf("\n"); //printf("gammaN :=");polprint64s(gammaN,gdegN); printf("\n"); //printf("gammaNTay=");polprint64s(gammaNTay,gdegN); printf("\n"); //printf("gdegN = %lld\n",gdegN); //move contents of F0 to F //Calculate exact degree bound of factors p1 = F; p2 = f0; p3 = F0; //Initialize matrix G, Space, and degrees for(i=0;i<(dx+1)*numPolys;i++){ G[i] = H; Space[i] = 1; degrees[i] = 0; H += 1; } s = poleval64s(gamma,gdeg,alpha,p); for(i=0;i1){ j=0; while(j= k){P1[s+t+j][k] = add64s(P1[s+t+j][k],TEMP1[j],p);} j++; } if(t%2==1){ TEMP1[j] = 0; if(p3[s+2*j]>=k){TEMP1[j] = P1[s+2*j][k];} P1[t+s+j] = extendSpace(P1[t+s+j],&H,&p2[t+s+j],p3[s+2*j],p3[t+s+j],log2N(p3[s+2*j])+1); p3[s+t+j] = p3[s+2*j]; if(p3[s+t+j] >= k){P1[t+s+j][k] = TEMP1[j];} } //if(i==1){printf("TEMP1=");polprint64s(TEMP1,n/2,p); printf("\n");} s += t; t = ceil2(t); } } //printf("after update\n"); /*for(i=0;i0){ poldiv64s(gammaNTay,TEMP1,gdegN,t,p); gammaNTay +=t; gdegN = gdegN-t; //printf("zt=");polprint64s(gammaNTay,gdegN); printf("\n"); } else{gammaN[0] = mul64s(gammaN[0],modinv64s(TEMP1[0],p),p);} //printf("%lld\n",gdegN); //polprint64s(gammaNTay,gdegN);printf("\n"); p1 += maxSizeA; } //altar final factor for(j=0;j<=du;j++){ d=0; for(k=0;k<=2*DZ;k++){ H[k] = p1[k*(DX+1)+j]; if(H[k] != 0){d = k;} } poldiv64s(H,gammaNTay,d,gdegN,p); for(k=0;k<=d-gdegN;k++){p1[k*(DX+1)+j] = H[k+gdegN];} for(k=d-gdegN+1;k<=2*DZ;k++){p1[k*(DX+1)+j]=0;} } DDZ[n-1] = maxDeg[n-1] - gdegN; //perform final change of base back go y s = sub64s(p,alpha,p); for(i=0;i=0;k--){ if(F[i*maxSizeA + j*(DX+1) + k] != 0){break;} DDX[i*(DZ+1)+j] -= 1; } } } //modify the factors so that the evaluations match the initial factorization input (f0) for(i=0;i=1;j--){ poly1 = &F[(j)*(dz+1)*(dx+1)]; poly2 = &CoeffCalc[(j)*(dx+1)*(dz+1)]; coeffDegs[(j)*(dz+1)] = facDegs[(j)*(dz+1)] + coeffDegs[(j+1)*(dz+1)]; fastPolyMult(poly1,poly2,&CoeffCalc[(j-1)*(dx+1)*(dz+1)],facDegs[(j)*(dz+1)],coeffDegs[(j+1)*(dz+1)],p); } //main FOR loop T3 = clock(); for(k=1;k<=dz;k++){ //printf("Iteration: %d\n\n",k); //get the error for this loop point1 = k*(dx+1); ck = &(E[point1]); //zero relevant elements /*for(m=0;m=1; j--){ curDeg = accDeg; accDeg = accDeg + maxDeg[j]; //make sure i need to do current calculations if(i <= accDeg){ //first 2 polynomials multiplied if (j==n-2) { MIN = max32s(0,i-maxDeg[j]); MAX = min32s(i,maxDeg[j]); point1 = (n-1)*(dx+1)*(dz+1); point2 = (n-2)*(dx+1)*(dz+1); //refers to the degree of (y-alpha) for each factor for (q=MIN;q<=MAX;q++){ //multiply the 2 polynomials together (classical) point3 = q*(dx+1); point4 = (i-q)*(dx+1); poly2 = &F[point1+point3]; poly1 = &F[point2+point4]; coeffDegs[(n-2)*(dz+1)+i] = max32s(coeffDegs[(n-2)*(dz+1)+i],facDegs[(n-1)*(dz+1)+(i-q)]+facDegs[(n-2)*(dz+1)+q]); //multiply quickly fastPolyMult(poly2,poly1,&CoeffCalc[(j-1)*(dx+1)*(dz+1) + i*(dx+1)],facDegs[(n-1)*(dz+1)+q],facDegs[(n-2)*(dz+1)+(i-q)],p); } } //continued polynomial multiplication up to degree d else{ MIN = max32s(0,i-curDeg); MAX = min32s(i,maxDeg[j]); point1 = (j)*(dx+1)*(dz+1); //this draws from F point2 = (j-1)*(dx+1)*(dz+1); //this draws from CoeffCalc //refers to the degree of (y-alpha) for each factor for (q=MIN;q<=MAX;q++){ //multiply the 2 polynomials together (classical) point3 = q*(dx+1); point4 = (i-q)*(dx+1); poly2 = &F[point1+point3]; poly1 = &CoeffCalc[point1 + point4]; coeffDegs[(j)*(dz+1)+i] = max32s(coeffDegs[(j)*(dz+1)+i],coeffDegs[(j+1)*(dz+1)+(i-q)]+facDegs[(j)*(dz+1)+q]); //multiply quickly fastPolyMult(poly2,poly1,&CoeffCalc[(j-1)*(dx+1)*(dz+1) + i*(dx+1)],facDegs[(j)*(dz+1)+q],coeffDegs[(j+1)*(dz+1)+(i-q)],p); } } } } } //zero Delta array cleanArray64s(Delta,dx+1); curDeg = accDeg; accDeg = accDeg + maxDeg[0]; MIN = max32s(0,k-accDeg); MAX = min32s(k,curDeg); //Calculate final coefficients (Delta) for(m=MIN;m<=MAX;m++){ poly1 = &F[m*(dx+1)]; poly2 = &CoeffCalc[(k-m)*(dx+1)]; fastPolyMult(poly1,poly2,Delta,facDegs[m],coeffDegs[(dz+1) + (k-m)],p); } T2 = clock(); s1 = s1 + T2 - T1; //subtract delta from e T1 = clock(); temp = polsub64s(ck, Delta, ck, dx, dx, p); T2 = clock(); s5 = s5 + T2 - T1; //printf("ck:=");polprint64s(ck,dx);printf("\n"); cleanArray64s(TEMP1,maxSizeA); //check to make sure ck isn't zero flag = 0; for (i=0;i<=dx;i++){ if (ck[i] != 0){ flag = 1; break; } } if(flag == 1) { //Solve Diophantine Equation T1 = clock(); Dionvar(F0, n, du, ck, dx, M, DioSVal,sDeg, W, TEMP1, p, &numDioMuls); T2 = clock(); s4 = s4 + T2 - T1; //printf("Del:=");polprint64s(TEMP1,maxSizeA);printf("\n"); //Update F point2 = k*(dx+1); for(i=0;i=1;i--){ poly1 = &F[(i)*(dx+1)*(dz+1)]; poly2 = &F[(i)*(dx+1)*(dz+1) + k*(dx+1)]; poly3 = &CoeffCalc[(i)*(dx+1)*(dz+1)]; poly4 = &CoeffCalc[(i-1)*(dx+1)*(dz+1) + k*(dx+1)]; cleanArray64s(TEMP2,dx+1); fastPolyMult(poly1,TEMP1,TEMP2,facDegs[(i)*(dz+1)],accDeg,p); fastPolyMult(poly2,poly3,TEMP2,facDegs[(i)*(dz+1)+k],coeffDegs[(i+1)*(dz+1)],p); accDeg = max32s(accDeg + facDegs[(i)*(dz+1)],facDegs[(i)*(dz+1)+k]+coeffDegs[(i+1)*(dz+1)]); coeffDegs[(i)*(dz+1)+k] = max32s(accDeg,coeffDegs[(i)*(dz+1)+k]); poly1 = &CoeffCalc[(i-1)*(dx+1)*(dz+1) + k*(dx+1)]; for(j=0;j<=accDeg;j++){ TEMP1[j] = TEMP2[j]; poly1[j] = add64s(poly1[j],TEMP2[j],p); } } } } T4 = clock(); //print statements /* printf("Polynomial Multiplication time=%8.2fms\n",(s1)/1000.0/1.0); printf("Diophantine time=%8.2fms\n",(s4)/1000.0/1.0); printf("Sub time=%8.2fms\n",(s5)/1000.0/1.0); printf("Total Loop time=%8.2fms\n",(T4-T3)/1000.0/1.0); */ return 0; }