| version 1.18, 2001/10/09 01:36:10 | 
version 1.33, 2015/08/14 13:51:54 | 
 | 
 | 
|  /* $OpenXM: OpenXM_contrib2/asir2000/engine/Hgfs.c,v 1.17 2001/09/03 07:01:06 noro Exp $ */ | 
 /* $OpenXM: OpenXM_contrib2/asir2000/engine/Hgfs.c,v 1.32 2015/08/08 14:19:41 fujimoto Exp $ */ | 
|   | 
  | 
|  #include "ca.h" | 
 #include "ca.h" | 
|   | 
 #include "inline.h" | 
|   | 
  | 
|   | 
 int debug_sfbfctr; | 
|   | 
  | 
|  void lnfsf(int n,UM p0,UM p1,struct p_pair *list,UM np0,UM np1); | 
 void lnfsf(int n,UM p0,UM p1,struct p_pair *list,UM np0,UM np1); | 
|   | 
 void extractcoefbm(BM f,int dx,UM r); | 
|   | 
  | 
|  int comp_dum(DUM a,DUM b) | 
 int comp_dum(DUM a,DUM b) | 
|  { | 
 { | 
| Line 14  int comp_dum(DUM a,DUM b) | 
 
  | 
| Line 18  int comp_dum(DUM a,DUM b) | 
 
 
 | 
|                  return 0; | 
                 return 0; | 
|  } | 
 } | 
|   | 
  | 
|  void fctrsf(P p,DCP *dcp) | 
 void ufctrsf(P p,DCP *dcp) | 
|  { | 
 { | 
|          int n,i,j,k; | 
         int n,i,j,k; | 
|          DCP dc,dc0; | 
         DCP dc,dc0; | 
| Line 26  void fctrsf(P p,DCP *dcp) | 
 
  | 
| Line 30  void fctrsf(P p,DCP *dcp) | 
 
 
 | 
|   | 
  | 
|          simp_ff((Obj)p,&obj); p = (P)obj; | 
         simp_ff((Obj)p,&obj); p = (P)obj; | 
|          if ( !p ) { | 
         if ( !p ) { | 
|                  *dcp = 0; return; | 
                 NEWDC(dc); COEF(dc) = 0; DEG(dc) = ONE; | 
|   | 
                 NEXT(dc) = 0; *dcp = dc; | 
|   | 
                 return; | 
|          } | 
         } | 
|          mp = W_UMALLOC(UDEG(p)); | 
         mp = W_UMALLOC(UDEG(p)); | 
|          ptosfum(p,mp); | 
         ptosfum(p,mp); | 
| Line 75  void gensqfrsfum(UM p,struct oDUM *dc) | 
 
  | 
| Line 81  void gensqfrsfum(UM p,struct oDUM *dc) | 
 
 
 | 
|  { | 
 { | 
|          int n,i,j,d,mod; | 
         int n,i,j,d,mod; | 
|          UM t,s,g,f,f1,b; | 
         UM t,s,g,f,f1,b; | 
|   | 
         GFS u,v; | 
|   | 
  | 
|          if ( (n = DEG(p)) == 1 ) { | 
         if ( (n = DEG(p)) == 1 ) { | 
|                  dc[0].f = UMALLOC(DEG(p)); cpyum(p,dc[0].f); dc[0].n = 1; | 
                 dc[0].f = UMALLOC(DEG(p)); cpyum(p,dc[0].f); dc[0].n = 1; | 
| Line 113  void gensqfrsfum(UM p,struct oDUM *dc) | 
 
  | 
| Line 120  void gensqfrsfum(UM p,struct oDUM *dc) | 
 
 
 | 
|                                  break; | 
                                 break; | 
|                          else { | 
                         else { | 
|                                  DEG(s) = DEG(t)/mod; | 
                                 DEG(s) = DEG(t)/mod; | 
|                                  for ( j = 0; j <= DEG(t); j++ ) | 
                                 for ( j = 0; j <= DEG(t); j++ ) { | 
|                                          COEF(s)[j] = COEF(t)[j*mod]; | 
                                         iftogfs(COEF(t)[j*mod],&u); | 
|   | 
                                         pthrootgfs(u,&v); | 
|   | 
                                         COEF(s)[j] = v?FTOIF(CONT(v)):0; | 
|   | 
                                 } | 
|                                  cpyum(s,b); d *= mod; | 
                                 cpyum(s,b); d *= mod; | 
|                          } | 
                         } | 
|                  } | 
                 } | 
| Line 502  void canzassf(UM f,int d,UM *r) | 
 
  | 
| Line 512  void canzassf(UM f,int d,UM *r) | 
 
 
 | 
|   | 
  | 
|  /* Hensel related functions */ | 
 /* Hensel related functions */ | 
|   | 
  | 
|  int sfberle(VL,P,int,GFS *,DCP *); | 
 int sfberle(V,V,P,int,GFS *,DCP *); | 
|  void sfgcdgen(P,ML,ML *); | 
 void sfgcdgen(P,ML,ML *); | 
|  void sfhenmain2(BM,UM,UM,int,BM *); | 
 void sfhenmain2(BM,UM,UM,int,BM *); | 
|  void ptosfbm(int,P,BM); | 
 void ptosfbm(int,P,BM); | 
|   | 
 void sfhensel(int count,P f,V x,V y,int degbound,GFS *evp,P *sfp,ML *listp); | 
|   | 
  | 
|  /* f = f(x,y) */ | 
 /* f = f(x,y) */ | 
|   | 
  | 
|  void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *listp) | 
 void sfhensel(int count,P f,V x,V y,int degbound,GFS *evp,P *sfp,ML *listp) | 
|  { | 
 { | 
|          int i; | 
         int i; | 
|          int fn; | 
         int fn; | 
|          ML rlist; | 
         ML rlist; | 
|          BM fl; | 
         BM fl; | 
|          VL vl,nvl; | 
         VL vl,nvl; | 
|          V y; | 
         int dx,dy,bound; | 
|          int dx,dy; | 
  | 
|          GFS ev; | 
         GFS ev; | 
|          P f1,t,c,sf; | 
         P f1,t,c,sf; | 
|          DCP dc; | 
         DCP dc,dct,dc0; | 
|          UM q,fm,hm; | 
         UM q,fm,hm; | 
|          UM *gm; | 
         UM *gm; | 
|          struct oEGT tmp0,tmp1,eg_hensel,eg_hensel_t; | 
         struct oEGT tmp0,tmp1,eg_hensel,eg_hensel_t; | 
| Line 530  void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *li | 
 
  | 
| Line 540  void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *li | 
 
 
 | 
|                  reordvar(vl,x,&nvl); reorderp(nvl,vl,f,&f1); | 
                 reordvar(vl,x,&nvl); reorderp(nvl,vl,f,&f1); | 
|                  vl = nvl; f = f1; | 
                 vl = nvl; f = f1; | 
|          } | 
         } | 
|          y = vl->next->v; | 
         if ( vl->next ) | 
|   | 
                 y = vl->next->v; | 
|          dx = getdeg(x,f); | 
         dx = getdeg(x,f); | 
|          dy = getdeg(y,f); | 
         dy = getdeg(y,f); | 
|          if ( dx == 1 ) { | 
         if ( dx == 1 ) { | 
|                  *listp = rlist = MLALLOC(1); rlist->n = 1; rlist->c[0] = 0; | 
                 *listp = rlist = MLALLOC(1); rlist->n = 1; rlist->c[0] = 0; | 
|                  return; | 
                 return; | 
|          } | 
         } | 
|          fn = sfberle(vl,f,count,&ev,&dc); | 
         fn = sfberle(x,y,f,count,&ev,&dc); | 
|          if ( fn <= 1 ) { | 
         if ( fn <= 1 ) { | 
|                  /* fn == 0 => short of evaluation points */ | 
                 /* fn == 0 => short of evaluation points */ | 
|                  *listp = rlist = MLALLOC(1); rlist->n = fn; rlist->c[0] = 0; | 
                 *listp = rlist = MLALLOC(1); rlist->n = fn; rlist->c[0] = 0; | 
|                  return; | 
                 return; | 
|          } | 
         } | 
|          /* pass the the leading coeff. to the first element */ | 
         if ( degbound >= 0 ) { | 
|          c = dc->c; dc = NEXT(dc); | 
                 /* | 
|          mulp(vl,dc->c,c,&t); dc->c = t; | 
                  * reconstruct dc so that | 
|   | 
                  * dc[1],... : factors satisfy degree bound | 
|   | 
                  * dc[0]     : product of others | 
|   | 
                  */ | 
|   | 
                 c = dc->c; dc = NEXT(dc); | 
|   | 
                 dc0 = 0; | 
|   | 
                 fn = 0; | 
|   | 
                 while ( dc ) { | 
|   | 
                         if ( getdeg(x,COEF(dc)) <= degbound ) { | 
|   | 
                                 dct = NEXT(dc); NEXT(dc) = dc0; dc0 = dc; dc = dct; | 
|   | 
                                 fn++; | 
|   | 
                         } else { | 
|   | 
                                 mulp(vl,COEF(dc),c,&t); c = t; | 
|   | 
                                 dc = NEXT(dc); | 
|   | 
                         } | 
|   | 
                 } | 
|   | 
                 if ( OID(c) == O_P ) { | 
|   | 
                         NEWDC(dc); COEF(dc) = c; DEG(dc) = ONE; NEXT(dc) = dc0; | 
|   | 
                         fn++; | 
|   | 
                 } else { | 
|   | 
                         mulp(vl,dc0->c,c,&t); dc0->c = t; dc = dc0; | 
|   | 
                 } | 
|   | 
         } else { | 
|   | 
                 /* pass the the leading coeff. to the first element */ | 
|   | 
                 c = dc->c; dc = NEXT(dc); | 
|   | 
                 mulp(vl,dc->c,c,&t); dc->c = t; | 
|   | 
         } | 
|   | 
  | 
|          /* convert mod y-a factors into UM */ | 
         /* convert mod y-a factors into UM */ | 
|          gm = (UM *)ALLOCA(fn*sizeof(UM)); | 
         gm = (UM *)ALLOCA(fn*sizeof(UM)); | 
| Line 554  void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *li | 
 
  | 
| Line 591  void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *li | 
 
 
 | 
|                  ptosfum(dc->c,gm[i]); | 
                 ptosfum(dc->c,gm[i]); | 
|          } | 
         } | 
|   | 
  | 
|   | 
         /* set bound */ | 
|   | 
         /* g | f, lc_y(g) = lc_y(f) => deg_y(g) <= deg_y(f) */ | 
|   | 
         /* so, bound = dy is sufficient, but we use slightly large value */ | 
|   | 
         bound = dy+2; | 
|   | 
  | 
|          /* f(x,y) -> f(x,y+ev) */ | 
         /* f(x,y) -> f(x,y+ev) */ | 
|          fl = BMALLOC(dx,dy); | 
         fl = BMALLOC(dx,bound); | 
|          ptosfbm(dy,f,fl); | 
         ptosfbm(bound,f,fl); | 
|          if ( ev ) shiftsfbm(fl,FTOIF(CONT(ev))); | 
         if ( ev ) shiftsfbm(fl,FTOIF(CONT(ev))); | 
|   | 
  | 
|          /* sf = f(x+ev) */ | 
         /* sf = f(x+ev) */ | 
| Line 568  void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *li | 
 
  | 
| Line 610  void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *li | 
 
 
 | 
|          hm = W_UMALLOC(dx); | 
         hm = W_UMALLOC(dx); | 
|   | 
  | 
|          q = W_UMALLOC(dx); | 
         q = W_UMALLOC(dx); | 
|          rlist = MLALLOC(fn); rlist->n = fn; rlist->bound = dy; | 
         rlist = MLALLOC(fn); rlist->n = fn; rlist->bound = bound; | 
|          fprintf(asir_out,"%d candidates\n",fn); | 
         if ( debug_sfbfctr ) | 
|   | 
                 fprintf(asir_out,"%d candidates\n",fn); | 
|          init_eg(&eg_hensel); | 
         init_eg(&eg_hensel); | 
|          for ( i = 0; i < fn-1; i++ ) { | 
         for ( i = 0; i < fn-1; i++ ) { | 
|                  fprintf(asir_out,"deg(fm) = %d, deg(gm[%d]) = %d\n", | 
                 if ( debug_sfbfctr ) | 
|   | 
                         fprintf(asir_out,"deg(fm) = %d, deg(gm[%d]) = %d\n", | 
|                          DEG(fm),i,DEG(gm[i])); | 
                         DEG(fm),i,DEG(gm[i])); | 
|                  init_eg(&eg_hensel_t); | 
                 init_eg(&eg_hensel_t); | 
|                  get_eg(&tmp0); | 
                 get_eg(&tmp0); | 
|                  /* fl = gm[i]*hm mod y */ | 
                 /* fl = gm[i]*hm mod y */ | 
|                  divsfum(fm,gm[i],hm); | 
                 divsfum(fm,gm[i],hm); | 
|                  /* fl is replaced by the cofactor of gk mod y^dy */ | 
                 /* fl is replaced by the cofactor of gk mod y^bound */ | 
|                  /* rlist->c[i] = gk */ | 
                 /* rlist->c[i] = gk */ | 
|                  sfhenmain2(fl,gm[i],hm,dy,(BM *)&rlist->c[i]); | 
                 sfhenmain2(fl,gm[i],hm,bound,(BM *)&rlist->c[i]); | 
|                  cpyum(hm,fm); | 
                 cpyum(hm,fm); | 
|                  get_eg(&tmp1); add_eg(&eg_hensel_t,&tmp0,&tmp1); | 
                 get_eg(&tmp1); add_eg(&eg_hensel_t,&tmp0,&tmp1); | 
|                  add_eg(&eg_hensel,&tmp0,&tmp1); | 
                 add_eg(&eg_hensel,&tmp0,&tmp1); | 
|                  print_eg("Hensel",&eg_hensel_t); | 
                 if ( debug_sfbfctr) { | 
|   | 
                         print_eg("Hensel",&eg_hensel_t); | 
|   | 
                         fprintf(asir_out,"\n"); | 
|   | 
                 } | 
|   | 
         } | 
|   | 
         if ( debug_sfbfctr) { | 
|   | 
                 print_eg("Hensel total",&eg_hensel); | 
|                  fprintf(asir_out,"\n"); | 
                 fprintf(asir_out,"\n"); | 
|          } | 
         } | 
|          print_eg("Hensel total",&eg_hensel); | 
  | 
|          fprintf(asir_out,"\n"); | 
  | 
|          /* finally, fl must be the lift of gm[fn-1] */ | 
         /* finally, fl must be the lift of gm[fn-1] */ | 
|          rlist->c[i] = fl; | 
         rlist->c[i] = fl; | 
|   | 
  | 
| Line 605  void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *li | 
 
  | 
| Line 653  void sfhensel(int count,P f,V x,GFS *evp,P *sfp,ML *li | 
 
 
 | 
|   | 
  | 
|  /* main variable of f = x */ | 
 /* main variable of f = x */ | 
|   | 
  | 
|  int sfberle(VL vl,P f,int count,GFS *ev,DCP *dcp) | 
 int sfberle(V x,V y,P f,int count,GFS *ev,DCP *dcp) | 
|  { | 
 { | 
|          UM wf,wf1,wf2,wfs,gcd; | 
         UM wf,wf1,wf2,wfs,gcd; | 
|          int fn,n; | 
         int fn,n; | 
|          GFS m,fm; | 
         GFS m,fm; | 
|          DCP dc,dct,dc0; | 
         DCP dc,dct,dc0; | 
|          VL nvl; | 
         VL vl; | 
|          V x,y; | 
  | 
|          P lc,lc0,f0; | 
         P lc,lc0,f0; | 
|          Obj obj; | 
         Obj obj; | 
|          int j,q1,index,i; | 
         int j,q,index,i; | 
|   | 
  | 
|          clctv(vl,f,&nvl); vl = nvl; | 
         NEWVL(vl); vl->v = x; | 
|          x = vl->v; y = vl->next->v; | 
         NEWVL(NEXT(vl)); NEXT(vl)->v = y; | 
|   | 
         NEXT(NEXT(vl)) =0; | 
|          simp_ff((Obj)f,&obj); f = (P)obj; | 
         simp_ff((Obj)f,&obj); f = (P)obj; | 
|          n = QTOS(DEG(DC(f))); | 
         n = QTOS(DEG(DC(f))); | 
|          wf = W_UMALLOC(n); wf1 = W_UMALLOC(n); wf2 = W_UMALLOC(n); | 
         wf = W_UMALLOC(n); wf1 = W_UMALLOC(n); wf2 = W_UMALLOC(n); | 
|          wfs = W_UMALLOC(n); gcd = W_UMALLOC(n); | 
         wfs = W_UMALLOC(n); gcd = W_UMALLOC(n); | 
|          q1 = field_order_sf()-1; | 
         q = field_order_sf(); | 
|          lc = DC(f)->c; | 
         lc = DC(f)->c; | 
|          for ( j = 0, fn = n + 1, index = 0; | 
         for ( j = 0, fn = n + 1, index = 0; | 
|                  index < q1 && j < count && fn > 1; index++ ) { | 
                 index < q && j < count && fn > 1; index++ ) { | 
|                  MKGFS(index,m); | 
                 indextogfs(index,&m); | 
|                  substp(vl,lc,y,(P)m,&lc0); | 
                 substp(vl,lc,y,(P)m,&lc0); | 
|                  if ( lc0 ) { | 
                 if ( lc0 ) { | 
|                          substp(vl,f,y,(P)m,&f0); | 
                         substp(vl,f,y,(P)m,&f0); | 
|                          ptosfum(f0,wf); cpyum(wf,wf1); | 
                         ptosfum(f0,wf); cpyum(wf,wf1); | 
|                          diffsfum(wf1,wf2); gcdsfum(wf1,wf2,gcd); | 
                         diffsfum(wf1,wf2); gcdsfum(wf1,wf2,gcd); | 
|                          if ( DEG(gcd) == 0 ) { | 
                         if ( DEG(gcd) == 0 ) { | 
|                                  fctrsf(f0,&dc); | 
                                 ufctrsf(f0,&dc); | 
|                                  for ( dct = NEXT(dc), i = 0; dct; dct = NEXT(dct), i++ ); | 
                                 for ( dct = NEXT(dc), i = 0; dct; dct = NEXT(dct), i++ ); | 
|                                  if ( i < fn ) { | 
                                 if ( i < fn ) { | 
|                                          dc0 = dc; fn = i; fm = m; | 
                                         dc0 = dc; fn = i; fm = m; | 
| Line 643  int sfberle(VL vl,P f,int count,GFS *ev,DCP *dcp) | 
 
  | 
| Line 691  int sfberle(VL vl,P f,int count,GFS *ev,DCP *dcp) | 
 
 
 | 
|                          } | 
                         } | 
|                  } | 
                 } | 
|          } | 
         } | 
|          if ( index == q1 ) | 
         if ( index == q ) | 
|                  return 0; | 
                 return 0; | 
|          else if ( fn == 1 ) | 
         else if ( fn == 1 ) | 
|                  return 1; | 
                 return 1; | 
| Line 721  void sfhenmain2(BM f,UM g0,UM h0,int dy,BM *gp) | 
 
  | 
| Line 769  void sfhenmain2(BM f,UM g0,UM h0,int dy,BM *gp) | 
 
 
 | 
|          wa = W_UMALLOC(2*dx); wb = W_UMALLOC(2*dx);  /* XXX */ | 
         wa = W_UMALLOC(2*dx); wb = W_UMALLOC(2*dx);  /* XXX */ | 
|          eucsfum(w1,w2,wa,wb); | 
         eucsfum(w1,w2,wa,wb); | 
|   | 
  | 
|          fprintf(stderr,"dy=%d\n",dy); | 
         if ( debug_sfbfctr) | 
|   | 
                 fprintf(stderr,"dy=%d\n",dy); | 
|          for ( k = 1; k <= dy; k++ ) { | 
         for ( k = 1; k <= dy; k++ ) { | 
|                  fprintf(stderr,"."); | 
                 if ( debug_sfbfctr) | 
|   | 
                         fprintf(stderr,"."); | 
|   | 
  | 
|                  /* at this point, f = gk*hk mod y^k */ | 
                 /* at this point, f = gk*hk mod y^k */ | 
|   | 
  | 
| Line 779  void sfhenmain2(BM f,UM g0,UM h0,int dy,BM *gp) | 
 
  | 
| Line 829  void sfhenmain2(BM f,UM g0,UM h0,int dy,BM *gp) | 
 
 
 | 
|                  cpyum(wg1,COEF(gk)[k]); | 
                 cpyum(wg1,COEF(gk)[k]); | 
|                  cpyum(wh1,COEF(hk)[k]); | 
                 cpyum(wh1,COEF(hk)[k]); | 
|          } | 
         } | 
|          fprintf(stderr,"\n"); | 
         if ( debug_sfbfctr) | 
|   | 
                 fprintf(stderr,"\n"); | 
|          *gp = gk; | 
         *gp = gk; | 
|          DEG(f) = dy; | 
         DEG(f) = dy; | 
|          for ( i = 0; i <= dy; i++ ) | 
         for ( i = 0; i <= dy; i++ ) | 
|                  cpyum(COEF(hk)[i],COEF(f)[i]); | 
                 cpyum(COEF(hk)[i],COEF(f)[i]); | 
|  } | 
 } | 
|   | 
  | 
|   | 
 /* a0*g+b0*h = 1 mod y -> a*g+b*h = 1 mod y^(dy+1) */ | 
|   | 
  | 
|   | 
 void sfexgcd_by_hensel(BM g,BM h,int dy,BM *ap,BM *bp) | 
|   | 
 { | 
|   | 
         int i,k; | 
|   | 
         int dx; | 
|   | 
         UM wt,wa,wb,q,w1,w2,ws; | 
|   | 
         UM wc,wd,we,wz,wa1,wb1; | 
|   | 
         BM wz0,wz1; | 
|   | 
         int dg,dh; | 
|   | 
         BM a,b,c; | 
|   | 
  | 
|   | 
         dg = degbm(g); | 
|   | 
         dh = degbm(h); | 
|   | 
         dx = dg+dh; | 
|   | 
  | 
|   | 
         a = BMALLOC(dh,dy); | 
|   | 
         b = BMALLOC(dg,dy); | 
|   | 
         /* c holds a*g+b*h-1 */ | 
|   | 
         c = BMALLOC(dg+dh,dy); | 
|   | 
  | 
|   | 
         W_BMALLOC(dx,dy,wz0); W_BMALLOC(dx,dy,wz1); | 
|   | 
  | 
|   | 
         wt = W_UMALLOC(dx); ws = W_UMALLOC(dx); q = W_UMALLOC(2*dx); | 
|   | 
         wa1 = W_UMALLOC(2*dx); wb1 = W_UMALLOC(2*dx); | 
|   | 
         wc = W_UMALLOC(2*dx); wd = W_UMALLOC(2*dx); | 
|   | 
         we = W_UMALLOC(2*dx); wz = W_UMALLOC(2*dx); | 
|   | 
  | 
|   | 
         /* compute wa,wb s.t. wa*g0+wb*h0 = 1 mod y */ | 
|   | 
         w1 = W_UMALLOC(dg); cpyum(COEF(g)[0],w1); | 
|   | 
         w2 = W_UMALLOC(dh); cpyum(COEF(h)[0],w2); | 
|   | 
         wa = W_UMALLOC(2*dx); wb = W_UMALLOC(2*dx);  /* XXX */ | 
|   | 
         eucsfum(w1,w2,wa,wb); | 
|   | 
         cpyum(wa,COEF(a)[0]); cpyum(wb,COEF(b)[0]); | 
|   | 
  | 
|   | 
         /* initialize c to a*g+b*h-1 */ | 
|   | 
         mulsfbm(a,g,c); mulsfbm(b,h,wz0); addtosfbm(wz0,c); | 
|   | 
         COEF(COEF(c)[0])[0] = 0; | 
|   | 
  | 
|   | 
         if ( debug_sfbfctr) | 
|   | 
                 fprintf(stderr,"dy=%d\n",dy); | 
|   | 
         for ( k = 1; k <= dy; k++ ) { | 
|   | 
                 if ( debug_sfbfctr) | 
|   | 
                         fprintf(stderr,"."); | 
|   | 
  | 
|   | 
                 /* at this point, a*g+b*h = 1 mod y^k, c = a*g+b*h-1 */ | 
|   | 
  | 
|   | 
                 /* wt = -((a*g+b*h-1)/y^k) */ | 
|   | 
                 cpyum(COEF(c)[k],wt); | 
|   | 
                 for ( i = DEG(wt); i >= 0; i-- ) | 
|   | 
                         COEF(wt)[i] = _chsgnsf(COEF(wt)[i]); | 
|   | 
  | 
|   | 
                 /* compute wa1,wb1 s.t. wa1*g0+wb1*h0 = wt */ | 
|   | 
                 mulsfum(wa,wt,wa1); DEG(wa1) = divsfum(wa1,COEF(h)[0],q); | 
|   | 
                 mulsfum(wa1,COEF(g)[0],wc); subsfum(wt,wc,wd); | 
|   | 
                 DEG(wd) = divsfum(wd,COEF(h)[0],wb1); | 
|   | 
  | 
|   | 
                 /* c += ((wa1*g+wb1*h)*y^k mod y^(dy+1) */ | 
|   | 
                 /* wz0 = wa1*y^k */ | 
|   | 
                 clearbm(dx,wz0); | 
|   | 
                 cpyum(wa1,COEF(wz0)[k]); | 
|   | 
  | 
|   | 
                 /* wz1 = wz0*g mod y^(dy+1) */ | 
|   | 
                 clearbm(dx,wz1); | 
|   | 
                 mulsfbm(g,wz0,wz1); | 
|   | 
                 /* c += wz1 */ | 
|   | 
                 addtosfbm(wz1,c); | 
|   | 
  | 
|   | 
                 /* wz0 = wb1*y^k */ | 
|   | 
                 clearbm(dx,wz0); | 
|   | 
                 cpyum(wb1,COEF(wz0)[k]); | 
|   | 
  | 
|   | 
                 /* wz1 = wz0*h mod y^(dy+1) */ | 
|   | 
                 clearbm(dx,wz1); | 
|   | 
                 mulsfbm(h,wz0,wz1); | 
|   | 
                 /* c += wz1 */ | 
|   | 
                 addtosfbm(wz1,c); | 
|   | 
  | 
|   | 
                 /* a += wa1*y^k, b += wb1*y^k */ | 
|   | 
                 cpyum(wa1,COEF(a)[k]); | 
|   | 
                 cpyum(wb1,COEF(b)[k]); | 
|   | 
         } | 
|   | 
         if ( debug_sfbfctr) | 
|   | 
                 fprintf(stderr,"\n"); | 
|   | 
         DEG(a) = dy; | 
|   | 
         DEG(b) = dy; | 
|   | 
         *ap = a; | 
|   | 
         *bp = b; | 
|   | 
 } | 
|   | 
  | 
|  /* fl->c[i] = coef_y(f,i) */ | 
 /* fl->c[i] = coef_y(f,i) */ | 
|   | 
  | 
|  void ptosfbm(int dy,P f,BM fl) | 
 void ptosfbm(int dy,P f,BM fl) | 
| Line 830  void sfbmtop(BM f,V x,V y,P *fp) | 
 
  | 
| Line 971  void sfbmtop(BM f,V x,V y,P *fp) | 
 
 
 | 
|                          if ( DEG(c[j]) >= i && (a = COEF(c[j])[i]) ) { | 
                         if ( DEG(c[j]) >= i && (a = COEF(c[j])[i]) ) { | 
|                                  NEWDC(dct); | 
                                 NEWDC(dct); | 
|                                  STOQ(j,DEG(dct)); | 
                                 STOQ(j,DEG(dct)); | 
|                                  MKGFS(IFTOF(a),b); | 
                                 iftogfs(a,&b); | 
|                                  COEF(dct) = (P)b; | 
                                 COEF(dct) = (P)b; | 
|                                  NEXT(dct) = dc; | 
                                 NEXT(dct) = dc; | 
|                                  dc = dct; | 
                                 dc = dct; | 
| Line 863  void sfsqfr(P f,DCP *dcp) | 
 
  | 
| Line 1004  void sfsqfr(P f,DCP *dcp) | 
 
 
 | 
|                  NEWDC(dc); DEG(dc) = ONE; COEF(dc) = f; NEXT(dc) = 0; *dcp = dc; | 
                 NEWDC(dc); DEG(dc) = ONE; COEF(dc) = f; NEXT(dc) = 0; *dcp = dc; | 
|          } else if ( !NEXT(vl) ) | 
         } else if ( !NEXT(vl) ) | 
|                  sfusqfr(f,dcp); | 
                 sfusqfr(f,dcp); | 
|          else if ( !NEXT(NEXT(vl)) ) | 
  | 
|                  sfbsqfr(f,vl->v,NEXT(vl)->v,dcp); | 
  | 
|          else | 
         else | 
|                  error("sfsqfr : not implemented yet"); | 
                 sqfrsf(vl,f,dcp); | 
|  } | 
 } | 
|   | 
  | 
|  void sfusqfr(P f,DCP *dcp) | 
 void sfusqfr(P f,DCP *dcp) | 
| Line 897  void sfusqfr(P f,DCP *dcp) | 
 
  | 
| Line 1036  void sfusqfr(P f,DCP *dcp) | 
 
 
 | 
|          *dcp = dct; | 
         *dcp = dct; | 
|  } | 
 } | 
|   | 
  | 
|   | 
 #if 0 | 
|   | 
 void sfbsqfrmain(P f,V x,V y,DCP *dcp) | 
|   | 
 { | 
|   | 
         /* XXX*/ | 
|   | 
 } | 
|   | 
  | 
|   | 
 /* f is bivariate */ | 
|   | 
  | 
|  void sfbsqfr(P f,V x,V y,DCP *dcp) | 
 void sfbsqfr(P f,V x,V y,DCP *dcp) | 
|  { | 
 { | 
|          P t,rf,cx,cy; | 
         P t,rf,cx,cy; | 
|          VL vl,rvl; | 
         VL vl,rvl; | 
|          DCP dcx,dcy; | 
         DCP dcx,dcy,dct,dc; | 
|          struct oVL vl0,vl1; | 
         struct oVL vl0,vl1; | 
|   | 
  | 
|          /* vl = [x,y] */ | 
         /* cy(y) = cont(f,x), f /= cy */ | 
|          vl0.v = x; vl0.next = &vl1; vl1.v = y; vl1.next = 0; vl = &vl0; | 
  | 
|          /* cy(y) = cont(f,x), f /= cx */ | 
  | 
|          cont_pp_sfp(vl,f,&cy,&t); f = t; | 
         cont_pp_sfp(vl,f,&cy,&t); f = t; | 
|          /* rvl = [y,x] */ | 
         /* rvl = [y,x] */ | 
|          reordvar(vl,y,&rvl); reorderp(rvl,vl,f,&rf); | 
         reordvar(vl,y,&rvl); reorderp(rvl,vl,f,&rf); | 
| Line 915  void sfbsqfr(P f,V x,V y,DCP *dcp) | 
 
  | 
| Line 1060  void sfbsqfr(P f,V x,V y,DCP *dcp) | 
 
 
 | 
|          reorderp(vl,rvl,rf,&f); | 
         reorderp(vl,rvl,rf,&f); | 
|   | 
  | 
|          /* f -> cx*cy*f */ | 
         /* f -> cx*cy*f */ | 
|          sfusqfr(cx,&dcx); | 
         sfsqfr(cx,&dcx); dcx = NEXT(dcx); | 
|          sfusqfr(cy,&dcy); | 
         sfsqfr(cy,&dcy); dcy = NEXT(dcy); | 
|   | 
         if ( dcx ) { | 
|   | 
                 for ( dct = dcx; NEXT(dct); dct = NEXT(dct) ); | 
|   | 
                 NEXT(dct) = dcy; | 
|   | 
         } else | 
|   | 
                 dcx = dcy; | 
|   | 
         if ( OID(f) == O_N ) | 
|   | 
                 *dcp = dcx; | 
|   | 
         else { | 
|   | 
                 /* f must be bivariate */ | 
|   | 
                 sfbsqfrmain(f,x,y,&dc); | 
|   | 
                 if ( dcx ) { | 
|   | 
                         for ( dct = dcx; NEXT(dct); dct = NEXT(dct) ); | 
|   | 
                         NEXT(dct) = dc; | 
|   | 
                 } else | 
|   | 
                         dcx = dc; | 
|   | 
                 *dcp = dcx; | 
|   | 
         } | 
|  } | 
 } | 
|   | 
 #endif | 
|   | 
  | 
|  void sfdtest(P,ML,V,V,DCP *); | 
 void sfdtest(P,ML,V,V,DCP *); | 
|   | 
  | 
|  void sfbfctr(P f,V x,V y,DCP *dcp) | 
 /* if degbound >= 0 find factor s.t. deg_x(factor) <= degbound */ | 
|   | 
  | 
|   | 
 void sfbfctr(P f,V x,V y,int degbound,DCP *dcp) | 
|  { | 
 { | 
|          ML list; | 
         ML list; | 
|          P sf; | 
         P sf; | 
| Line 931  void sfbfctr(P f,V x,V y,DCP *dcp) | 
 
  | 
| Line 1096  void sfbfctr(P f,V x,V y,DCP *dcp) | 
 
 
 | 
|          int dx,dy; | 
         int dx,dy; | 
|   | 
  | 
|          /* sf(x) = f(x+ev) = list->c[0]*list->c[1]*... */ | 
         /* sf(x) = f(x+ev) = list->c[0]*list->c[1]*... */ | 
|          sfhensel(5,f,x,&ev,&sf,&list); | 
         sfhensel(5,f,x,y,degbound,&ev,&sf,&list); | 
|          if ( list->n == 0 ) | 
         if ( list->n == 0 ) | 
|                  error("sfbfctr : short of evaluation points"); | 
                 error("sfbfctr : short of evaluation points"); | 
|          else if ( list->n == 1 ) { | 
         else if ( list->n == 1 ) { | 
| Line 954  void sfbfctr(P f,V x,V y,DCP *dcp) | 
 
  | 
| Line 1119  void sfbfctr(P f,V x,V y,DCP *dcp) | 
 
 
 | 
|          *dcp = dc; | 
         *dcp = dc; | 
|  } | 
 } | 
|   | 
  | 
|   | 
 /* returns shifted f, shifted factors and the eval pt */ | 
|   | 
  | 
|   | 
 void sfbfctr_shift(P f,V x,V y,int degbound,GFS *evp,P *sfp,DCP *dcp) | 
|   | 
 { | 
|   | 
         ML list; | 
|   | 
         P sf; | 
|   | 
         GFS ev; | 
|   | 
         DCP dc,dct; | 
|   | 
         int dx,dy; | 
|   | 
  | 
|   | 
         /* sf(x) = f(x+ev) = list->c[0]*list->c[1]*... */ | 
|   | 
         sfhensel(5,f,x,y,degbound,&ev,&sf,&list); | 
|   | 
         if ( list->n == 0 ) | 
|   | 
                 error("sfbfctr_shift : short of evaluation points"); | 
|   | 
         else if ( list->n == 1 ) { | 
|   | 
                 /* f is irreducible */ | 
|   | 
                 NEWDC(dc); DEG(dc) = ONE; COEF(dc) = f; NEXT(dc) = 0; | 
|   | 
                 *evp = 0; | 
|   | 
                 *sfp = f; | 
|   | 
                 *dcp = dc; | 
|   | 
         } else { | 
|   | 
                 sfdtest(sf,list,x,y,dcp); | 
|   | 
                 *evp = ev; | 
|   | 
                 *sfp = sf; | 
|   | 
         } | 
|   | 
 } | 
|   | 
  | 
|  /* f = f(x,y) = list->c[0]*list->c[1]*... mod y^(list->bound+1) */ | 
 /* f = f(x,y) = list->c[0]*list->c[1]*... mod y^(list->bound+1) */ | 
|   | 
  | 
|  void sfdtest(P f,ML list,V x,V y,DCP *dcp) | 
 void sfdtest(P f,ML list,V x,V y,DCP *dcp) | 
|  { | 
 { | 
|          int np,dx,dy; | 
         int np,dx,dy; | 
|          int i,j,k; | 
         int i,j,k,bound; | 
|          int *win; | 
         int *win; | 
|          P g,lcg,factor,cofactor,lcyx; | 
         P g,lcg,factor,cofactor,lcyx; | 
|          P csum; | 
         P csum; | 
|          DCP dcf,dcf0,dc; | 
         DCP dcf,dcf0,dc; | 
|          BM *c; | 
         BM *c; | 
|          BM lcy; | 
         BM lcy; | 
|          UM lcg0; | 
         UM lcg0,lcy0,w; | 
|   | 
         UM *d1c; | 
|          ML wlist; | 
         ML wlist; | 
|          struct oVL vl1,vl0; | 
         struct oVL vl1,vl0; | 
|          VL vl; | 
         VL vl; | 
|          int z; | 
         int z,dt,dtok; | 
|   | 
  | 
|          /* vl = [x,y] */ | 
         /* vl = [x,y] */ | 
|          vl0.v = x; vl0.next = &vl1; vl1.v = y; vl1.next = 0; vl = &vl0; | 
         vl0.v = x; vl0.next = &vl1; vl1.v = y; vl1.next = 0; vl = &vl0; | 
| Line 982  void sfdtest(P f,ML list,V x,V y,DCP *dcp) | 
 
  | 
| Line 1175  void sfdtest(P f,ML list,V x,V y,DCP *dcp) | 
 
 
 | 
|          win = W_ALLOC(np+1); | 
         win = W_ALLOC(np+1); | 
|          wlist = W_MLALLOC(np); | 
         wlist = W_MLALLOC(np); | 
|          wlist->n = list->n; | 
         wlist->n = list->n; | 
|          wlist->bound = dy; | 
         bound = wlist->bound = list->bound; | 
|          c = (BM *)COEF(wlist); | 
         c = (BM *)COEF(wlist); | 
|          bcopy((char *)COEF(list),(char *)c,(int)(sizeof(BM)*np)); | 
         bcopy((char *)COEF(list),(char *)c,(int)(sizeof(BM)*np)); | 
|   | 
  | 
| Line 1006  void sfdtest(P f,ML list,V x,V y,DCP *dcp) | 
 
  | 
| Line 1199  void sfdtest(P f,ML list,V x,V y,DCP *dcp) | 
 
 
 | 
|          NEWP(lcyx); VR(lcyx) = x; DC(lcyx) = dc; | 
         NEWP(lcyx); VR(lcyx) = x; DC(lcyx) = dc; | 
|          ptosfbm(dy,lcyx,lcy); | 
         ptosfbm(dy,lcyx,lcy); | 
|   | 
  | 
|          fprintf(stderr,"np = %d\n",np); | 
         /* initialize lcy0 by LC(f) */ | 
|   | 
         lcy0 = W_UMALLOC(bound); | 
|   | 
         ptosfum(COEF(DC(g)),lcy0); | 
|   | 
  | 
|   | 
         /* ((d-1 coefs)*lcy0 */ | 
|   | 
         d1c = (UM *)W_ALLOC(np*sizeof(UM)); | 
|   | 
         w = W_UMALLOC(2*bound); | 
|   | 
         for ( i = 1; i < np; i++ ) { | 
|   | 
                 extractcoefbm(c[i],degbm(c[i])-1,w); | 
|   | 
                 d1c[i] = W_UMALLOC(2*bound); | 
|   | 
                 mulsfum(w,lcy0,d1c[i]); | 
|   | 
                 /* d1c[i] = d1c[i] mod y^(bound+1) */ | 
|   | 
                 if ( DEG(d1c[i]) > bound ) { | 
|   | 
                         for ( j = DEG(d1c[i]); j > bound; j-- ) | 
|   | 
                                 COEF(d1c[i])[j] = 0; | 
|   | 
                         degum(d1c[i],bound); | 
|   | 
                 } | 
|   | 
         } | 
|   | 
  | 
|   | 
         if ( debug_sfbfctr) | 
|   | 
                 fprintf(stderr,"np = %d\n",np); | 
|   | 
         dtok = 0; | 
|          for ( g = f, k = 1, dcf = dcf0 = 0, win[0] = 1, --np, z = 0; ; z++ ) { | 
         for ( g = f, k = 1, dcf = dcf0 = 0, win[0] = 1, --np, z = 0; ; z++ ) { | 
|                  if ( !(z % 1000) ) fprintf(stderr,"."); | 
                 if ( debug_sfbfctr && !(z % 1000) ) fprintf(stderr,"."); | 
|                  if ( sfdtestmain(vl,lcg,lcg0,lcy,csum,wlist,k,win,&factor,&cofactor) ) { | 
                 dt = sfdegtest(dy,bound,d1c,k,win); | 
|   | 
                 if ( dt ) | 
|   | 
                         dtok++; | 
|   | 
                 if ( dt && sfdtestmain(vl,lcg,lcg0,lcy,csum,wlist, | 
|   | 
                                 k,win,&factor,&cofactor) ) { | 
|                          NEXTDC(dcf0,dcf); DEG(dcf) = ONE; COEF(dcf) = factor; | 
                         NEXTDC(dcf0,dcf); DEG(dcf) = ONE; COEF(dcf) = factor; | 
|                          g = cofactor; | 
                         g = cofactor; | 
|   | 
  | 
| Line 1022  void sfdtest(P f,ML list,V x,V y,DCP *dcp) | 
 
  | 
| Line 1240  void sfdtest(P f,ML list,V x,V y,DCP *dcp) | 
 
 
 | 
|                          /* update csum */ | 
                         /* update csum */ | 
|                          sfcsump(vl,lcg,&csum); | 
                         sfcsump(vl,lcg,&csum); | 
|   | 
  | 
|   | 
                         /* update dy */ | 
|   | 
                         dy = getdeg(y,g); | 
|   | 
  | 
|                          /* update lcy */ | 
                         /* update lcy */ | 
|                          clearbm(0,lcy); | 
                         clearbm(0,lcy); | 
|                          COEF(dc) = COEF(DC(g)); | 
                         COEF(dc) = COEF(DC(g)); | 
| Line 1043  void sfdtest(P f,ML list,V x,V y,DCP *dcp) | 
 
  | 
| Line 1264  void sfdtest(P f,ML list,V x,V y,DCP *dcp) | 
 
 
 | 
|                          else | 
                         else | 
|                                  for ( i = 1; i < k; i++ ) | 
                                 for ( i = 1; i < k; i++ ) | 
|                                          win[i] = win[0] + i; | 
                                         win[i] = win[0] + i; | 
|   | 
  | 
|   | 
  | 
|   | 
                         /* update lcy0  */ | 
|   | 
                         ptosfum(COEF(DC(g)),lcy0); | 
|   | 
  | 
|   | 
                         /* update d-1 coeffs */ | 
|   | 
                         for ( i = 1; i <= np; i++ ) { | 
|   | 
                                 extractcoefbm(c[i],degbm(c[i])-1,w); | 
|   | 
                                 mulsfum(w,lcy0,d1c[i]); | 
|   | 
                                 /* d1c[i] = d1c[1] mod y^(bound+1) */ | 
|   | 
                                 if ( DEG(d1c[i]) > bound ) { | 
|   | 
                                         for ( j = DEG(d1c[i]); j > bound; j-- ) | 
|   | 
                                                 COEF(d1c[i])[j] = 0; | 
|   | 
                                         degum(d1c[i],bound); | 
|   | 
                                 } | 
|   | 
                         } | 
|                  } else if ( !ncombi(1,np,k,win) ) | 
                 } else if ( !ncombi(1,np,k,win) ) | 
|                          if ( k == np ) | 
                         if ( k == np ) | 
|                                  break; | 
                                 break; | 
| Line 1050  void sfdtest(P f,ML list,V x,V y,DCP *dcp) | 
 
  | 
| Line 1287  void sfdtest(P f,ML list,V x,V y,DCP *dcp) | 
 
 
 | 
|                                  for ( i = 0, ++k; i < k; i++ ) | 
                                 for ( i = 0, ++k; i < k; i++ ) | 
|                                          win[i] = i + 1; | 
                                         win[i] = i + 1; | 
|          } | 
         } | 
|          fprintf(stderr,"\n"); | 
         if ( debug_sfbfctr ) | 
|   | 
                 fprintf(stderr,"total %d, omitted by degtest %d\n",z,z-dtok); | 
|          NEXTDC(dcf0,dcf); COEF(dcf) = g; | 
         NEXTDC(dcf0,dcf); COEF(dcf) = g; | 
|          DEG(dcf) = ONE; NEXT(dcf) = 0; *dcp = dcf0; | 
         DEG(dcf) = ONE; NEXT(dcf) = 0; *dcp = dcf0; | 
|  } | 
 } | 
|   | 
  | 
|   | 
 void extractcoefbm(BM f,int dx,UM r) | 
|   | 
 { | 
|   | 
         int j; | 
|   | 
         UM fj; | 
|   | 
  | 
|   | 
         for ( j = DEG(f); j >= 0; j-- ) { | 
|   | 
                 fj = COEF(f)[j]; | 
|   | 
                 if ( fj && DEG(fj) >= dx ) { | 
|   | 
                         COEF(r)[j] = COEF(fj)[dx]; | 
|   | 
                 } else | 
|   | 
                         COEF(r)[j] = 0; | 
|   | 
         } | 
|   | 
         degum(r,DEG(f)); | 
|   | 
 } | 
|   | 
  | 
|   | 
 /* deg_y(prod mod y^(bound+1)) <= dy ? */ | 
|   | 
  | 
|   | 
 int sfdegtest(int dy,int bound,UM *d1c,int k,int *in) | 
|   | 
 { | 
|   | 
         int i,j; | 
|   | 
         UM w,w1,wt; | 
|   | 
         BM t; | 
|   | 
  | 
|   | 
         w = W_UMALLOC(bound); | 
|   | 
         w1 = W_UMALLOC(bound); | 
|   | 
         clearum(w,bound); | 
|   | 
         for ( i = 0; i < k; i++ ) { | 
|   | 
                 addsfum(w,d1c[in[i]],w1); wt = w; w = w1; w1 = wt; | 
|   | 
         } | 
|   | 
         return DEG(w) <= dy ? 1 : 0; | 
|   | 
 } | 
|   | 
  | 
|  /* lcy = LC(g), lcg = lcy*g, lcg0 = const part of lcg */ | 
 /* lcy = LC(g), lcg = lcy*g, lcg0 = const part of lcg */ | 
|   | 
  | 
|  int sfdtestmain(VL vl,P lcg,UM lcg0,BM lcy,P csum,ML list, | 
 int sfdtestmain(VL vl,P lcg,UM lcg0,BM lcy,P csum,ML list, | 
|          int k,int *in,P *fp,P *cofp) | 
         int k,int *in,P *fp,P *cofp) | 
|  { | 
 { | 
| Line 1184  void cont_pp_sfp(VL vl,P f,P *cp,P *fp) | 
 
  | 
| Line 1455  void cont_pp_sfp(VL vl,P f,P *cp,P *fp) | 
 
 
 | 
|          y = vl->next->v; | 
         y = vl->next->v; | 
|          d = getdeg(y,f); | 
         d = getdeg(y,f); | 
|          if ( d == 0 ) { | 
         if ( d == 0 ) { | 
|                  MKGFS(0,g); | 
                 itogfs(1,&g); | 
|                  *cp = (P)g; | 
                 *cp = (P)g; | 
|                  *fp = f;  /* XXX */ | 
                 *fp = f;  /* XXX */ | 
|          } else { | 
         } else { | 
| Line 1250  int divtp_by_sfbm(VL vl,P f,P g,P *qp) | 
 
  | 
| Line 1521  int divtp_by_sfbm(VL vl,P f,P g,P *qp) | 
 
 
 | 
|  /* XXX generate an irreducible poly of degree n */ | 
 /* XXX generate an irreducible poly of degree n */ | 
|   | 
  | 
|  extern int current_gfs_q1; | 
 extern int current_gfs_q1; | 
|   | 
 extern int *current_gfs_ntoi; | 
|   | 
  | 
|  void generate_defpoly_sfum(int n,UM *dp) | 
 void generate_defpoly_sfum(int n,UM *dp) | 
|  { | 
 { | 
| Line 1277  void generate_defpoly_sfum(int n,UM *dp) | 
 
  | 
| Line 1549  void generate_defpoly_sfum(int n,UM *dp) | 
 
 
 | 
|                  for ( j = 0; j < i; j++ ) | 
                 for ( j = 0; j < i; j++ ) | 
|                          w[j] = 0; | 
                         w[j] = 0; | 
|                  w[i]++; | 
                 w[i]++; | 
|                  for ( i = 0; i < n; i++ ) | 
                 if ( !current_gfs_ntoi ) | 
|                          c[i] = w[i]?FTOIF(w[i]-1):0; | 
                         for ( i = 0; i < n; i++ ) | 
|   | 
                                 c[i] = w[i]?FTOIF(w[i]):0; | 
|   | 
                 else | 
|   | 
                         for ( i = 0; i < n; i++ ) | 
|   | 
                                 c[i] = w[i]?FTOIF(w[i]-1):0; | 
|                  if ( !c[0] ) | 
                 if ( !c[0] ) | 
|                          continue; | 
                         continue; | 
|                  diffsfum(r,dr); cpyum(r,t); gcdsfum(t,dr,g); | 
                 diffsfum(r,dr); cpyum(r,t); gcdsfum(t,dr,g); |