source: git/kernel/fast_mult.cc @ e95342

spielwiese
Last change on this file since e95342 was e95342, checked in by Michael Brickenstein <bricken@…>, 19 years ago
*bricken: memory leak removed git-svn-id: file:///usr/local/Singular/svn/trunk@7729 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 5.6 KB
Line 
1#include "fast_mult.h"
2#include "kbuckets.h"
3typedef poly fastmultrec(poly f, poly g, ring r);
4static const int pass_option=1;
5static int mults=0;
6int Mults(){
7  return mults;
8}
9static void degsplit(poly p,int n,poly &p1,poly&p2, int vn, ring r){
10  poly erg1_i, erg2_i;
11  erg1_i=NULL;
12  erg2_i=NULL;
13  while(p){
14    if(p_GetExp(p,vn,r)>=n){
15      if (p1==NULL){
16        p1=p;
17      } else{
18        pNext(erg1_i)=p;
19      }
20      erg1_i=p;
21    } else{
22      if (p2==NULL){
23        p2=p;
24      } else{
25        pNext(erg2_i)=p;
26      }
27      erg2_i=p;
28    }
29    p=pNext(p);
30  }
31  if(erg2_i){
32    pNext(erg2_i)=NULL;
33  }
34  if (erg1_i){
35    pNext(erg1_i)=NULL;
36  }
37 
38}
39static void div_by_x_power_n(poly p, int n, int vn, ring r){
40  while(p){
41    assume(p_GetExp(p,vn,r)>=n);
42    int e=p_GetExp(p,vn,r);
43    p_SetExp(p,vn,e-n,r);
44    p=pNext(p);
45  }
46}
47
48static poly do_unifastmult(poly f,int df,poly g,int dg, int vn, fastmultrec rec, ring r){
49  int n=1;
50  if ((f==NULL)||(g==NULL)) return NULL;
51  //int df=pGetExp(f,vn);//pFDeg(f);
52  //  int dg=pGetExp(g,vn);//pFDeg(g);
53       
54  int dm;
55  if(df>dg){
56    dm=df;
57  }else{
58    dm=dg;
59  }
60  while(n<=dm)
61    {
62      n*=2;
63    }
64  if(n==1){
65    return(pp_Mult_qq(f,g,r));
66  }
67 
68  int pot=n/2;
69  assume(pot*2==n);
70
71
72  //splitting
73  poly f1=NULL;
74  poly f0=NULL;//f-(x^(pot)*F1);
75  degsplit(p_Copy(f,r),pot,f1,f0,vn,r);
76  div_by_x_power_n(f1,pot,vn,r);
77
78  poly g1=NULL;
79  poly g0=NULL;
80  degsplit(p_Copy(g,r),pot,g1,g0,vn,r);
81  div_by_x_power_n(g1,pot,vn,r);
82 
83  //p00, p11
84  poly p00=rec(f0,g0,r);//unifastmult(f0,g0);
85  poly p11=rec(f1,g1,r);
86
87  //construct erg, factor
88  poly erg=NULL;
89  poly factor=p_ISet(1,r);
90
91  p_SetExp(factor,vn,n,r);
92  erg=pp_Mult_mm(p11,factor,r);
93  erg=p_Add_q(erg,p_Copy(p00,r),r);
94
95 
96
97
98 
99  if((f1!=NULL) &&(f0!=NULL) &&(g0!=NULL) && (g1!=NULL)){
100    //if(true){
101    //eat up f0,f1,g0,g1
102    poly s1=p_Add_q(f0,f1,r);
103    poly s2=p_Add_q(g0,g1,r);
104    poly pbig=rec(s1,s2,r);
105    p_Delete(&s1,r);
106    p_Delete(&s2,r);
107
108 
109    //eat up pbig
110    poly sum=pbig;
111    p_SetExp(factor,vn,pot,r);
112 
113    //eat up p00
114    sum=p_Add_q(sum,p_Neg(p00,r),r);
115 
116    //eat up p11
117    sum=p_Add_q(sum,p_Neg(p11,r),r);
118
119 
120    sum=p_Mult_mm(sum,factor,r);
121
122
123    //eat up sum
124    erg=p_Add_q(sum,erg,r);
125  } else {
126    //eat up f0,f1,g0,g1
127    poly s1=rec(f0,g1,r);
128    poly s2=rec(g0,f1,r);
129    p_SetExp(factor,vn,pot,r);
130    poly h=p_Mult_mm(((s1!=NULL)?s1:s2),factor,r);
131    p_Delete(&f1,r);
132    p_Delete(&f0,r);
133    p_Delete(&g0,r);
134    p_Delete(&g1,r);
135    p_Delete(&p00,r);
136    p_Delete(&p11,r);
137    erg=p_Add_q(erg,h,r);
138  }
139 
140 
141  p_Delete(&factor,r);
142                 
143                 
144
145  return(erg);
146}
147
148// poly do_unifastmult_buckets(poly f,poly g){
149   
150 
151
152
153//   int n=1;
154//   if ((f==NULL)||(g==NULL)) return NULL;
155//   int df=pGetExp(f,1);//pFDeg(f);
156//     int dg=pGetExp(g,1);//pFDeg(g);
157       
158//   int dm;
159//   if(df>dg){
160//     dm=df;
161//   }else{
162//     dm=dg;
163//   }
164//   while(n<=dm)
165//     {
166//       n*=2;
167//     }
168//   int pseudo_len=0;
169//   if(n==1){
170//     return ppMult_qq(f,g);
171
172//   }
173//   kBucket_pt erg_bucket= kBucketCreate(currRing);
174//   kBucketInit(erg_bucket,NULL,0 /*pLength(P.p)*/);
175
176//   int pot=n/2;
177//   assume(pot*2==n);
178
179
180//   //splitting
181//   poly f1=NULL;
182//   poly f0=NULL;//f-(x^(pot)*F1);
183//   degsplit(pCopy(f),pot,f1,f0);
184//   div_by_x_power_n(f1,pot);
185//   poly g1=NULL;
186//   poly g0=NULL;
187//   degsplit(pCopy(g),pot,g1,g0);
188//   div_by_x_power_n(g1,pot);
189 
190//   //p00
191//   //p11
192//   poly p00=unifastmult(f0,g0);
193//   poly p11=unifastmult(f1,g1);
194 
195
196
197
198//   //eat up f0,f1,g0,g1
199//   poly pbig=unifastmult(pAdd(f0,f1),pAdd(g0,g1)); 
200//   poly factor=pOne();//pCopy(erg_mult);
201//   pSetExp(factor,1,n);
202//   pseudo_len=0;
203//   kBucket_Add_q(erg_bucket,ppMult_mm(p11,factor),&pseudo_len);
204//   pseudo_len=0;
205//   kBucket_Add_q(erg_bucket,pCopy(p00),&pseudo_len);
206//   pSetExp(factor,1,pot);
207
208//   //eat up pbig
209//   pseudo_len=0;
210//   kBucket_Add_q(erg_bucket,pMult_mm(pbig,factor),&pseudo_len);
211//   pseudo_len=0;
212//   //eat up p00
213//   kBucket_Add_q(erg_bucket,pMult_mm(pNeg(p00),factor),&pseudo_len);
214//   pseudo_len=0;
215//   //eat up p11
216//   kBucket_Add_q(erg_bucket,pMult_mm(pNeg(p11),factor),&pseudo_len);
217
218 
219//   pseudo_len=0;
220
221 
222//   pDelete(&factor);
223
224//   int len=0;
225//   poly erg=NULL;
226//   kBucketClear(erg_bucket,&erg,&len);
227//   kBucketDestroy(&erg_bucket);
228
229//   return erg;
230// }
231
232static inline int max(int a, int b){
233  return (a>b)? a:b;
234}
235static inline int min(int a, int b){
236  return (a>b)? b:a;
237}
238poly unifastmult(poly f,poly g, ring r){
239  int vn=1;
240  if((f==NULL)||(g==NULL)) return NULL;
241  int df=p_GetExp(f,vn,r);
242  int dg=p_GetExp(g,vn,r);
243  if ((df==0)||(dg==0))
244    return pp_Mult_qq(f,g,r);
245  if (df*dg<100)
246    return pp_Mult_qq(f,g,r);
247  // if (df*dg>10000)
248  //  return
249  //    do_unifastmult_buckets(f,g);
250  //else
251  return do_unifastmult(f,df,g,dg,vn,unifastmult,r);
252
253}
254
255poly multifastmult(poly f, poly g, ring r){
256  mults++;
257  if((f==NULL)||(g==NULL)) return NULL;
258  if (pLength(f)*pLength(g)<100)
259    return pp_Mult_qq(f,g,r);
260  //find vn
261  //determine df,dg simultaneously
262  int i;
263  int can_i=-1;
264  int can_df=0;
265  int can_dg=0;
266  int can_crit=0;
267  for(i=1;i<=rVar(r);i++){
268    poly p;
269    int df=0;
270    int dg=0;
271    //max min max Strategie
272    p=f;
273    while(p){
274      df=max(df,p_GetExp(p,i,r));
275      p=pNext(p);
276    }
277    if(df>can_crit){
278      p=g;
279      while(p){
280        dg=max(dg,p_GetExp(p,i,r));
281        p=pNext(p);
282      }
283      int crit=min(df,dg);
284      if (crit>can_crit){
285        can_crit=crit;
286        can_i=i;
287        can_df=df;
288        can_dg=dg;
289      }
290    }
291  }
292  if(can_crit==0)
293    return pp_Mult_qq(f,g,r);
294  else
295    {
296      poly erg=do_unifastmult(f,can_df,g,can_dg,can_i,multifastmult,r);
297      p_Normalize(erg,r);
298      return(erg);
299    }
300}
Note: See TracBrowser for help on using the repository browser.