[BACK]Return to binomial.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / Ti

Annotation of OpenXM/src/Ti/binomial.c, Revision 1.1.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: extern int NT;
                     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:   if (NT == 1) {
                    102:     fprintf(of,"[");
                    103:     for (i=0; i<ring_N; i++) {
                    104:       fprintf(of,"%d",exps[i]);
                    105:       if (i != ring_N-1) fprintf(of," , ");
                    106:     }
                    107:     fprintf(of,"]");
                    108:   }else{
                    109:     for(i=0;i<ring_N;i++){
                    110:       if (exps[i]!=0){
                    111:        if (jk!=0) fprintf(of,"*");
                    112:        else jk=1;
                    113:        ring_putvar(of,i);
                    114:        if (exps[i]>1) fprintf(of,"^%d",exps[i]);
                    115:       }
                    116:     }
                    117:   }
                    118: }
                    119:
                    120: /*
                    121: ** void get_monomial(FILE *,int *):
                    122: **      Read ascii representation of monomial as power product -- convert
                    123: **      to exponent vector stored in *exps.
                    124: **
                    125: */
                    126: void get_monomial(FILE *is,int *exps){
                    127: char c='*';
                    128: int v,e;
                    129:
                    130:  for(v=0;v<ring_N;v++)exps[v]=0;
                    131:  while(c=='*'){
                    132:    eatwhite(is);
                    133:    v=ring_getvar(is);
                    134:    eatwhite(is);
                    135:    c=fgetc(is);
                    136:    if (c=='^'){
                    137:        fscanf(is,"%d",&e);
                    138:        c=fgetc(is);
                    139:    }
                    140:    else {
                    141:      e=1;
                    142:    }
                    143:    exps[v]=e;
                    144:  }
                    145:  ungetc(c,is);
                    146: }
                    147:
                    148: /*
                    149: ** int monomial_divides(monomial m1, monomial m2):
                    150: **     return TRUE if m1 divides m2
                    151: **
                    152: */
                    153: int monomial_divides(monomial m1, monomial m2){
                    154:  int i;
                    155:  for(i=0;i<ring_N;i++)if (m1[i]>m2[i]) return FALSE;
                    156:  return TRUE;
                    157: }
                    158:
                    159: /*
                    160: ** int monomial_rel_prime(monomial m1, monomial m2):
                    161: **     return TRUE if m1 is reletively prime to m2.
                    162: **
                    163: */
                    164: int monomial_rel_prime(monomial m1, monomial m2){
                    165:  int i;
                    166:  for(i=0;i<ring_N;i++) if (m1[i]!=0 && m2[i]!=0) return FALSE;
                    167:  return TRUE;
                    168: }
                    169:
                    170: /*
                    171: ** int monomial_equal(monomial m1, monomial m2):
                    172: **     return TRUE if monomials m1 and m2 have same exponents
                    173: **
                    174: */
                    175: int monomial_equal(monomial m1, monomial m2){
                    176:    int i;
                    177:    for(i=0;i<ring_N;i++) if (m1[i]-m2[i]!=0) return FALSE;
                    178:    return TRUE;
                    179: }
                    180:
                    181: /*
                    182: **int monomial_lcm(monomial m1, monomial m2, monomial m3):
                    183: **    copy least common multiple of m1 and m2 into m3.
                    184: **
                    185: */
                    186: int monomial_lcm(monomial m1, monomial m2, monomial m3){
                    187:   int i;
                    188:   for(i=0;i<ring_N;i++){
                    189:     if (m1[i]>=m2[i]) m3[i]=m1[i];
                    190:     else m3[i]=m2[i];
                    191:   }
                    192: }
                    193:
                    194: /*
                    195: **
                    196: **
                    197: */
                    198: int monomial_stddegree(monomial m){
                    199:  int i,d=0;
                    200:  for(i=0;i<ring_N;i++) d+=m[i];
                    201:  return d;
                    202: }
                    203:
                    204:
                    205: /*
                    206: ** int monomial_lexcomp(monomial m1, monomial m2):
                    207: **     return >0 if m1 is lexicographically greater then m2
                    208: **
                    209: */
                    210: int monomial_lexcomp(monomial m1, monomial m2){
                    211: int i,jk;
                    212:  for(i=0;i<ring_N;i++) if ((jk=m1[i]-m2[i])!=0) break;
                    213:  return jk;
                    214: }
                    215:
                    216: /*
                    217: ** int monomial_rlexcomp(monomial m1, monomial m2):
                    218: **     return >0 if m1 is degree reverse lexicographically greater than m2
                    219: **     with variables taken in order a>b...., except that variable ring_lv is
                    220: **     taken last (if it is >=0).
                    221: **
                    222: */
                    223: int monomial_rlexcomp(monomial m1, monomial m2){
                    224: int i,jk,d=0;
                    225:  /* compute diference of total degrees */
                    226:  for(i=0;i<ring_N;i++) d+=ring_weight[i]*(m1[i]-m2[i]);
                    227:  if (d!=0) return d;
                    228:  /* test ring_lv entree first */
                    229:  if (ring_lv>=0 && ((jk=m1[ring_lv]-m2[ring_lv])!=0)) return -1*jk;
                    230:  /* now test entrees in reverse order */
                    231:  for(i=ring_N-1;i>=0;i--) if ((jk=m1[i]-m2[i])!=0) return -1*jk;
                    232:  return 0;
                    233: }
                    234:
                    235: /*
                    236: **----------binomial defs------------------------------------------------
                    237: **
                    238: **
                    239: */
                    240:
                    241: /*
                    242: ** binomial binomial_new(): allocate storage for a new binomial--
                    243: **                          initialize flags and set exponents to zero;
                    244: */
                    245: binomial binomial_new(){
                    246:    binomial m;
                    247:    int i,*E=0,*E2=0;
                    248:
                    249:    if ((m=(binomial)malloc(sizeof(struct bin_tag)))==0){
                    250:     fprintf(stderr,"binomial_new(): first malloc failed\n");
                    251:     return 0;
                    252:    }
                    253:    if ((m->E=(int *)malloc(2*ring_N*sizeof(int)))==0){
                    254:     fprintf(stderr,"binomial_new(): seccond malloc failed\n");
                    255:     free((void*)m);
                    256:     return 0;
                    257:    }
                    258:    m->exps1=m->E;
                    259:    m->exps2=m->E+ring_N;
                    260:    m->ff=UNKNOWN;
                    261:    m->bf=BINOMIAL;
                    262:    m->next=0;
                    263:    for(i=0;i<ring_N;i++) { m->exps1[i]=(m->exps2[i]=0);}
                    264:    return m;
                    265: }
                    266:
                    267:
                    268: /*
                    269: ** void binomial_free(binomial m):
                    270: **      reclaim space allocated by binomial_new()
                    271: **
                    272: */
                    273: void binomial_free(binomial m){
                    274:     if (m->E!=0)free((void *)(m->E));
                    275:     free((void *)m);
                    276: }
                    277:
                    278: /*
                    279: ** void binomial_read(FILE *is, binomial b):
                    280: **      read data into binomial
                    281: **
                    282: */
                    283: void binomial_read(FILE *is, binomial b){
                    284:   char c, d='-';
                    285:   eatwhite(is);
                    286:   c=getc(is);
                    287:   /* read in status of facet flag if present*/
                    288:   if (c=='#') b->ff=FACET;
                    289:   else if (c=='!') b->ff=NONFACET;
                    290:   else if (c=='?') b->ff=UNKNOWN;
                    291:   else ungetc(c,is);
                    292:
                    293:   /* read in leading and trailing monomials if present*/
                    294:   eatwhite(is);
                    295:   if ((c=getc(is))=='-') d='+';
                    296:   else ungetc(c,is);
                    297:   get_monomial(is,b->exps1);
                    298:   eatwhite(is);
                    299:   if ((c=getc(is))==d){
                    300:     get_monomial(is,b->exps2);
                    301:     b->bf=BINOMIAL;
                    302:   }else{
                    303:     b->bf=MONOMIAL;
                    304:     ungetc(c,is);
                    305:   }
                    306:   if (d=='+'){
                    307:    if (b->bf==MONOMIAL){
                    308:      fprintf(stderr,"WARNING: binomial_read() monomial with negative coef\n");
                    309:    }
                    310:    binomial_flip(b);
                    311:   }
                    312: }
                    313:
                    314:
                    315: /*
                    316: ** void binomial_print(FILE *,binomial):
                    317: **      print binomial
                    318: **
                    319: */
                    320: void binomial_print(FILE *of, binomial b){
                    321:   if (NT == 1) {
                    322:     if (b==0) fprintf(of,"[ ]");
                    323:     else {
                    324:       /* if (b->ff==FACET) fprintf(of,"# ");
                    325:         else if (b->ff==NONFACET) fprintf(of,"! "); */
                    326:       /*else if (b->ff==UNKNOWN) fprintf(of,"? ");*/
                    327:       fprintf(of,"[");
                    328:       print_monomial(of,b->exps1);
                    329:       if (b->bf==BINOMIAL){
                    330:        fprintf(of," , ");
                    331:        print_monomial(of,b->exps2);
                    332:        fprintf(of,"]");
                    333:       }
                    334:     }
                    335:   }else{
                    336:     if (b==0) fprintf(of,"(NULL)");
                    337:     else {
                    338:       if (b->ff==FACET) fprintf(of,"# ");
                    339:       else if (b->ff==NONFACET) fprintf(of,"! ");
                    340:       /*else if (b->ff==UNKNOWN) fprintf(of,"? ");*/
                    341:       print_monomial(of,b->exps1);
                    342:       if (b->bf==BINOMIAL){
                    343:        fprintf(of,"-");
                    344:        print_monomial(of,b->exps2);
                    345:       }
                    346:     }
                    347:   }
                    348: }
                    349:
                    350: /*
                    351: ** void binomial_copy(binomial src,binomial dest):
                    352: **      copy source binomials exponents and flags to those of dest binomial
                    353: **
                    354: */
                    355: void binomial_copy(binomial src,binomial dest){
                    356:  int i;
                    357:
                    358:  for(i=0;i<ring_N;i++){
                    359:     binomial_lead(dest)[i]=binomial_lead(src)[i];
                    360:     binomial_trail(dest)[i]=binomial_trail(src)[i];
                    361:  }
                    362:  binomial_next(dest)=0;
                    363:  dest->bf=src->bf;
                    364: }
                    365:
                    366: /*
                    367: ** void binomial_flip(binomial b):
                    368: **      interchange leading and trailing terms of binomial
                    369: **
                    370: */
                    371: void binomial_flip(binomial b){
                    372:    int *tmp;
                    373:    tmp=binomial_lead(b);
                    374:    binomial_lead(b)=binomial_trail(b);
                    375:    binomial_trail(b)=tmp;
                    376: }
                    377:
                    378: /*
                    379: ** binomial monomial_spair(binomial b,monomial m):
                    380: **   form spair between marked binomial and marked monomial
                    381: **   and reduce result by binomial as many times as possible
                    382: **
                    383: */
                    384: binomial monomial_spair(binomial b,monomial m){
                    385:   binomial S = 0;
                    386:   int i,tmp;
                    387:
                    388:   S=binomial_new();
                    389:
                    390:   /* form monomial spair i.e. trailing term times factor required to */
                    391:   /* bump lead term up to monomial -- also set trail terms to zero  */
                    392:   for(i=0;i<ring_N;i++){
                    393:     (binomial_lead(S))[i]=(binomial_trail(b))[i];
                    394:     (binomial_trail(S))[i]=0;
                    395:     if ((tmp=(m[i]-(binomial_lead(b))[i]))>0)((binomial_lead(S))[i])+=tmp;
                    396:   }
                    397:
                    398:   /*reduce S by b as many times as possible*/
                    399:   while(monomial_divides(binomial_lead(b),binomial_lead(S))==TRUE){
                    400:     for(i=0;i<ring_N;i++){
                    401:       tmp=(binomial_lead(S))[i]-(binomial_lead(b))[i];
                    402:       (binomial_lead(S))[i]=(binomial_trail(b))[i]+tmp;
                    403:     }
                    404:
                    405:   }
                    406:   return S;
                    407: }
                    408:
                    409: /*
                    410: ** int binomial_spair(binomial b1, binomial b2):
                    411: **     replace b1, by spair of b1 and b2 -- the spair is taken with respect
                    412: **     to the markings of b1 and b2, but it's marking is not meaningfull.
                    413: **     returns TRUE if result is equivalent to zero monomial.
                    414: **
                    415: */
                    416: int binomial_spair(binomial b1, binomial b2){
                    417:    int i,jk,jk2=TRUE;
                    418:    for(i=0;i<ring_N;i++){
                    419:      jk=binomial_lead(b1)[i]-binomial_lead(b2)[i];
                    420:      if (binomial_lead(b1)[i]!=0 && binomial_lead(b2)!=0) jk2=FALSE;
                    421:      binomial_lead(b1)[i]=binomial_trail(b2)[i];
                    422:      if (jk>0) binomial_lead(b1)[i]+=jk;
                    423:      else binomial_trail(b1)[i]-=jk;
                    424:    }
                    425:    jk=monomial_equal(binomial_lead(b1),binomial_trail(b1));
                    426:    if (jk==TRUE || jk2==TRUE) return TRUE;
                    427:    else return FALSE;
                    428: }
                    429:
                    430:
                    431: /*
                    432: **void binomial_bumpto(binomial b1, binomial b2):
                    433: **     assuming that the leading term of b1 divides that of b2
                    434: **     multiply both sides of b1 so that the leading terms of b1
                    435: **     and b2 are equal
                    436: **
                    437: */
                    438: void binomial_bumpto(binomial b1, binomial b2){
                    439:   int i,tmp;
                    440:   for(i=0;i<ring_N;i++){
                    441:     tmp=(binomial_lead(b2))[i]-(binomial_lead(b1))[i];
                    442:     (binomial_lead(b1))[i]+=tmp;
                    443:     (binomial_trail(b1))[i]+=tmp;
                    444:   }
                    445: }
                    446:
                    447: /*
                    448: ** void reducetrail(binomial b1, binomial b2):
                    449: **      assuming that lead(b2) divides trail(b1) change b1 into binomial
                    450: **      resulting from bumping b2 so that lead(b2)=trail(b1) and adding
                    451: **      result to b1.
                    452: **
                    453: */
                    454: void reducetrail(binomial b1, binomial b2){
                    455:       int i;
                    456:       for( i=0;i<ring_N;i++){
                    457:           binomial_trail(b1)[i]+=binomial_trail(b2)[i]-binomial_lead(b2)[i];
                    458:        }
                    459: }
                    460:
                    461: /*
                    462: ** int binomial_compair(binomial b1,binomial b2):
                    463: **     return TRUE if the lead term of b1 is lexicographically greater than
                    464: **     that of b2 or if they tie return true if the trail term b1 is greater
                    465: **     or equal to that of b2 otherwise return false
                    466: */
                    467: int binomial_compair(binomial b1,binomial b2){
                    468:  int tmp;
                    469:
                    470:  tmp=monomial_lexcomp(binomial_lead(b1),binomial_lead(b2));
                    471:  if (tmp>0) return TRUE;
                    472:  else if (tmp<0) return FALSE;
                    473:  else {
                    474:    tmp=monomial_lexcomp(binomial_trail(b1),binomial_trail(b2));
                    475:    if (tmp>=0) return TRUE;
                    476:    else return FALSE;
                    477:  }
                    478: }
                    479:
                    480:
                    481:
                    482:
                    483:
                    484:
                    485:
                    486:
                    487:
                    488:
                    489:
                    490:
                    491:
                    492:

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