[BACK]Return to dist.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / engine

Diff for /OpenXM_contrib2/asir2000/engine/dist.c between version 1.35 and 1.45

version 1.35, 2005/11/25 02:43:39 version 1.45, 2012/12/17 07:20:44
Line 45 
Line 45 
  * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,   * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
  * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.   * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
  *   *
  * $OpenXM: OpenXM_contrib2/asir2000/engine/dist.c,v 1.34 2005/11/24 08:16:03 noro Exp $   * $OpenXM: OpenXM_contrib2/asir2000/engine/dist.c,v 1.44 2011/03/30 02:43:18 noro Exp $
 */  */
 #include "ca.h"  #include "ca.h"
   
Line 65 
Line 65 
 #define ORD_HOMO_WW_DRL_ZIGZAG 13  #define ORD_HOMO_WW_DRL_ZIGZAG 13
   
 int cmpdl_drl_zigzag(), cmpdl_homo_ww_drl_zigzag();  int cmpdl_drl_zigzag(), cmpdl_homo_ww_drl_zigzag();
   int cmpdl_top_weight();
   
 int (*cmpdl)()=cmpdl_revgradlex;  int (*cmpdl)()=cmpdl_revgradlex;
   int (*cmpdl_tie_breaker)();
 int (*primitive_cmpdl[3])() = {cmpdl_revgradlex,cmpdl_gradlex,cmpdl_lex};  int (*primitive_cmpdl[3])() = {cmpdl_revgradlex,cmpdl_gradlex,cmpdl_lex};
   
 int do_weyl;  int do_weyl;
Line 118  int has_sfcoef_p(P f)
Line 120  int has_sfcoef_p(P f)
         }          }
 }  }
   
   extern N *current_top_weight_vector;
   static int current_top_weight_len;
   
 void initd(struct order_spec *spec)  void initd(struct order_spec *spec)
 {  {
           int len,i;
   
         switch ( spec->id ) {          switch ( spec->id ) {
                 case 3:                  case 3:
                         cmpdl = cmpdl_composite;                          cmpdl = cmpdl_composite;
Line 165  void initd(struct order_spec *spec)
Line 172  void initd(struct order_spec *spec)
                         }                          }
                         break;                          break;
         }          }
           if ( current_top_weight_vector ) {
                   cmpdl_tie_breaker = cmpdl;
                   cmpdl = cmpdl_top_weight;
                   for ( len = 0, i = 0; i < spec->nv; i++ )
                           if ( current_top_weight_vector[i] )
                                   len = MAX(PL(current_top_weight_vector[i]),len);
                   current_top_weight_len = len;
           }
         dp_current_spec = spec;          dp_current_spec = spec;
 }  }
   
Line 642  void comm_muld(VL vl,DP p1,DP p2,DP *pr)
Line 657  void comm_muld(VL vl,DP p1,DP p2,DP *pr)
                         l = l1;                          l = l1;
                 }                  }
                 if ( l > wlen ) {                  if ( l > wlen ) {
                         if ( w ) GC_free(w);                          if ( w ) GCFREE(w);
                         w = (MP *)MALLOC(l*sizeof(MP));                          w = (MP *)MALLOC(l*sizeof(MP));
                         wlen = l;                          wlen = l;
                 }                  }
Line 680  void comm_muld_trunc(VL vl,DP p1,DP p2,DL dl,DP *pr)
Line 695  void comm_muld_trunc(VL vl,DP p1,DP p2,DL dl,DP *pr)
                         l = l1;                          l = l1;
                 }                  }
                 if ( l > wlen ) {                  if ( l > wlen ) {
                         if ( w ) GC_free(w);                          if ( w ) GCFREE(w);
                         w = (MP *)MALLOC(l*sizeof(MP));                          w = (MP *)MALLOC(l*sizeof(MP));
                         wlen = l;                          wlen = l;
                 }                  }
Line 814  void weyl_muld(VL vl,DP p1,DP p2,DP *pr)
Line 829  void weyl_muld(VL vl,DP p1,DP p2,DP *pr)
         else {          else {
                 for ( m = BDY(p1), l = 0; m; m = NEXT(m), l++ );                  for ( m = BDY(p1), l = 0; m; m = NEXT(m), l++ );
                 if ( l > wlen ) {                  if ( l > wlen ) {
                         if ( w ) GC_free(w);                          if ( w ) GCFREE(w);
                         w = (MP *)MALLOC(l*sizeof(MP));                          w = (MP *)MALLOC(l*sizeof(MP));
                         wlen = l;                          wlen = l;
                 }                  }
Line 846  void weyl_muldm(VL vl,MP m0,DP p,DP *pr)
Line 861  void weyl_muldm(VL vl,MP m0,DP p,DP *pr)
         else {          else {
                 for ( m = BDY(p), l = 0; m; m = NEXT(m), l++ );                  for ( m = BDY(p), l = 0; m; m = NEXT(m), l++ );
                 if ( l > wlen ) {                  if ( l > wlen ) {
                         if ( w ) GC_free(w);                          if ( w ) GCFREE(w);
                         w = (MP *)MALLOC(l*sizeof(MP));                          w = (MP *)MALLOC(l*sizeof(MP));
                         wlen = l;                          wlen = l;
                 }                  }
Line 858  void weyl_muldm(VL vl,MP m0,DP p,DP *pr)
Line 873  void weyl_muldm(VL vl,MP m0,DP p,DP *pr)
                 for ( i = 0, tlen = 1; i < n2; i++ )                  for ( i = 0, tlen = 1; i < n2; i++ )
                         tlen *= d0->d[n2+i]+1;                          tlen *= d0->d[n2+i]+1;
                 if ( tlen > rtlen ) {                  if ( tlen > rtlen ) {
                         if ( tab ) GC_free(tab);                          if ( tab ) GCFREE(tab);
                         if ( psum ) GC_free(psum);                          if ( psum ) GCFREE(psum);
                         rtlen = tlen;                          rtlen = tlen;
                         tab = (struct cdl *)MALLOC(rtlen*sizeof(struct cdl));                          tab = (struct cdl *)MALLOC(rtlen*sizeof(struct cdl));
                         psum = (MP *)MALLOC(rtlen*sizeof(MP));                          psum = (MP *)MALLOC(rtlen*sizeof(MP));
Line 921  void weyl_mulmm(VL vl,MP m0,MP m1,int n,struct cdl *rt
Line 936  void weyl_mulmm(VL vl,MP m0,MP m1,int n,struct cdl *rt
         rtab[0].d = d;          rtab[0].d = d;
   
         if ( rtablen > tmptablen ) {          if ( rtablen > tmptablen ) {
                 if ( tmptab ) GC_free(tmptab);                  if ( tmptab ) GCFREE(tmptab);
                 tmptab = (struct cdl *)MALLOC(rtablen*sizeof(struct cdl));                  tmptab = (struct cdl *)MALLOC(rtablen*sizeof(struct cdl));
                 tmptablen = rtablen;                  tmptablen = rtablen;
         }          }
Line 947  void weyl_mulmm(VL vl,MP m0,MP m1,int n,struct cdl *rt
Line 962  void weyl_mulmm(VL vl,MP m0,MP m1,int n,struct cdl *rt
                         continue;                          continue;
                 }                  }
                 if ( k+1 > tablen ) {                  if ( k+1 > tablen ) {
                         if ( tab ) GC_free(tab);                          if ( tab ) GCFREE(tab);
                         if ( ctab ) GC_free(ctab);                          if ( ctab ) GCFREE(ctab);
                         tablen = k+1;                          tablen = k+1;
                         tab = (struct cdl *)MALLOC(tablen*sizeof(struct cdl));                          tab = (struct cdl *)MALLOC(tablen*sizeof(struct cdl));
                         ctab = (Q *)MALLOC(tablen*sizeof(Q));                          ctab = (Q *)MALLOC(tablen*sizeof(Q));
Line 1089  void adddl(int n,DL d1,DL d2,DL *dr)
Line 1104  void adddl(int n,DL d1,DL d2,DL *dr)
         DL dt;          DL dt;
         int i;          int i;
   
         if ( !d1->td )          *dr = dt = (DL)MALLOC_ATOMIC((n+1)*sizeof(int));
                 *dr = d2;          dt->td = d1->td + d2->td;
         else if ( !d2->td )          for ( i = 0; i < n; i++ )
                 *dr = d1;                  dt->d[i] = d1->d[i]+d2->d[i];
         else {  
                 *dr = dt = (DL)MALLOC_ATOMIC((n+1)*sizeof(int));  
                 dt->td = d1->td + d2->td;  
                 for ( i = 0; i < n; i++ )  
                         dt->d[i] = d1->d[i]+d2->d[i];  
         }  
 }  }
   
 /* d1 += d2 */  /* d1 += d2 */
Line 1121  int compd(VL vl,DP p1,DP p2)
Line 1130  int compd(VL vl,DP p1,DP p2)
                 return p2 ? -1 : 0;                  return p2 ? -1 : 0;
         else if ( !p2 )          else if ( !p2 )
                 return 1;                  return 1;
           else if ( NV(p1) != NV(p2) )
                   error("compd : size mismatch");
         else {          else {
                 for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2);                  for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2);
                         m1 && m2; m1 = NEXT(m1), m2 = NEXT(m2) )                          m1 && m2; m1 = NEXT(m1), m2 = NEXT(m2) )
Line 1496  int cmpdl_order_pair(int n,DL d1,DL d2)
Line 1507  int cmpdl_order_pair(int n,DL d1,DL d2)
         struct order_pair *pair;          struct order_pair *pair;
   
         len = dp_current_spec->ord.block.length;          len = dp_current_spec->ord.block.length;
           if ( n != dp_current_spec->nv )
                   error("cmpdl_order_pair : incompatible order specification");
         pair = dp_current_spec->ord.block.order_pair;          pair = dp_current_spec->ord.block.order_pair;
   
         head = 0;          head = 0;
Line 1636  int cmpdl_matrix(int n,DL d1,DL d2)
Line 1649  int cmpdl_matrix(int n,DL d1,DL d2)
         return 0;          return 0;
 }  }
   
   int cmpdl_top_weight(int n,DL d1,DL d2)
   {
           int *w;
           N sum,wm,wma,t;
           N *a;
           struct oN tn;
           int len,i,sgn,tsgn;
           int *t1,*t2;
   
           w = (int *)ALLOCA(n*sizeof(int));
           len = current_top_weight_len+3;
           t1 = d1->d; t2 = d2->d;
           for ( i = 0; i < n; i++ ) w[i] = t1[i]-t2[i];
           sum = (N)W_ALLOC(len); sgn = 0;
           wm = (N)W_ALLOC(len);
           wma = (N)W_ALLOC(len);
           a = current_top_weight_vector;
           for ( i = 0; i < n; i++ ) {
                   if ( !a[i] || !w[i] ) continue;
                   tn.p = 1;
                   if ( w[i] > 0 ) {
                           tn.b[0] = w[i]; tsgn = 1;
                   } else {
                           tn.b[0] = -w[i]; tsgn = -1;
                   }
                   _muln(a[i],&tn,wm);
                   if ( !sgn ) {
                           sgn = tsgn;
                           t = wm; wm = sum; sum = t;
                   } else if ( sgn == tsgn ) {
                           _addn(sum,wm,wma);
                           if ( !PL(wma) )
                                   sgn = 0;
                           t = wma; wma = sum; sum = t;
                   } else {
                           sgn *= _subn(sum,wm,wma);
                           t = wma; wma = sum; sum = t;
                   }
           }
           if ( sgn > 0 ) return 1;
           else if ( sgn < 0 ) return -1;
           else return (*cmpdl_tie_breaker)(n,d1,d2);
   }
   
 GeoBucket create_bucket()  GeoBucket create_bucket()
 {  {
         GeoBucket g;          GeoBucket g;
Line 1799  int ni_next(int *a,int n)
Line 1856  int ni_next(int *a,int n)
   
 int comp_nbm(NBM a,NBM b)  int comp_nbm(NBM a,NBM b)
 {  {
         int d,i,w;          int d,i,w,ai,bi;
         int *ab,*bb;          int *ab,*bb;
   
         if ( a->d > b->d ) return 1;          if ( a->d > b->d ) return 1;
         else if ( a->d < b->d ) return -1;          else if ( a->d < b->d ) return -1;
         else {          else {
                 d = a->d; ab = a->b; bb = b->b;                  d = a->d; ab = a->b; bb = b->b;
   #if 0
                 w = (d+31)/32;                  w = (d+31)/32;
                 for ( i = 0; i < w; i++ )                  for ( i = 0; i < w; i++ )
                         if ( ab[i] > bb[i] ) return 1;                          if ( ab[i] > bb[i] ) return 1;
                         else if ( ab[i] < bb[i] ) return -1;                          else if ( ab[i] < bb[i] ) return -1;
   #else
                   for ( i = 0; i < d; i++ ) {
                           ai = NBM_GET(ab,i);
                           bi = NBM_GET(bb,i);
                           if ( ai > bi ) return 1;
                           else if ( ai < bi ) return -1;
                   }
   #endif
                 return 0;                  return 0;
         }          }
 }  }
Line 1819  NBM mul_nbm(NBM a,NBM b)
Line 1885  NBM mul_nbm(NBM a,NBM b)
         int ad,bd,d,i,j;          int ad,bd,d,i,j;
         int *ab,*bb,*mb;          int *ab,*bb,*mb;
         NBM m;          NBM m;
         Q c,c1;  
         NODE r;          NODE r;
         NBP u;          NBP u;
   
         ad = a->d; bd = b->d; ab = a->b; bb = b->b;          ad = a->d; bd = b->d; ab = a->b; bb = b->b;
         d = ad + bd;          d = ad + bd;
         NEWNBM(m); NEWNBMBDY(m,d);          NEWNBM(m); NEWNBMBDY(m,d);
         m->d = d; mulq(a->c,b->c,&m->c); mb = m->b;          m->d = d; mulp(CO,a->c,b->c,&m->c); mb = m->b;
         j = 0;          j = 0;
         for ( i = 0; i < ad; i++, j++ )          for ( i = 0; i < ad; i++, j++ )
                 if ( NBM_GET(ab,i) ) NBM_SET(mb,j);                  if ( NBM_GET(ab,i) ) NBM_SET(mb,j);
Line 1837  NBM mul_nbm(NBM a,NBM b)
Line 1902  NBM mul_nbm(NBM a,NBM b)
         return m;          return m;
 }  }
   
 NBP shuffle_mul_nbm(NBM a,NBM b)  NBP nbmtonbp(NBM m)
 {  {
         int ad,bd,d,i,ai,bi,bit,s;          NODE n;
         int *ab,*bb,*wmb,*w;  
         NBM wm,tm;  
         Q c,c1;  
         NODE r,t,t1,p;  
         NBP u;          NBP u;
   
         ad = a->d; bd = b->d; ab = a->b; bb = b->b;          MKNODE(n,m,0);
         d = ad + bd;          MKNBP(u,n);
         w = (int *)ALLOCA(d*sizeof(int));          return u;
         NEWNBM(wm); NEWNBMBDY(wm,d); wmb = wm->b;  }
         for ( i = 0; i < ad; i++ ) w[i] = 1;  
         for ( ; i < d; i++ ) w[i] = 0;  /* a=c*x*rest -> a0= x*rest, ah=x, ar=rest */
         mulq(a->c,b->c,&c);  
         r = 0;  P separate_nbm(NBM a,NBP *a0,NBP *ah,NBP *ar)
         do {  {
                 wm->d = d; wm->c = c;          int i,d1;
                 ai = 0; bi = 0;          NBM t;
                 for ( i = 0; i < d; i++ ) {  
                         if ( w[i] ) { bit = NBM_GET(ab,ai); ai++; }          if ( !a->d ) error("separate_nbm : invalid argument");
                         else { bit = NBM_GET(bb,bi); bi++; }  
                         if ( bit ) NBM_SET(wmb,i);          if ( a0 ) {
                         else NBM_CLR(wmb,i);                  NEWNBM(t); t->d = a->d; t->b = a->b; t->c = (P)ONE;
                   *a0 = nbmtonbp(t);
           }
   
           if ( ah ) {
                   NEWNBM(t); NEWNBMBDY(t,1); t->d = 1; t->c = (P)ONE;
                   if ( NBM_GET(a->b,0) ) NBM_SET(t->b,0);
                   else NBM_CLR(t->b,0);
                   *ah = nbmtonbp(t);
           }
   
           if ( ar ) {
                   d1 = a->d-1;
                   NEWNBM(t); NEWNBMBDY(t,d1); t->d = d1; t->c = (P)ONE;
                   for ( i = 0; i < d1; i++ ) {
                           if ( NBM_GET(a->b,i+1) ) NBM_SET(t->b,i);
                           else NBM_CLR(t->b,i);
                 }                  }
                 for ( p = 0, t = r; t; p = t, t = NEXT(t) ) {                  *ar = nbmtonbp(t);
                         tm = (NBM)BDY(t);          }
                         s = comp_nbm(tm,wm);  
                         if ( s < 0 ) {          return a->c;
                                 /* insert */  }
                                 MKNODE(t1,wm,t);  
                                 if ( !p ) r = t1;  /* a=c*rest*x -> a0= rest*x, ar=rest, at=x */
                                 else NEXT(p) = t1;  
                                 NEWNBM(wm); NEWNBMBDY(wm,d); wmb = wm->b;  P separate_tail_nbm(NBM a,NBP *a0,NBP *ar,NBP *at)
                                 break;  {
                         } else if ( s == 0 ) {          int i,d,d1;
                                 /* add coefs */          NBM t;
                                 addq(tm->c,c,&c1);  
                                 if ( c1 ) tm->c = c1;          if ( !(d=a->d) ) error("separate_tail_nbm : invalid argument");
                                 else NEXT(p) = NEXT(t);  
                                 break;          if ( a0 ) {
                         }                  NEWNBM(t); t->d = a->d; t->b = a->b; t->c = (P)ONE;
                   *a0 = nbmtonbp(t);
           }
   
           d1 = a->d-1;
           if ( at ) {
                   NEWNBM(t); NEWNBMBDY(t,1); t->d = 1; t->c = (P)ONE;
                   if ( NBM_GET(a->b,d1) ) NBM_SET(t->b,0);
                   else NBM_CLR(t->b,0);
                   *at = nbmtonbp(t);
           }
   
           if ( ar ) {
                   NEWNBM(t); NEWNBMBDY(t,d1); t->d = d1; t->c = (P)ONE;
                   for ( i = 0; i < d1; i++ ) {
                           if ( NBM_GET(a->b,i) ) NBM_SET(t->b,i);
                           else NBM_CLR(t->b,i);
                 }                  }
                 if ( !t ) {                  *ar = nbmtonbp(t);
                         /* append */          }
                         MKNODE(t1,wm,t);  
                         if ( !p ) r = t1;          return a->c;
                         else NEXT(p) = t1;  }
                         NEWNBM(wm); NEWNBMBDY(wm,d); wmb = wm->b;  
   NBP make_xky(int k)
   {
           int k1,i;
           NBM t;
   
           NEWNBM(t); NEWNBMBDY(t,k); t->d = k; t->c = (P)ONE;
           k1 = k-1;
           for ( i = 0; i < k1; i++ ) NBM_SET(t->b,i);
           NBM_CLR(t->b,i);
           return nbmtonbp(t);
   }
   
   /* a=c*x^(k-1)*y*rest -> a0= x^(k-1)*y*rest, ah=x^(k-1)*y, ar=rest */
   
   P separate_xky_nbm(NBM a,NBP *a0,NBP *ah,NBP *ar)
   {
           int i,d1,k,k1;
           NBM t;
   
           if ( !a->d )
                   error("separate_nbm : invalid argument");
           for ( i = 0; i < a->d && NBM_GET(a->b,i); i++ );
           if ( i == a->d )
                   error("separate_nbm : invalid argument");
           k1 = i;
           k = i+1;
   
           if ( a0 ) {
                   NEWNBM(t); t->d = a->d; t->b = a->b; t->c = (P)ONE;
                   *a0 = nbmtonbp(t);
           }
   
           if ( ah ) {
                   NEWNBM(t); NEWNBMBDY(t,k); t->d = k; t->c = (P)ONE;
                   for ( i = 0; i < k1; i++ ) NBM_SET(t->b,i);
                   NBM_CLR(t->b,i);
                   *ah = nbmtonbp(t);
           }
   
           if ( ar ) {
                   d1 = a->d-k;
                   NEWNBM(t); NEWNBMBDY(t,d1); t->d = d1; t->c = (P)ONE;
                   for ( i = 0; i < d1; i++ ) {
                           if ( NBM_GET(a->b,i+k) ) NBM_SET(t->b,i);
                           else NBM_CLR(t->b,i);
                 }                  }
         } while ( ni_next(w,d) );                  *ar = nbmtonbp(t);
         MKNBP(u,r);          }
         return u;  
           return a->c;
 }  }
   
 int nbmtoxky(NBM a,int *b)  void shuffle_mulnbp(VL vl,NBP p1,NBP p2, NBP *rp);
   void harmonic_mulnbp(VL vl,NBP p1,NBP p2, NBP *rp);
   void mulnbmnbp(VL vl,NBM m,NBP p, NBP *rp);
   void mulnbpnbm(VL vl,NBP p,NBM m, NBP *rp);
   
   NBP shuffle_mul_nbm(NBM a,NBM b)
 {  {
         int d,i,j,k;          NBP u,a0,ah,ar,b0,bh,br,a1,b1,t;
         int *p;          P ac,bc,c;
   
         d = a->d; p = a->b;          if ( !a->d || !b->d )
         for ( i = j = 0, k = 1; i < d; i++ ) {                  u = nbmtonbp(mul_nbm(a,b));
                 if ( !NBM_GET(p,i) ) {          else {
                         b[j++] = k;                  ac = separate_nbm(a,&a0,&ah,&ar);
                         k = 1;                  bc = separate_nbm(b,&b0,&bh,&br);
                 } else k++;                  mulp(CO,ac,bc,&c);
                   shuffle_mulnbp(CO,ar,b0,&t); mulnbp(CO,ah,t,&a1);
                   shuffle_mulnbp(CO,a0,br,&t); mulnbp(CO,bh,t,&b1);
                   addnbp(CO,a1,b1,&t); mulnbp(CO,(NBP)c,t,&u);
         }          }
         return j;          return u;
 }  }
   
 NBP harmonic_mul_nbm(NBM a,NBM b)  NBP harmonic_mul_nbm(NBM a,NBM b)
 {  {
         int da,db,d,la,lb,lmax,lmin,l,lab,la1,lb1,lab1;          NBP u,a0,ah,ar,b0,bh,br,a1,b1,t,s,abk,ab1;
         int i,j,k,ia,ib,s;          P ac,bc,c;
         int *wa,*wb,*w,*wab,*wa1,*wmb;  
         Q c,c1;  
         NBM wm,tm;  
         NODE r,t1,t,p;  
         NBP u;  
   
         da = a->d; db = b->d; d = da+db;          if ( !a->d || !b->d )
         wa = (int *)ALLOCA(da*sizeof(int));                  u = nbmtonbp(mul_nbm(a,b));
         wb = (int *)ALLOCA(db*sizeof(int));          else {
         la = nbmtoxky(a,wa);                  mulp(CO,a->c,b->c,&c);
         lb = nbmtoxky(b,wb);                  ac = separate_xky_nbm(a,&a0,&ah,&ar);
         mulq(a->c,b->c,&c);                  bc = separate_xky_nbm(b,&b0,&bh,&br);
         /* wa[0],..,wa[la-1] <-> x^wa[0]y x^wa[1]y .. */                  mulp(CO,ac,bc,&c);
         /* lmax : total length */                  harmonic_mulnbp(CO,ar,b0,&t); mulnbp(CO,ah,t,&a1);
         lmax = la+lb;                  harmonic_mulnbp(CO,a0,br,&t); mulnbp(CO,bh,t,&b1);
         lmin = la>lb?la:lb;                  abk = make_xky(((NBM)BDY(BDY(ah)))->d+((NBM)BDY(BDY(bh)))->d);
         w = (int *)ALLOCA(lmax*sizeof(int));                  harmonic_mulnbp(CO,ar,br,&t); mulnbp(CO,abk,t,&ab1);
         /* position of a+b */                  addnbp(CO,a1,b1,&t); addnbp(CO,t,ab1,&s); mulnbp(CO,(NBP)c,s,&u);
         wab = (int *)ALLOCA(lmax*sizeof(int));  
         /* position of a */  
         wa1 = (int *)ALLOCA(lmax*sizeof(int));  
         NEWNBM(wm); NEWNBMBDY(wm,d); wmb = wm->b;  
         for ( l = lmin, r = 0; l <= lmax; l++ ) {  
                 lab = lmax - l;  
                 la1 = la - lab;  
                 lb1 = lb - lab;  
                 lab1 = l-lab;  
                 /* partion l into three parts: a, b, a+b */  
                 /* initialize wab */  
                 for ( i = 0; i < lab; i++ ) wab[i] = 1;  
                 for ( ; i < l; i++ ) wab[i] = 0;  
                 do {  
                         /* initialize wa1 */  
                         for ( i = 0; i < la1; i++ ) wa1[i] = 1;  
                         for ( ; i < lab1; i++ ) wa1[i] = 0;  
                         do {  
                                 ia = 0; ib = 0;  
                                 for ( i = j = 0; i < l; i++ )  
                                         if ( wab[i] ) w[i] = wa[ia++]+wb[ib++];  
                                         else if ( wa1[j++] ) w[i] = wa[ia++];  
                                         else w[i] = wb[ib++];  
                                 for ( i = j = 0; i < l; i++ ) {  
                                         for ( k = w[i]-1; k > 0; k--, j++ ) NBM_SET(wmb,j);  
                                         NBM_CLR(wmb,j); j++;  
                                 }  
                                 wm->d = j; wm->c = c;  
                                 for ( p = 0, t = r; t; p = t, t = NEXT(t) ) {  
                                         tm = (NBM)BDY(t);  
                                         s = comp_nbm(tm,wm);  
                                         if ( s < 0 ) {  
                                                 /* insert */  
                                                 MKNODE(t1,wm,t);  
                                                 if ( !p ) r = t1;  
                                                 else NEXT(p) = t1;  
                                                 NEWNBM(wm); NEWNBMBDY(wm,d); wmb = wm->b;  
                                                 break;  
                                         } else if ( s == 0 ) {  
                                                 /* add coefs */  
                                                 addq(tm->c,c,&c1);  
                                                 if ( c1 ) tm->c = c1;  
                                                 else NEXT(p) = NEXT(t);  
                                                 break;  
                                         }  
                                 }  
                                 if ( !t ) {  
                                         /* append */  
                                         MKNODE(t1,wm,t);  
                                         if ( !p ) r = t1;  
                                         else NEXT(p) = t1;  
                                         NEWNBM(wm); NEWNBMBDY(wm,d); wmb = wm->b;  
                                 }  
                         } while ( ni_next(wa1,lab1) );  
                 } while ( ni_next(wab,l) );  
         }          }
         MKNBP(u,r);  
         return u;          return u;
   
 }  }
   
 void addnbp(VL vl,NBP p1,NBP p2, NBP *rp)  void addnbp(VL vl,NBP p1,NBP p2, NBP *rp)
 {  {
         NODE b1,b2,br,br0;          NODE b1,b2,br,br0;
         NBM m1,m2,m;          NBM m1,m2,m;
         Q c;          P c;
   
         if ( !p1 )          if ( !p1 )
                 *rp = p2;                  *rp = p2;
Line 2005  void addnbp(VL vl,NBP p1,NBP p2, NBP *rp)
Line 2092  void addnbp(VL vl,NBP p1,NBP p2, NBP *rp)
                         m1 = (NBM)BDY(b1); m2 = (NBM)BDY(b2);                          m1 = (NBM)BDY(b1); m2 = (NBM)BDY(b2);
                         switch ( comp_nbm(m1,m2) ) {                          switch ( comp_nbm(m1,m2) ) {
                                 case 0:                                  case 0:
                                         addq(m1->c,m2->c,&c);                                          addp(CO,m1->c,m2->c,&c);
                                         if ( c ) {                                          if ( c ) {
                                                 NEXTNODE(br0,br);                                                  NEXTNODE(br0,br);
                                                 NEWNBM(m); m->d = m1->d; m->c = c; m->b = m1->b;                                                  NEWNBM(m); m->d = m1->d; m->c = c; m->b = m1->b;
Line 2055  void chsgnnbp(NBP p,NBP *rp)
Line 2142  void chsgnnbp(NBP p,NBP *rp)
         for ( r0 = 0, b = BDY(p); b; b = NEXT(b) ) {          for ( r0 = 0, b = BDY(p); b; b = NEXT(b) ) {
                 NEXTNODE(r0,r);                  NEXTNODE(r0,r);
                 m = (NBM)BDY(b);                  m = (NBM)BDY(b);
                 NEWNBM(m1); m1->d = m->d; m1->b = m->b; chsgnq(m->c,&m1->c);                  NEWNBM(m1); m1->d = m->d; m1->b = m->b; chsgnp(m->c,&m1->c);
                 BDY(r) = m1;                  BDY(r) = m1;
         }          }
         if ( r0 ) NEXT(r) = 0;          if ( r0 ) NEXT(r) = 0;
         MKNBP(*rp,r0);          MKNBP(*rp,r0);
 }  }
   
 void mulnbmnbp(VL vl,NBM m,NBP p, NBP *rp);  
 void mulnbpnbm(VL vl,NBP p,NBM m, NBP *rp);  
   
 void mulnbp(VL vl,NBP p1,NBP p2, NBP *rp)  void mulnbp(VL vl,NBP p1,NBP p2, NBP *rp)
 {  {
         NODE b;          NODE b,n;
         NBP r,t,s;          NBP r,t,s;
           NBM m;
   
         if ( !p1 || !p2 ) *rp = 0;          if ( !p1 || !p2 ) {
         else if ( length(BDY(p1)) < length(BDY(p2)) ) {                  *rp = 0; return;
           }
           if ( OID(p1) != O_NBP ) {
                   if ( !POLY(p1) )
                           error("mulnbp : invalid argument");
                   NEWNBM(m); m->d = 0; m->b = 0; m->c = (P)p1;
                   MKNODE(n,m,0); MKNBP(p1,n);
           }
           if ( OID(p2) != O_NBP ) {
                   if ( !POLY(p2) )
                           error("mulnbp : invalid argument");
                   NEWNBM(m); m->d = 0; m->b = 0; m->c = (P)p2;
                   MKNODE(n,m,0); MKNBP(p2,n);
           }
           if ( length(BDY(p1)) < length(BDY(p2)) ) {
                 for ( r = 0, b = BDY(p1); b; b = NEXT(b) ) {                  for ( r = 0, b = BDY(p1); b; b = NEXT(b) ) {
                         mulnbmnbp(vl,(NBM)BDY(b),p2,&t);                          mulnbmnbp(vl,(NBM)BDY(b),p2,&t);
                         addnbp(vl,r,t,&s); r = s;                          addnbp(vl,r,t,&s); r = s;
Line 2126  void pwrnbp(VL vl,NBP a,Q q,NBP *c)
Line 2225  void pwrnbp(VL vl,NBP a,Q q,NBP *c)
         NODE r;          NODE r;
   
         if ( !q ) {          if ( !q ) {
                  NEWNBM(m); m->d = 0; m->c = ONE; m->b = 0;                   NEWNBM(m); m->d = 0; m->c = (P)ONE; m->b = 0;
                  MKNODE(r,m,0); MKNBP(*c,r);                   MKNODE(r,m,0); MKNBP(*c,r);
         } else if ( !a )          } else if ( !a )
                 *c = 0;                  *c = 0;
Line 2143  void pwrnbp(VL vl,NBP a,Q q,NBP *c)
Line 2242  void pwrnbp(VL vl,NBP a,Q q,NBP *c)
         }          }
 }  }
   
   int compnbp(VL vl,NBP p1,NBP p2)
   {
           NODE n1,n2;
           NBM m1,m2;
           int t;
   
           if ( !p1 )
                   return p2 ? -1 : 0;
           else if ( !p2 )
                   return 1;
           else {
                   for ( n1 = BDY(p1), n2 = BDY(p2);
                           n1 && n2; n1 = NEXT(n1), n2 = NEXT(n2) ) {
                           m1 = (NBM)BDY(n1); m2 = (NBM)BDY(n2);
                           if ( (t = comp_nbm(m1,m2)) || (t = compp(CO,m1->c,m2->c) ) )
                                   return t;
                   }
                   if ( n1 )
                           return 1;
                   else if ( n2 )
                           return -1;
                   else
                           return 0;
           }
   }
   
 void shuffle_mulnbp(VL vl,NBP p1,NBP p2, NBP *rp)  void shuffle_mulnbp(VL vl,NBP p1,NBP p2, NBP *rp)
 {  {
         NODE b1,b2;          NODE b1,b2,n;
         NBP r,t,s;          NBP r,t,s;
         NBM m;          NBM m;
   
         if ( !p1 || !p2 ) *rp = 0;          if ( !p1 || !p2 ) {
         else {                  *rp = 0; return;
                 for ( r = 0, b1 = BDY(p1); b1; b1 = NEXT(b1) )  
                         for ( m = BDY(b1), b2 = BDY(p2); b2; b2 = NEXT(b2) ) {  
                                 t = shuffle_mul_nbm(m,(NBM)BDY(b2));  
                                 addnbp(vl,r,t,&s); r = s;  
                         }  
                 *rp = r;  
         }          }
           if ( OID(p1) != O_NBP ) {
                   if ( !POLY(p1) )
                           error("shuffle_mulnbp : invalid argument");
                   NEWNBM(m); m->d = 0; m->b = 0; m->c = (P)p1;
                   MKNODE(n,m,0); MKNBP(p1,n);
           }
           if ( OID(p2) != O_NBP ) {
                   if ( !POLY(p2) )
                           error("shuffle_mulnbp : invalid argument");
                   NEWNBM(m); m->d = 0; m->b = 0; m->c = (P)p2;
                   MKNODE(n,m,0); MKNBP(p2,n);
           }
           for ( r = 0, b1 = BDY(p1); b1; b1 = NEXT(b1) )
                   for ( m = BDY(b1), b2 = BDY(p2); b2; b2 = NEXT(b2) ) {
                           t = shuffle_mul_nbm(m,(NBM)BDY(b2));
                           addnbp(vl,r,t,&s); r = s;
                   }
           *rp = r;
 }  }
   
 void harmonic_mulnbp(VL vl,NBP p1,NBP p2, NBP *rp)  void harmonic_mulnbp(VL vl,NBP p1,NBP p2, NBP *rp)
 {  {
         NODE b1,b2;          NODE b1,b2,n;
         NBP r,t,s;          NBP r,t,s;
         NBM m;          NBM m;
   
         if ( !p1 || !p2 ) *rp = 0;          if ( !p1 || !p2 ) {
         else {                  *rp = 0; return;
                 for ( r = 0, b1 = BDY(p1); b1; b1 = NEXT(b1) )          }
                         for ( m = BDY(b1), b2 = BDY(p2); b2; b2 = NEXT(b2) ) {          if ( OID(p1) != O_NBP ) {
                                 t = harmonic_mul_nbm(m,(NBM)BDY(b2));                  if ( !POLY(p1) )
                                 addnbp(vl,r,t,&s); r = s;                          error("harmonic_mulnbp : invalid argument");
                   NEWNBM(m); m->d = 0; m->b = 0; m->c = (P)p1;
                   MKNODE(n,m,0); MKNBP(p1,n);
           }
           if ( OID(p2) != O_NBP ) {
                   if ( !POLY(p2) )
                           error("harmonic_mulnbp : invalid argument");
                   NEWNBM(m); m->d = 0; m->b = 0; m->c = (P)p2;
                   MKNODE(n,m,0); MKNBP(p2,n);
           }
           for ( r = 0, b1 = BDY(p1); b1; b1 = NEXT(b1) )
                   for ( m = BDY(b1), b2 = BDY(p2); b2; b2 = NEXT(b2) ) {
                           t = harmonic_mul_nbm(m,(NBM)BDY(b2));
                           addnbp(vl,r,t,&s); r = s;
                   }
           *rp = r;
   }
   
   #if 0
   NBP shuffle_mul_nbm(NBM a,NBM b)
   {
           int ad,bd,d,i,ai,bi,bit,s;
           int *ab,*bb,*wmb,*w;
           NBM wm,tm;
           P c,c1;
           NODE r,t,t1,p;
           NBP u;
   
           ad = a->d; bd = b->d; ab = a->b; bb = b->b;
           d = ad + bd;
           w = (int *)ALLOCA(d*sizeof(int));
           NEWNBM(wm); NEWNBMBDY(wm,d); wmb = wm->b;
           for ( i = 0; i < ad; i++ ) w[i] = 1;
           for ( ; i < d; i++ ) w[i] = 0;
           mulp(CO,a->c,b->c,&c);
           r = 0;
           do {
                   wm->d = d; wm->c = c;
                   ai = 0; bi = 0;
                   for ( i = 0; i < d; i++ ) {
                           if ( w[i] ) { bit = NBM_GET(ab,ai); ai++; }
                           else { bit = NBM_GET(bb,bi); bi++; }
                           if ( bit ) NBM_SET(wmb,i);
                           else NBM_CLR(wmb,i);
                   }
                   for ( p = 0, t = r; t; p = t, t = NEXT(t) ) {
                           tm = (NBM)BDY(t);
                           s = comp_nbm(tm,wm);
                           if ( s < 0 ) {
                                   /* insert */
                                   MKNODE(t1,wm,t);
                                   if ( !p ) r = t1;
                                   else NEXT(p) = t1;
                                   NEWNBM(wm); NEWNBMBDY(wm,d); wmb = wm->b;
                                   break;
                           } else if ( s == 0 ) {
                                   /* add coefs */
                                   addp(CO,tm->c,c,&c1);
                                   if ( c1 ) tm->c = c1;
                                   else NEXT(p) = NEXT(t);
                                   break;
                         }                          }
                 *rp = r;                  }
                   if ( !t ) {
                           /* append */
                           MKNODE(t1,wm,t);
                           if ( !p ) r = t1;
                           else NEXT(p) = t1;
                           NEWNBM(wm); NEWNBMBDY(wm,d); wmb = wm->b;
                   }
           } while ( ni_next(w,d) );
           MKNBP(u,r);
           return u;
   }
   
   int nbmtoxky(NBM a,int *b)
   {
           int d,i,j,k;
           int *p;
   
           d = a->d; p = a->b;
           for ( i = j = 0, k = 1; i < d; i++ ) {
                   if ( !NBM_GET(p,i) ) {
                           b[j++] = k;
                           k = 1;
                   } else k++;
         }          }
           return j;
 }  }
   
   NBP harmonic_mul_nbm(NBM a,NBM b)
   {
           int da,db,d,la,lb,lmax,lmin,l,lab,la1,lb1,lab1;
           int i,j,k,ia,ib,s;
           int *wa,*wb,*w,*wab,*wa1,*wmb;
           P c,c1;
           NBM wm,tm;
           NODE r,t1,t,p;
           NBP u;
   
           da = a->d; db = b->d; d = da+db;
           wa = (int *)ALLOCA(da*sizeof(int));
           wb = (int *)ALLOCA(db*sizeof(int));
           la = nbmtoxky(a,wa);
           lb = nbmtoxky(b,wb);
           mulp(CO,a->c,b->c,&c);
           /* wa[0],..,wa[la-1] <-> x^wa[0]y x^wa[1]y .. */
           /* lmax : total length */
           lmax = la+lb;
           lmin = la>lb?la:lb;
           w = (int *)ALLOCA(lmax*sizeof(int));
           /* position of a+b */
           wab = (int *)ALLOCA(lmax*sizeof(int));
           /* position of a */
           wa1 = (int *)ALLOCA(lmax*sizeof(int));
           NEWNBM(wm); NEWNBMBDY(wm,d); wmb = wm->b;
           for ( l = lmin, r = 0; l <= lmax; l++ ) {
                   lab = lmax - l;
                   la1 = la - lab;
                   lb1 = lb - lab;
                   lab1 = l-lab;
                   /* partion l into three parts: a, b, a+b */
                   /* initialize wab */
                   for ( i = 0; i < lab; i++ ) wab[i] = 1;
                   for ( ; i < l; i++ ) wab[i] = 0;
                   do {
                           /* initialize wa1 */
                           for ( i = 0; i < la1; i++ ) wa1[i] = 1;
                           for ( ; i < lab1; i++ ) wa1[i] = 0;
                           do {
                                   ia = 0; ib = 0;
                                   for ( i = j = 0; i < l; i++ )
                                           if ( wab[i] ) w[i] = wa[ia++]+wb[ib++];
                                           else if ( wa1[j++] ) w[i] = wa[ia++];
                                           else w[i] = wb[ib++];
                                   for ( i = j = 0; i < l; i++ ) {
                                           for ( k = w[i]-1; k > 0; k--, j++ ) NBM_SET(wmb,j);
                                           NBM_CLR(wmb,j); j++;
                                   }
                                   wm->d = j; wm->c = c;
                                   for ( p = 0, t = r; t; p = t, t = NEXT(t) ) {
                                           tm = (NBM)BDY(t);
                                           s = comp_nbm(tm,wm);
                                           if ( s < 0 ) {
                                                   /* insert */
                                                   MKNODE(t1,wm,t);
                                                   if ( !p ) r = t1;
                                                   else NEXT(p) = t1;
                                                   NEWNBM(wm); NEWNBMBDY(wm,d); wmb = wm->b;
                                                   break;
                                           } else if ( s == 0 ) {
                                                   /* add coefs */
                                                   addp(CO,tm->c,c,&c1);
                                                   if ( c1 ) tm->c = c1;
                                                   else NEXT(p) = NEXT(t);
                                                   break;
                                           }
                                   }
                                   if ( !t ) {
                                           /* append */
                                           MKNODE(t1,wm,t);
                                           if ( !p ) r = t1;
                                           else NEXT(p) = t1;
                                           NEWNBM(wm); NEWNBMBDY(wm,d); wmb = wm->b;
                                   }
                           } while ( ni_next(wa1,lab1) );
                   } while ( ni_next(wab,l) );
           }
           MKNBP(u,r);
           return u;
   }
   #endif

Legend:
Removed from v.1.35  
changed lines
  Added in v.1.45

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>