/*4:*/ #line 86 "gb_raman.w" #include "gb_graph.h" #define panic(c) {panic_code= c;gb_trouble_code= 0;return NULL;} #define dead_panic(c) {gb_free(working_storage) ;panic(c) ;} #define late_panic(c) {gb_recycle(new_graph) ;dead_panic(c) ;} \ #define ref a.I \ #line 88 "gb_raman.w" /*18:*/ #line 411 "gb_raman.w" typedef struct{ long a0,a1,a2,a3; unsigned long bar; }quaternion; /*:18*/ #line 89 "gb_raman.w" /*6:*/ #line 124 "gb_raman.w" static long*q_sqr; static long*q_sqrt; static long*q_inv; /*:6*//*15:*/ #line 272 "gb_raman.w" static char name_buf[]= "(1111,1111;1,1111)"; /*:15*//*20:*/ #line 431 "gb_raman.w" static quaternion*gen; /*:20*//*22:*/ #line 479 "gb_raman.w" static unsigned long gen_count; static unsigned long max_gen_count; #line 26 "gb_raman.ch" static void deposit(long a,long b,long c,long d) #line 484 "gb_raman.w" { if(gen_count>=max_gen_count) gen_count= max_gen_count+1; else{ gen[gen_count].a0= gen[gen_count+1].a0= a; gen[gen_count].a1= b;gen[gen_count+1].a1= -b; gen[gen_count].a2= c;gen[gen_count+1].a2= -c; gen[gen_count].a3= d;gen[gen_count+1].a3= -d; if(a){ gen[gen_count].bar= gen_count+1; gen[gen_count+1].bar= gen_count; gen_count+= 2; }else{ gen[gen_count].bar= gen_count; gen_count++; } } } /*:22*//*30:*/ #line 697 "gb_raman.w" #line 35 "gb_raman.ch" static long lin_frac( long a, long k) #line 701 "gb_raman.w" {register long q= q_inv[0]; long a00= gen[k].a0,a01= gen[k].a1,a10= gen[k].a2, a11= gen[k].a3; register long num,den; if(a==q)num= a00,den= a10; else num= (a00*a+a01)%q,den= (a10*a+a11)%q; if(den==0)return q; else return(num*q_inv[den])%q; } /*:30*/ #line 90 "gb_raman.w" #line 14 "gb_raman.ch" Graph*raman( long p, long q, unsigned long type, unsigned long reduce) #line 97 "gb_raman.w" {/*5:*/ #line 110 "gb_raman.w" Graph*new_graph; Area working_storage; /*:5*//*9:*/ #line 151 "gb_raman.w" register long a,aa,k; long b,bb,c,cc,d,dd; long n; long n_factor; register Vertex*v; /*:9*/ #line 97 "gb_raman.w" /*7:*/ #line 129 "gb_raman.w" if(q<3||q> 46337)panic(very_bad_specs); if(p<2)panic(very_bad_specs+1); init_area(working_storage); q_sqr= gb_typed_alloc(3*q,long,working_storage); if(q_sqr==0)panic(no_room+1); q_sqrt= q_sqr+q; q_inv= q_sqrt+q; /*8:*/ #line 142 "gb_raman.w" for(a= 1;a=q)dead_panic(bad_specs+1); if(k==q-1)break; } /*:10*/ #line 139 "gb_raman.w" ; /*11:*/ #line 177 "gb_raman.w" for(b= a,bb= aa;b!=bb;b= (a*b)%q,bb= (aa*bb)%q)q_inv[b]= bb,q_inv[bb]= b; q_inv[1]= 1;q_inv[b]= b; q_inv[0]= q; /*:11*/ #line 140 "gb_raman.w" ; /*:7*/ #line 98 "gb_raman.w" ; /*12:*/ #line 187 "gb_raman.w" if(p==2){ if(q_sqrt[13%q]<0||q_sqrt[q-2]<0) dead_panic(bad_specs+2); } if((a= p%q)==0)dead_panic(bad_specs+3); if(type==0)type= (q_sqrt[a]> 0?3:4); n_factor= (type==3?(q-1)/2:q-1); switch(type){ case 1:n= q+1;break; case 2:n= q*(q+1)/2;break; default:if((q_sqrt[a]> 0&&type!=3)||(q_sqrt[a]<0&&type!=4)) dead_panic(bad_specs+4); if(q> 1289)dead_panic(bad_specs+5); n= n_factor*q*(q+1); break; } if(p>=(long)(0x3fffffff/n))dead_panic(bad_specs+6); /*:12*/ #line 99 "gb_raman.w" ; /*13:*/ #line 244 "gb_raman.w" new_graph= gb_new_graph(n); if(new_graph==NULL) dead_panic(no_room); sprintf(new_graph->id,"raman(%ld,%ld,%lu,%lu)",p,q,type,reduce); strcpy(new_graph->util_types,"ZZZIIZIZZZZZZZ"); v= new_graph->vertices; switch(type){ case 1:/*14:*/ #line 260 "gb_raman.w" new_graph->util_types[4]= 'Z'; for(a= 0;aname= gb_save_string(name_buf); v->x.I= a; v++; } v->name= gb_save_string("INF"); v->x.I= q; v++; /*:14*/ #line 252 "gb_raman.w" ;break; case 2:/*16:*/ #line 279 "gb_raman.w" for(a= 0;aname= gb_save_string(name_buf); v->x.I= a;v->y.I= aa; v++; } /*:16*/ #line 253 "gb_raman.w" ;break; default:/*17:*/ #line 300 "gb_raman.w" new_graph->util_types[5]= 'I'; for(c= 0;c<=q;c++) for(b= 0;bz.I= c; if(c==q){ v->y.I= b; v->x.I= (type==3?q_sqr[a]:a); sprintf(name_buf,"(%ld,%ld;0,1)",v->x.I,b); }else{ v->x.I= b; v->y.I= (b*c+q-(type==3?q_sqr[a]:a))%q; sprintf(name_buf,"(%ld,%ld;1,%ld)",b,v->y.I,c); } v->name= gb_save_string(name_buf); v++; } /*:17*/ #line 254 "gb_raman.w" ;break; } /*:13*/ #line 100 "gb_raman.w" ; /*19:*/ #line 422 "gb_raman.w" gen= gb_typed_alloc(p+2,quaternion,working_storage); if(gen==NULL)late_panic(no_room+2); gen_count= 0;max_gen_count= p+1; if(p==2)/*25:*/ #line 584 "gb_raman.w" {long s= q_sqrt[q-2],t= (q_sqrt[13%q]*s)%q; gen[0].a0= 1;gen[0].a1= gen[0].a2= 0;gen[0].a3= q-1;gen[0].bar= 0; gen[1].a0= gen[2].a3= (2+s)%q; gen[1].a1= gen[1].a2= t; gen[2].a1= gen[2].a2= q-t; gen[1].a3= gen[2].a0= (q+2-s)%q; gen[1].bar= 2;gen[2].bar= 1; gen_count= 3; } /*:25*/ #line 426 "gb_raman.w" else/*21:*/ #line 454 "gb_raman.w" {long sa,sb; long pp= (p>>1)&1; for(a= 1-pp,sa= p-a;sa> 0;sa-= (a+1)<<2,a+= 2) for(b= pp,sb= sa-b,bb= sb-b-b;bb>=0;bb-= 12*(b+1),sb-= (b+1)<<2,b+= 2) for(c= b,cc= bb;cc>=0;cc-= (c+1)<<3,c+= 2) for(d= c,aa= cc;aa>=0;aa-= (d+1)<<2,d+= 2) if(aa==0)/*23:*/ #line 503 "gb_raman.w" { deposit(a,b,c,d); if(b){ deposit(a,-b,c,d);deposit(a,-b,-c,d); } if(c)deposit(a,b,-c,d); if(b=0;k--){ a00= (gen[k].a0+g*gen[k].a1+h*gen[k].a3)%q; if(a00<0)a00+= q; a11= (gen[k].a0-g*gen[k].a1-h*gen[k].a3)%q; if(a11<0)a11+= q; a01= (gen[k].a2+g*gen[k].a3-h*gen[k].a1)%q; if(a01<0)a01+= q; a10= (-gen[k].a2+g*gen[k].a3-h*gen[k].a1)%q; if(a10<0)a10+= q; gen[k].a0= a00;gen[k].a1= a01;gen[k].a2= a10;gen[k].a3= a11; } } /*:24*/ #line 462 "gb_raman.w" ; } /*:21*/ #line 428 "gb_raman.w" ; if(gen_count!=max_gen_count)late_panic(bad_specs+7); /*:19*/ #line 101 "gb_raman.w" ; /*26:*/ #line 629 "gb_raman.w" for(k= p;k>=0;k--){long kk; if((kk= gen[k].bar)<=k) for(v= new_graph->vertices;vvertices+n;v++){ register Vertex*u; /*27:*/ #line 663 "gb_raman.w" if(type<3)/*31:*/ #line 715 "gb_raman.w" if(type==1)u= new_graph->vertices+lin_frac(v->x.I,k); else{ a= lin_frac(v->x.I,k);aa= lin_frac(v->y.I,k); u= new_graph->vertices+(ax.I;b= v->y.I; if(v->z.I==q)c= 0,d= 1; else c= 1,d= v->z.I; /*28:*/ #line 676 "gb_raman.w" aa= (a*a00+b*a10)%q; bb= (a*a01+b*a11)%q; cc= (c*a00+d*a10)%q; dd= (c*a01+d*a11)%q; /*:28*/ #line 670 "gb_raman.w" ; a= (cc?q_inv[cc]:q_inv[dd]); d= (a*dd)%q;c= (a*cc)%q;b= (a*bb)%q;a= (a*aa)%q; /*29:*/ #line 682 "gb_raman.w" if(c==0)d= q,aa= a; else{ aa= (a*d-b)%q; if(aa<0)aa+= q; b= a; } u= new_graph->vertices+((d*q+b)*n_factor+(type==3?q_sqrt[aa]:aa)-1); /*:29*/ #line 673 "gb_raman.w" ; } /*:27*/ #line 635 "gb_raman.w" ; if(u==v){ if(!reduce){ gb_new_edge(v,v,1L); v->arcs->ref= kk;(v->arcs+1)->ref= k; } }else{register Arc*ap; if(u->arcs&&u->arcs->ref==kk) continue; else if(reduce) for(ap= v->arcs;ap;ap= ap->next) if(ap->tip==u)goto done; gb_new_edge(v,u,1L); v->arcs->ref= k;u->arcs->ref= kk; if((ap= v->arcs->next)!=NULL&&ap->ref==kk){ v->arcs->next= ap->next;ap->next= v->arcs;v->arcs= ap; } done:; } } } /*:26*/ #line 102 "gb_raman.w" ; if(gb_trouble_code) late_panic(alloc_fault); gb_free(working_storage); return new_graph; } /*:4*/