1 | #include "fast_mult.h" |
---|
2 | #include "kbuckets.h" |
---|
3 | typedef poly fastmultrec(poly f, poly g); |
---|
4 | static const int pass_option=1; |
---|
5 | static void degsplit(poly p,int n,poly &p1,poly&p2, int vn){ |
---|
6 | poly erg1_i, erg2_i; |
---|
7 | erg1_i=NULL; |
---|
8 | erg2_i=NULL; |
---|
9 | while(p){ |
---|
10 | if(pGetExp(p,vn)>=n){ |
---|
11 | if (p1==NULL){ |
---|
12 | p1=p; |
---|
13 | } else{ |
---|
14 | pNext(erg1_i)=p; |
---|
15 | } |
---|
16 | erg1_i=p; |
---|
17 | } else{ |
---|
18 | if (p2==NULL){ |
---|
19 | p2=p; |
---|
20 | } else{ |
---|
21 | pNext(erg2_i)=p; |
---|
22 | } |
---|
23 | erg2_i=p; |
---|
24 | } |
---|
25 | p=pNext(p); |
---|
26 | } |
---|
27 | if(erg2_i){ |
---|
28 | pNext(erg2_i)=NULL; |
---|
29 | } |
---|
30 | if (erg1_i){ |
---|
31 | pNext(erg1_i)=NULL; |
---|
32 | } |
---|
33 | |
---|
34 | } |
---|
35 | static void div_by_x_power_n(poly p, int n, int vn){ |
---|
36 | while(p){ |
---|
37 | assume(pGetExp(p,vn)>=n); |
---|
38 | int e=pGetExp(p,vn); |
---|
39 | pSetExp(p,vn,e-n); |
---|
40 | p=pNext(p); |
---|
41 | } |
---|
42 | } |
---|
43 | |
---|
44 | poly do_unifastmult(poly f,int df,poly g,int dg, int vn, fastmultrec rec){ |
---|
45 | int n=1; |
---|
46 | if ((f==NULL)||(g==NULL)) return NULL; |
---|
47 | //int df=pGetExp(f,vn);//pFDeg(f); |
---|
48 | // int dg=pGetExp(g,vn);//pFDeg(g); |
---|
49 | |
---|
50 | int dm; |
---|
51 | if(df>dg){ |
---|
52 | dm=df; |
---|
53 | }else{ |
---|
54 | dm=dg; |
---|
55 | } |
---|
56 | while(n<=dm) |
---|
57 | { |
---|
58 | n*=2; |
---|
59 | } |
---|
60 | if(n==1){ |
---|
61 | return(ppMult_qq(f,g)); |
---|
62 | } |
---|
63 | |
---|
64 | int pot=n/2; |
---|
65 | assume(pot*2==n); |
---|
66 | |
---|
67 | |
---|
68 | //splitting |
---|
69 | poly f1=NULL; |
---|
70 | poly f0=NULL;//f-(x^(pot)*F1); |
---|
71 | degsplit(pCopy(f),pot,f1,f0,vn); |
---|
72 | div_by_x_power_n(f1,pot,vn); |
---|
73 | |
---|
74 | poly g1=NULL; |
---|
75 | poly g0=NULL; |
---|
76 | degsplit(pCopy(g),pot,g1,g0,vn); |
---|
77 | div_by_x_power_n(g1,pot,vn); |
---|
78 | |
---|
79 | //p00, p11 |
---|
80 | poly p00=rec(f0,g0);//unifastmult(f0,g0); |
---|
81 | poly p11=rec(f1,g1); |
---|
82 | |
---|
83 | //construct erg, factor |
---|
84 | poly erg=NULL; |
---|
85 | poly factor=pOne(); |
---|
86 | |
---|
87 | pSetExp(factor,vn,n); |
---|
88 | erg=ppMult_mm(p11,factor); |
---|
89 | erg=pAdd(erg,pCopy(p00)); |
---|
90 | |
---|
91 | |
---|
92 | |
---|
93 | |
---|
94 | |
---|
95 | if((f1!=NULL) &&(f0!=NULL) &&(g0!=NULL) && (g1!=NULL)){ |
---|
96 | //if(true){ |
---|
97 | //eat up f0,f1,g0,g1 |
---|
98 | poly s1=pAdd(f0,f1); |
---|
99 | poly s2=pAdd(g0,g1); |
---|
100 | poly pbig=rec(s1,s2); |
---|
101 | pDelete(&s1); |
---|
102 | pDelete(&s2); |
---|
103 | |
---|
104 | |
---|
105 | //eat up pbig |
---|
106 | poly sum=pbig; |
---|
107 | pSetExp(factor,vn,pot); |
---|
108 | |
---|
109 | //eat up p00 |
---|
110 | sum=pAdd(sum,pNeg(p00)); |
---|
111 | |
---|
112 | //eat up p11 |
---|
113 | sum=pAdd(sum,pNeg(p11)); |
---|
114 | |
---|
115 | |
---|
116 | sum=pMult_mm(sum,factor); |
---|
117 | |
---|
118 | |
---|
119 | //eat up sum |
---|
120 | erg=pAdd(sum,erg); |
---|
121 | } else { |
---|
122 | //eat up f0,f1,g0,g1 |
---|
123 | poly s1=unifastmult(f0,g1); |
---|
124 | poly s2=unifastmult(g0,f1); |
---|
125 | pSetExp(factor,vn,pot); |
---|
126 | poly h=pMult_mm(((s1!=NULL)?s1:s2),factor); |
---|
127 | pDelete(&f1); |
---|
128 | pDelete(&f0); |
---|
129 | pDelete(&g0); |
---|
130 | pDelete(&g1); |
---|
131 | erg=pAdd(erg,h); |
---|
132 | } |
---|
133 | |
---|
134 | |
---|
135 | pDelete(&factor); |
---|
136 | |
---|
137 | |
---|
138 | |
---|
139 | return(erg); |
---|
140 | } |
---|
141 | |
---|
142 | // poly do_unifastmult_buckets(poly f,poly g){ |
---|
143 | |
---|
144 | |
---|
145 | |
---|
146 | |
---|
147 | // int n=1; |
---|
148 | // if ((f==NULL)||(g==NULL)) return NULL; |
---|
149 | // int df=pGetExp(f,1);//pFDeg(f); |
---|
150 | // int dg=pGetExp(g,1);//pFDeg(g); |
---|
151 | |
---|
152 | // int dm; |
---|
153 | // if(df>dg){ |
---|
154 | // dm=df; |
---|
155 | // }else{ |
---|
156 | // dm=dg; |
---|
157 | // } |
---|
158 | // while(n<=dm) |
---|
159 | // { |
---|
160 | // n*=2; |
---|
161 | // } |
---|
162 | // int pseudo_len=0; |
---|
163 | // if(n==1){ |
---|
164 | // return ppMult_qq(f,g); |
---|
165 | |
---|
166 | // } |
---|
167 | // kBucket_pt erg_bucket= kBucketCreate(currRing); |
---|
168 | // kBucketInit(erg_bucket,NULL,0 /*pLength(P.p)*/); |
---|
169 | |
---|
170 | // int pot=n/2; |
---|
171 | // assume(pot*2==n); |
---|
172 | |
---|
173 | |
---|
174 | // //splitting |
---|
175 | // poly f1=NULL; |
---|
176 | // poly f0=NULL;//f-(x^(pot)*F1); |
---|
177 | // degsplit(pCopy(f),pot,f1,f0); |
---|
178 | // div_by_x_power_n(f1,pot); |
---|
179 | // poly g1=NULL; |
---|
180 | // poly g0=NULL; |
---|
181 | // degsplit(pCopy(g),pot,g1,g0); |
---|
182 | // div_by_x_power_n(g1,pot); |
---|
183 | |
---|
184 | // //p00 |
---|
185 | // //p11 |
---|
186 | // poly p00=unifastmult(f0,g0); |
---|
187 | // poly p11=unifastmult(f1,g1); |
---|
188 | |
---|
189 | |
---|
190 | |
---|
191 | |
---|
192 | // //eat up f0,f1,g0,g1 |
---|
193 | // poly pbig=unifastmult(pAdd(f0,f1),pAdd(g0,g1)); |
---|
194 | // poly factor=pOne();//pCopy(erg_mult); |
---|
195 | // pSetExp(factor,1,n); |
---|
196 | // pseudo_len=0; |
---|
197 | // kBucket_Add_q(erg_bucket,ppMult_mm(p11,factor),&pseudo_len); |
---|
198 | // pseudo_len=0; |
---|
199 | // kBucket_Add_q(erg_bucket,pCopy(p00),&pseudo_len); |
---|
200 | // pSetExp(factor,1,pot); |
---|
201 | |
---|
202 | // //eat up pbig |
---|
203 | // pseudo_len=0; |
---|
204 | // kBucket_Add_q(erg_bucket,pMult_mm(pbig,factor),&pseudo_len); |
---|
205 | // pseudo_len=0; |
---|
206 | // //eat up p00 |
---|
207 | // kBucket_Add_q(erg_bucket,pMult_mm(pNeg(p00),factor),&pseudo_len); |
---|
208 | // pseudo_len=0; |
---|
209 | // //eat up p11 |
---|
210 | // kBucket_Add_q(erg_bucket,pMult_mm(pNeg(p11),factor),&pseudo_len); |
---|
211 | |
---|
212 | |
---|
213 | // pseudo_len=0; |
---|
214 | |
---|
215 | |
---|
216 | // pDelete(&factor); |
---|
217 | |
---|
218 | // int len=0; |
---|
219 | // poly erg=NULL; |
---|
220 | // kBucketClear(erg_bucket,&erg,&len); |
---|
221 | // kBucketDestroy(&erg_bucket); |
---|
222 | |
---|
223 | // return erg; |
---|
224 | // } |
---|
225 | poly unifastmult(poly f,poly g){ |
---|
226 | int vn=1; |
---|
227 | if((f==NULL)||(g==NULL)) return NULL; |
---|
228 | int df=pGetExp(f,vn); |
---|
229 | int dg=pGetExp(g,vn); |
---|
230 | if ((df==0)||(dg==0)) |
---|
231 | return ppMult_qq(f,g); |
---|
232 | if (df*dg<100) |
---|
233 | return ppMult_qq(f,g); |
---|
234 | // if (df*dg>10000) |
---|
235 | // return |
---|
236 | // do_unifastmult_buckets(f,g); |
---|
237 | //else |
---|
238 | return do_unifastmult(f,df,g,dg,vn,unifastmult); |
---|
239 | |
---|
240 | } |
---|
241 | |
---|