void LatticeReduction::reduceSlow(Tensor&t){ Vector v[3]; v[0]=t.getRow(0); v[1]=t.getRow(1); v[2]=t.getRow(2); reduce2(v[0],v[1],v[2]); double e01=dotProduct(v[0],v[1]); double e02=dotProduct(v[0],v[2]); double e12=dotProduct(v[1],v[2]); if(e01*e02*e12<0){ int eps01=0; if(e01>0.0) eps01=1; else if(e01<0.0) eps01=-1; int eps02=0; if(e02>0.0) eps02=1; else if(e02<0.0) eps02=-1; Vector n=v[0]-eps01*v[1]-eps02*v[2]; int i=0; double mx=modulo2(v[i]); for(int j=1;j<3;j++){ double f=modulo2(v[j]); if(f>mx){ i=j; mx=f; } } if(modulo2(n)<mx) v[i]=n; } sort(v); t.setRow(0,v[0]); t.setRow(1,v[1]); t.setRow(2,v[2]); }
void LatticeReduction::reduce2(Tensor&t){ Vector a=t.getRow(0); Vector b=t.getRow(1); Vector c=t.getRow(2); reduce2(a,b,c); t.setRow(0,a); t.setRow(1,b); t.setRow(2,c); }
int main(int argc, char *argv[]) { int num_threads; int vec_size; int custom_reduce_method; double accu; double time; double *vec; if (argc < 4) { printf("Usage: %s num_threads vec_size [reduce method]\n", argv[0]); printf(" - num_threads: number of threads to use for simulation, " "should be >=1\n"); printf(" - vec_size: size of the vector to do reduction on 10^n" "should be >=10\n"); printf(" - [reduce_method]: custom | sequential."); return EXIT_FAILURE; } num_threads = atoi(argv[1]); vec_size = pow(10, atoi(argv[2])); if (num_threads < 1) { printf("argument error: num_threads should be >=1.\n"); return EXIT_FAILURE; } if (vec_size < 4) { printf("argument error: vec_size should be >=4.\n"); return EXIT_FAILURE; } if (strcmp(argv[3], "sequential") == 0) { custom_reduce_method = 0; } else { custom_reduce_method = 1; } vec = (double*)malloc(vec_size * sizeof(double)); /* Fill a vector with a sinus values */ #pragma omp parallel for for (int i = 0; i < vec_size; i++) { vec[i] = sin(i); } omp_set_num_threads(num_threads); /* Start timing the effeciency of openMP */ timer_start(); /* Calculate a reduced vector with openMP */ if (custom_reduce_method) { accu = reduce2(fun, vec, vec_size, 0); /* accu = sum(vec, vec_size); */ } else { accu = reduce(fun, vec, vec_size, 0); } /* Stop timing */ time = timer_end(); printf("%d, %d, %g\n",num_threads, vec_size, time); free(vec); vec = NULL; return EXIT_SUCCESS; }
Number operator+( Number l, Number r) { int lnum = l.num; int lden = l.denom; int rnum = r.num; int rden = r.denom; // if one is whole number if (lden == 1) { return Number(lnum*rden + rnum, rden); } if (rden == 1) { return Number(rnum*lden + lnum, lden); } // sum of whole numbers int sumWhole = lnum/lden + rnum/rden; // what is left after subtracting whole number lnum = lnum%lden; rnum = rnum%rden; // lMaxMul is the largest integer that you can multiply // by lnum to not go over INT_MAX int lMaxMul = INT_MAX/abs(lnum); int rMaxMul = INT_MAX/abs(rnum); int gcdDenom = gcdFunction(lden,rden); // if numerators will not go over INT_MAX when // multiplied for common denom if (lMaxMul >= rden/gcdDenom && rMaxMul >= lden/gcdDenom) { // if the sum of numerators multiplied by their respective // factors will not go over INT_MAX if ( INT_MAX- lnum*(rden/gcdDenom) >= rnum*(lden/gcdDenom)) { // numerator (without reducing) int OriginalNum = lnum*(rden/gcdDenom) + rnum*(lden/gcdDenom); // reduce with both lden and rden Number reduce1(OriginalNum, lden); Number reduce2(reduce1.numerator(), rden/gcdDenom); return Number(reduce2.numerator() + sumWhole*(reduce1.denominator())*(reduce2.denominator()), (reduce1.denominator())*(reduce2.denominator())); } // if } // if // else, sum of two numbers is over 1 (or under -1) l.num = lnum; r.num = rnum; Number fill = l.fill(); // fill the first number so it reaches 1 or -1 // i.e. if l = 3/5 and r = 4/7, fill = 2/5 // 3/5 + 4/7 = 3/5 + 2/5 - 2/5 + 4/7 // = 1 - 2/5 + 4/7 if (lnum > 0) sumWhole++; else sumWhole--; Number wholeNumber(sumWhole, 1); Number sumFractions = r - fill; return wholeNumber + sumFractions; }