static void revol(rmptr r) {s_monom s; vmrec rec; vmptr m, m1; int i; s = r->n; r->n = r->d; r->d = s; rec.next = (r->d).v; m = &rec; m1 = m->next; while (m1 != NULL) { if (strcmp(m1->name,"i") == 0 ) { m->next = m1->next; if ( (m1->deg & 1) == 0) s.c= 1 ; else s.c= -1; s.v=m1; m1->next=NULL; mult_s(&(r->n),&s); m1 = m->next; } else if (strcmp(m1->name,"Sqrt2") == 0 ) { m->next = m1->next; for(i=0; i<m1->deg; i++) (r->d).c = (r->d).c*2; s.c=1; s.v=m1; m1->next=NULL; mult_s(&(r->n),&s); m1 = m->next; } else { m = m1; m1 = m1->next; } } (r->d).v = rec.next; reducec(&r->n.c,& r->d.c); if (r->d.c < 0) { r->d.c = - r->d.c; r->d.c = - r->d.c; } }
void mult_rptr(rmptr* m1,rmptr* m2) { reduce_s(&(*m1)->n,&(*m2)->d); reduce_s(&(*m1)->d,&(*m2)->n); mult_s(&(*m1)->n,&(*m2)->n); mult_s(&(*m1)->d,&(*m2)->d); free(*m2); delsqrt2(&(*m1)->n); del_i(&(*m1)->n); reducec(&(*m1)->n.c, &(*m1)->d.c); if ((*m1)->d.c < 0) { (*m1)->d.c = - (*m1)->d.c; (*m1)->d.c = - (*m1)->d.c; } }
// Sequential version of Karatsuba multiplication, with recursion // It works well when numbers are about same size large_int* mult_kar_eqsize(large_int* a, large_int* b) { int n; large_int a0,a1,b0,b1; large_int *a1_plus_a0,*b1_plus_b0, *a1b0_plus_a0b1; large_int *a1_mult_b1,*a0_mult_b0, *a1pa0_mult_b1pb0; large_int *temp,*result; if (debug) printf("Calling mult_kar_eqsize\n"); // For small numbers we use standard multiplication algorithm // This is the end of the recursion if (a->size<=KMUX_MINLEVEL || b->size<=KMUX_MINLEVEL) { if (debug) printf("Calling mult_gmp\n"); // return mult_gmp(a,b); return mult_s(a,b); } // Here we choose first if a or b are smaller. Then out of the smallest one // which we can call C, we find n that is <= 1/2 of it if (a->size>b->size) { n=b->size/2; if (2*n<b->size) n++; } else { n=a->size/2; if (2*n<a->size) n++; } a0.size=n; a1.size=a->size-n; b0.size=n; b1.size=b->size-n; // allocate arrays a0.int_array=malloc(sizeof(unsigned int)*a0.size); a1.int_array=malloc(sizeof(unsigned int)*a1.size); b0.int_array=malloc(sizeof(unsigned int)*b0.size); b1.int_array=malloc(sizeof(unsigned int)*b1.size); if (a0.int_array==NULL || a1.int_array==NULL || b0.int_array==NULL || b1.int_array==NULL) die("memory allocation error"); // Copy data from a,b into a0,a1,b0,b1 memcpy(a0.int_array,a->int_array,a0.size*sizeof(unsigned int)); memcpy(a1.int_array,(char*)a->int_array+((size_t)a0.size*sizeof(unsigned int)),a1.size*sizeof(unsigned int)); memcpy(b0.int_array,b->int_array,b0.size*sizeof(unsigned int)); memcpy(b1.int_array,(char*)b->int_array+((size_t)b0.size*sizeof(unsigned int)),b1.size*sizeof(unsigned int)); // Calculate a0+a1, b1+b0 - these can potentially be done in parallel to each other #pragma omp parallel sections default (shared) { a1_plus_a0=ADD(&a1,&a0); #pragma omp section b1_plus_b0=ADD(&b1,&b0); } // Calculate 3 intermediate products - can all be done in parallel #pragma omp parallel sections default (shared) { if (debug) printf("d0 "); a1_mult_b1=mult_kar_eqsize(&a1,&b1); if (debug) { printf("a1*b1 : "); print_hex(a1_mult_b1); } #pragma omp section { a0_mult_b0=mult_kar_eqsize(&a0,&b0); if (debug) { printf("a0*b0 : "); print_hex(a0_mult_b0); } } #pragma omp section { a1pa0_mult_b1pb0=mult_kar_eqsize(a1_plus_a0,b1_plus_b0); if (debug) { printf("(a1+a0)*(b1+b0) : "); print_hex(a1pa0_mult_b1pb0); } } } // From here on things can not really be parallelizeable if (debug && compare(a1_mult_b1,a1pa0_mult_b1pb0)>0) { printf("Noticed that a1b1 > (a1+a0)(b1+b0), this should not be\n"); temp=SUB(a1_mult_b1,a1pa0_mult_b1pb0); temp->sign=-1; } else { if (debug) printf("Calling sub -a1b1 , first_size=%d, second_size=%d\n",a1pa0_mult_b1pb0->size,a1_mult_b1->size); temp=SUB(a1pa0_mult_b1pb0,a1_mult_b1); temp->sign=1; if (debug) print_hex(temp); } if (debug && compare(temp,a0_mult_b0)<0) { if (debug) printf("Noticed that a0b0 > reminder, should not be"); a1b0_plus_a0b1=SUB(a0_mult_b0,temp); if (temp->sign==-1 && debug) printf("but we're good\n"); else { printf("we have a problem\n"); a1b0_plus_a0b1->sign=-1; } } else { if (debug) printf("calling sub -a0b0: "); a1b0_plus_a0b1=SUB(temp,a0_mult_b0); if (temp->sign==-1) printf("we have a problem\n"); if (debug) print_hex(a1b0_plus_a0b1); } free(temp->int_array); free(temp); // Do some shifting around to prepare final result shift_left(a1b0_plus_a0b1,n); shift_left(a1_mult_b1,n*2); if (debug) { printf("Shifted a1b0_plus_a0b1: "); print_hex(a1b0_plus_a0b1); printf("Shifted a1_mult_b1: "); print_hex(a1_mult_b1); } // Now we're ready to put it all together temp=ADD(a1_mult_b1,a1b0_plus_a0b1); result=ADD(temp,a0_mult_b0); // Free all allocated memory free(temp->int_array); free(a1_mult_b1->int_array); free(a0_mult_b0->int_array); free(a1pa0_mult_b1pb0->int_array); free(a1_plus_a0->int_array); free(b1_plus_b0->int_array); free(a1b0_plus_a0b1->int_array); free(a0.int_array); free(a1.int_array); free(b0.int_array); free(b1.int_array); free(temp); free(a1_mult_b1); free(a0_mult_b0); free(a1pa0_mult_b1pb0); free(a1_plus_a0); free(b1_plus_b0); free(a1b0_plus_a0b1); // And return return result; }
void diagramsrfactors(hlpcsptr gst,s_listptr* s,rmptr* totf) {s_listptr s1, s2, ss, dl; vcsect vcs_copy; int i; rmptr rcoef, rrcoef; rmptr r; s_monom stmp, stmp2; int first; s1 = NULL; s2 = NULL; first = 1; vcs_copy = vcs; while (gst != NULL) { ss = (s_listptr) m_alloc(sizeof(struct s_listrec)); ss->next = s1; s1 = ss; ss = (s_listptr) m_alloc(sizeof(struct s_listrec)); ss->next = s2; s2 = ss; coloringvcs(gst); attachvertexes(); rcoef = (rmptr) readExpression(vertexes[0].lgrnptr->comcoef, rd_rat,act_rat,NULL); for (i = 2; i <= vcs.sizet; i++) { rrcoef = (rmptr) readExpression(vertexes[i-1].lgrnptr->comcoef, rd_rat,act_rat,NULL); mult_rptr(&rcoef,&rrcoef); } if (first) { r = rcoef; s1->monom.c = 1; s1->monom.v = NULL; s2->monom.c = 1; s2->monom.v = NULL; first = 0; } else { copysmonom(r->n,&s1->monom); s2->monom = rcoef->n; reduce_s(&s1->monom,&s2->monom); copysmonom(s1->monom,&stmp); reduce_s(&r->n,&stmp); mult_s(&r->n,&stmp); /* for case Stmp = -1 */ copysmonom(r->d,&stmp); reduce_s(&stmp,&rcoef->d); copysmonom(rcoef->d,&stmp2); mult_s(&s1->monom,&rcoef->d); mult_s(&s2->monom,&stmp); mult_s(&r->d,&stmp2); free(rcoef); } vcs = vcs_copy; gst = gst->next; } vcs = vcs_copy; ss = s2; stmp.v = NULL; stmp.c = 1; while (s2 != NULL) { copysmonom(stmp,&stmp2); mult_s(&s2->monom,&stmp2); mult_s(&stmp,&s1->monom); dl = s1; s1 = s1->next; free(dl); s2 = s2->next; } clrvm(stmp.v); revers((void **)&ss); *s = ss; *totf = r; }