[BACK]Return to binomial.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / TiGERS_0.9

Annotation of OpenXM_contrib/TiGERS_0.9/binomial.c, Revision 1.1

1.1     ! maekawa     1: /*
        !             2: ** binomial.c                                 Birk Huber, 4/99
        !             3: ** -- define binomal type and main operations on binomials
        !             4: **
        !             5: **
        !             6: ** TiGERS,  Toric Groebner Basis Enumeration by Reverse Search
        !             7: ** copyright (c) 1999  Birk Huber
        !             8: **
        !             9: */
        !            10: #define BINOMIAL_H 1
        !            11: #include<stdio.h>
        !            12: #include<stdlib.h>
        !            13: #include "utils.h"
        !            14: #include "binomial.h"
        !            15:
        !            16:
        !            17: /*
        !            18: **-------------ring defs-----------------------------------------------------
        !            19: **
        !            20: ** Monomials in the ambiant polynomial ring will be represented by their
        !            21: ** exponent vectors. Before any computations can be done using monomials the
        !            22: ** dimension of this ring (and the exponent vectors) must be set and stored
        !            23: ** in the global variable "ring_N". The mapping between indeces and variable
        !            24: ** names for i.o. purposes is currently done by just using the first ring_N
        !            25: ** letters of the alphabet.
        !            26: **
        !            27: ** Data:
        !            28: **  int  ring_N: global variable holding dimension of ambiant ring
        !            29: **  int ring_lv: global variable used by deg-rev-lex term order, i.e. specify
        !            30: **               which variable to make cheepest(others ordered alphabetically)
        !            31: **
        !            32: ** Functions (or macros):
        !            33: **  int ring_set(int n): Set ring_N to n if ring_N has not yet been set.
        !            34: **  int ring_read(File *infile): Read in a description of the ring from
        !            35: **                               infile and set ring values accordingly.
        !            36: ** ring_getvar(FILE *): convert next variable name on FILE to variable index
        !            37: ** ring_putvar(File *of,int v): convert index to variable name.
        !            38: **
        !            39: ** Note: for now a ring description is just given the number of variables.
        !            40: **       the names are just the first ring_N letters of the alphabet:
        !            41: **       i.e. **            name        <====>   index
        !            42: **                          'a'         <====>      1
        !            43: **                          'b'         <====>      1
        !            44: **        eventually this scheme may be adjusted to allow names to be set
        !            45: **        at run time.
        !            46: */
        !            47: int ring_N=0;
        !            48: int ring_lv=-1;
        !            49: int *ring_weight=0;
        !            50:
        !            51: int ring_set(int n){
        !            52:   int i;
        !            53:   if (ring_N!=0) {
        !            54:     fprintf(stderr,"ring_set(): can't reset dimension\n");
        !            55:     return FALSE;
        !            56:   }
        !            57:   if ((ring_weight=(int *)(malloc(n*sizeof(int))))==0){
        !            58:     fprintf(stderr,"ring_set(): malloc failed for weight vector\n");
        !            59:     return FALSE;
        !            60:   }
        !            61:   for(i=0;i<n;i++) ring_weight[i]=1;
        !            62:   return ring_N=n;
        !            63: }
        !            64:
        !            65: int ring_read(FILE *infile){
        !            66:    int n;
        !            67:    eatwhite(infile);
        !            68:    if (fscanf(infile,"%d",&n)!=1){
        !            69:     fprintf(stderr,"ERROR: read_ring() unable to parse ring description\n");
        !            70:     return FALSE;
        !            71:    }
        !            72:    ring_set(n);
        !            73:    return TRUE;
        !            74: }
        !            75:
        !            76: int ring_getvar(FILE *ifile){
        !            77:   char c;
        !            78:   c=fgetc(ifile);
        !            79:   if ('a' > c || c >'a'+ring_N-1){
        !            80:      fprintf(stderr,"ring_getvar(): invalid variable read\n");
        !            81:      ungetc(c,ifile);
        !            82:      return -1;
        !            83:   }
        !            84:   return c-'a';
        !            85: }
        !            86:
        !            87: /*
        !            88: **------------monomial defs-----------------------------------------------
        !            89: ** monomials are represented by their exponent vectors:
        !            90: ** C integer vectors indexed from 0 to ring_dim-1
        !            91: **
        !            92: */
        !            93:
        !            94: /*
        !            95: ** void print_monomial(FILE *,int *):
        !            96: **      print exponent vector as monomial
        !            97: **
        !            98: */
        !            99: void print_monomial(FILE *of, int *exps){
        !           100:   int i,jk=0;
        !           101:   for(i=0;i<ring_N;i++){
        !           102:     if (exps[i]!=0){
        !           103:        if (jk!=0) fprintf(of,"*");
        !           104:        else jk=1;
        !           105:        ring_putvar(of,i);
        !           106:        if (exps[i]>1) fprintf(of,"^%d",exps[i]);
        !           107:     }
        !           108:   }
        !           109: }
        !           110:
        !           111: /*
        !           112: ** void get_monomial(FILE *,int *):
        !           113: **      Read ascii representation of monomial as power product -- convert
        !           114: **      to exponent vector stored in *exps.
        !           115: **
        !           116: */
        !           117: void get_monomial(FILE *is,int *exps){
        !           118: char c='*';
        !           119: int v,e;
        !           120:
        !           121:  for(v=0;v<ring_N;v++)exps[v]=0;
        !           122:  while(c=='*'){
        !           123:    eatwhite(is);
        !           124:    v=ring_getvar(is);
        !           125:    eatwhite(is);
        !           126:    c=fgetc(is);
        !           127:    if (c=='^'){
        !           128:        fscanf(is,"%d",&e);
        !           129:        c=fgetc(is);
        !           130:    }
        !           131:    else {
        !           132:      e=1;
        !           133:    }
        !           134:    exps[v]=e;
        !           135:  }
        !           136:  ungetc(c,is);
        !           137: }
        !           138:
        !           139: /*
        !           140: ** int monomial_divides(monomial m1, monomial m2):
        !           141: **     return TRUE if m1 divides m2
        !           142: **
        !           143: */
        !           144: int monomial_divides(monomial m1, monomial m2){
        !           145:  int i;
        !           146:  for(i=0;i<ring_N;i++)if (m1[i]>m2[i]) return FALSE;
        !           147:  return TRUE;
        !           148: }
        !           149:
        !           150: /*
        !           151: ** int monomial_rel_prime(monomial m1, monomial m2):
        !           152: **     return TRUE if m1 is reletively prime to m2.
        !           153: **
        !           154: */
        !           155: int monomial_rel_prime(monomial m1, monomial m2){
        !           156:  int i;
        !           157:  for(i=0;i<ring_N;i++) if (m1[i]!=0 && m2[i]!=0) return FALSE;
        !           158:  return TRUE;
        !           159: }
        !           160:
        !           161: /*
        !           162: ** int monomial_equal(monomial m1, monomial m2):
        !           163: **     return TRUE if monomials m1 and m2 have same exponents
        !           164: **
        !           165: */
        !           166: int monomial_equal(monomial m1, monomial m2){
        !           167:    int i;
        !           168:    for(i=0;i<ring_N;i++) if (m1[i]-m2[i]!=0) return FALSE;
        !           169:    return TRUE;
        !           170: }
        !           171:
        !           172: /*
        !           173: **int monomial_lcm(monomial m1, monomial m2, monomial m3):
        !           174: **    copy least common multiple of m1 and m2 into m3.
        !           175: **
        !           176: */
        !           177: int monomial_lcm(monomial m1, monomial m2, monomial m3){
        !           178:   int i;
        !           179:   for(i=0;i<ring_N;i++){
        !           180:     if (m1[i]>=m2[i]) m3[i]=m1[i];
        !           181:     else m3[i]=m2[i];
        !           182:   }
        !           183: }
        !           184:
        !           185: /*
        !           186: **
        !           187: **
        !           188: */
        !           189: int monomial_stddegree(monomial m){
        !           190:  int i,d=0;
        !           191:  for(i=0;i<ring_N;i++) d+=m[i];
        !           192:  return d;
        !           193: }
        !           194:
        !           195:
        !           196: /*
        !           197: ** int monomial_lexcomp(monomial m1, monomial m2):
        !           198: **     return >0 if m1 is lexicographically greater then m2
        !           199: **
        !           200: */
        !           201: int monomial_lexcomp(monomial m1, monomial m2){
        !           202: int i,jk;
        !           203:  for(i=0;i<ring_N;i++) if ((jk=m1[i]-m2[i])!=0) break;
        !           204:  return jk;
        !           205: }
        !           206:
        !           207: /*
        !           208: ** int monomial_rlexcomp(monomial m1, monomial m2):
        !           209: **     return >0 if m1 is degree reverse lexicographically greater than m2
        !           210: **     with variables taken in order a>b...., except that variable ring_lv is
        !           211: **     taken last (if it is >=0).
        !           212: **
        !           213: */
        !           214: int monomial_rlexcomp(monomial m1, monomial m2){
        !           215: int i,jk,d=0;
        !           216:  /* compute diference of total degrees */
        !           217:  for(i=0;i<ring_N;i++) d+=ring_weight[i]*(m1[i]-m2[i]);
        !           218:  if (d!=0) return d;
        !           219:  /* test ring_lv entree first */
        !           220:  if (ring_lv>=0 && ((jk=m1[ring_lv]-m2[ring_lv])!=0)) return -1*jk;
        !           221:  /* now test entrees in reverse order */
        !           222:  for(i=ring_N-1;i>=0;i--) if ((jk=m1[i]-m2[i])!=0) return -1*jk;
        !           223:  return 0;
        !           224: }
        !           225:
        !           226: /*
        !           227: **----------binomial defs------------------------------------------------
        !           228: **
        !           229: **
        !           230: */
        !           231:
        !           232: /*
        !           233: ** binomial binomial_new(): allocate storage for a new binomial--
        !           234: **                          initialize flags and set exponents to zero;
        !           235: */
        !           236: binomial binomial_new(){
        !           237:    binomial m;
        !           238:    int i,*E=0,*E2=0;
        !           239:
        !           240:    if ((m=(binomial)malloc(sizeof(struct bin_tag)))==0){
        !           241:     fprintf(stderr,"binomial_new(): first malloc failed\n");
        !           242:     return 0;
        !           243:    }
        !           244:    if ((m->E=(int *)malloc(2*ring_N*sizeof(int)))==0){
        !           245:     fprintf(stderr,"binomial_new(): seccond malloc failed\n");
        !           246:     free((void*)m);
        !           247:     return 0;
        !           248:    }
        !           249:    m->exps1=m->E;
        !           250:    m->exps2=m->E+ring_N;
        !           251:    m->ff=UNKNOWN;
        !           252:    m->bf=BINOMIAL;
        !           253:    m->next=0;
        !           254:    for(i=0;i<ring_N;i++) { m->exps1[i]=(m->exps2[i]=0);}
        !           255:    return m;
        !           256: }
        !           257:
        !           258:
        !           259: /*
        !           260: ** void binomial_free(binomial m):
        !           261: **      reclaim space allocated by binomial_new()
        !           262: **
        !           263: */
        !           264: void binomial_free(binomial m){
        !           265:     if (m->E!=0)free((void *)(m->E));
        !           266:     free((void *)m);
        !           267: }
        !           268:
        !           269: /*
        !           270: ** void binomial_read(FILE *is, binomial b):
        !           271: **      read data into binomial
        !           272: **
        !           273: */
        !           274: void binomial_read(FILE *is, binomial b){
        !           275:   char c, d='-';
        !           276:   eatwhite(is);
        !           277:   c=getc(is);
        !           278:   /* read in status of facet flag if present*/
        !           279:   if (c=='#') b->ff=FACET;
        !           280:   else if (c=='!') b->ff=NONFACET;
        !           281:   else if (c=='?') b->ff=UNKNOWN;
        !           282:   else ungetc(c,is);
        !           283:
        !           284:   /* read in leading and trailing monomials if present*/
        !           285:   eatwhite(is);
        !           286:   if ((c=getc(is))=='-') d='+';
        !           287:   else ungetc(c,is);
        !           288:   get_monomial(is,b->exps1);
        !           289:   eatwhite(is);
        !           290:   if ((c=getc(is))==d){
        !           291:     get_monomial(is,b->exps2);
        !           292:     b->bf=BINOMIAL;
        !           293:   }else{
        !           294:     b->bf=MONOMIAL;
        !           295:     ungetc(c,is);
        !           296:   }
        !           297:   if (d=='+'){
        !           298:    if (b->bf==MONOMIAL){
        !           299:      fprintf(stderr,"WARNING: binomial_read() monomial with negative coef\n");
        !           300:    }
        !           301:    binomial_flip(b);
        !           302:   }
        !           303: }
        !           304:
        !           305:
        !           306: /*
        !           307: ** void binomial_print(FILE *,binomial):
        !           308: **      print binomial
        !           309: **
        !           310: */
        !           311: void binomial_print(FILE *of, binomial b){
        !           312:    if (b==0) fprintf(of,"(NULL)");
        !           313:    else {
        !           314:      if (b->ff==FACET) fprintf(of,"# ");
        !           315:      else if (b->ff==NONFACET) fprintf(of,"! ");
        !           316:      /*else if (b->ff==UNKNOWN) fprintf(of,"? ");*/
        !           317:      print_monomial(of,b->exps1);
        !           318:      if (b->bf==BINOMIAL){
        !           319:       fprintf(of,"-");
        !           320:       print_monomial(of,b->exps2);
        !           321:      }
        !           322:    }
        !           323: }
        !           324:
        !           325: /*
        !           326: ** void binomial_copy(binomial src,binomial dest):
        !           327: **      copy source binomials exponents and flags to those of dest binomial
        !           328: **
        !           329: */
        !           330: void binomial_copy(binomial src,binomial dest){
        !           331:  int i;
        !           332:
        !           333:  for(i=0;i<ring_N;i++){
        !           334:     binomial_lead(dest)[i]=binomial_lead(src)[i];
        !           335:     binomial_trail(dest)[i]=binomial_trail(src)[i];
        !           336:  }
        !           337:  binomial_next(dest)=0;
        !           338:  dest->bf=src->bf;
        !           339: }
        !           340:
        !           341: /*
        !           342: ** void binomial_flip(binomial b):
        !           343: **      interchange leading and trailing terms of binomial
        !           344: **
        !           345: */
        !           346: void binomial_flip(binomial b){
        !           347:    int *tmp;
        !           348:    tmp=binomial_lead(b);
        !           349:    binomial_lead(b)=binomial_trail(b);
        !           350:    binomial_trail(b)=tmp;
        !           351: }
        !           352:
        !           353: /*
        !           354: ** binomial monomial_spair(binomial b,monomial m):
        !           355: **   form spair between marked binomial and marked monomial
        !           356: **   and reduce result by binomial as many times as possible
        !           357: **
        !           358: */
        !           359: binomial monomial_spair(binomial b,monomial m){
        !           360:   binomial S = 0;
        !           361:   int i,tmp;
        !           362:
        !           363:   S=binomial_new();
        !           364:
        !           365:   /* form monomial spair i.e. trailing term times factor required to */
        !           366:   /* bump lead term up to monomial -- also set trail terms to zero  */
        !           367:   for(i=0;i<ring_N;i++){
        !           368:     (binomial_lead(S))[i]=(binomial_trail(b))[i];
        !           369:     (binomial_trail(S))[i]=0;
        !           370:     if ((tmp=(m[i]-(binomial_lead(b))[i]))>0)((binomial_lead(S))[i])+=tmp;
        !           371:   }
        !           372:
        !           373:   /*reduce S by b as many times as possible*/
        !           374:   while(monomial_divides(binomial_lead(b),binomial_lead(S))==TRUE){
        !           375:     for(i=0;i<ring_N;i++){
        !           376:       tmp=(binomial_lead(S))[i]-(binomial_lead(b))[i];
        !           377:       (binomial_lead(S))[i]=(binomial_trail(b))[i]+tmp;
        !           378:     }
        !           379:
        !           380:   }
        !           381:   return S;
        !           382: }
        !           383:
        !           384: /*
        !           385: ** int binomial_spair(binomial b1, binomial b2):
        !           386: **     replace b1, by spair of b1 and b2 -- the spair is taken with respect
        !           387: **     to the markings of b1 and b2, but it's marking is not meaningfull.
        !           388: **     returns TRUE if result is equivalent to zero monomial.
        !           389: **
        !           390: */
        !           391: int binomial_spair(binomial b1, binomial b2){
        !           392:    int i,jk,jk2=TRUE;
        !           393:    for(i=0;i<ring_N;i++){
        !           394:      jk=binomial_lead(b1)[i]-binomial_lead(b2)[i];
        !           395:      if (binomial_lead(b1)[i]!=0 && binomial_lead(b2)!=0) jk2=FALSE;
        !           396:      binomial_lead(b1)[i]=binomial_trail(b2)[i];
        !           397:      if (jk>0) binomial_lead(b1)[i]+=jk;
        !           398:      else binomial_trail(b1)[i]-=jk;
        !           399:    }
        !           400:    jk=monomial_equal(binomial_lead(b1),binomial_trail(b1));
        !           401:    if (jk==TRUE || jk2==TRUE) return TRUE;
        !           402:    else return FALSE;
        !           403: }
        !           404:
        !           405:
        !           406: /*
        !           407: **void binomial_bumpto(binomial b1, binomial b2):
        !           408: **     assuming that the leading term of b1 divides that of b2
        !           409: **     multiply both sides of b1 so that the leading terms of b1
        !           410: **     and b2 are equal
        !           411: **
        !           412: */
        !           413: void binomial_bumpto(binomial b1, binomial b2){
        !           414:   int i,tmp;
        !           415:   for(i=0;i<ring_N;i++){
        !           416:     tmp=(binomial_lead(b2))[i]-(binomial_lead(b1))[i];
        !           417:     (binomial_lead(b1))[i]+=tmp;
        !           418:     (binomial_trail(b1))[i]+=tmp;
        !           419:   }
        !           420: }
        !           421:
        !           422: /*
        !           423: ** void reducetrail(binomial b1, binomial b2):
        !           424: **      assuming that lead(b2) divides trail(b1) change b1 into binomial
        !           425: **      resulting from bumping b2 so that lead(b2)=trail(b1) and adding
        !           426: **      result to b1.
        !           427: **
        !           428: */
        !           429: void reducetrail(binomial b1, binomial b2){
        !           430:       int i;
        !           431:       for( i=0;i<ring_N;i++){
        !           432:           binomial_trail(b1)[i]+=binomial_trail(b2)[i]-binomial_lead(b2)[i];
        !           433:        }
        !           434: }
        !           435:
        !           436: /*
        !           437: ** int binomial_compair(binomial b1,binomial b2):
        !           438: **     return TRUE if the lead term of b1 is lexicographically greater than
        !           439: **     that of b2 or if they tie return true if the trail term b1 is greater
        !           440: **     or equal to that of b2 otherwise return false
        !           441: */
        !           442: int binomial_compair(binomial b1,binomial b2){
        !           443:  int tmp;
        !           444:
        !           445:  tmp=monomial_lexcomp(binomial_lead(b1),binomial_lead(b2));
        !           446:  if (tmp>0) return TRUE;
        !           447:  else if (tmp<0) return FALSE;
        !           448:  else {
        !           449:    tmp=monomial_lexcomp(binomial_trail(b1),binomial_trail(b2));
        !           450:    if (tmp>=0) return TRUE;
        !           451:    else return FALSE;
        !           452:  }
        !           453: }
        !           454:
        !           455:
        !           456:
        !           457:
        !           458:
        !           459:
        !           460:
        !           461:
        !           462:
        !           463:
        !           464:
        !           465:
        !           466:
        !           467:

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