[BACK]Return to poly2.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / kan96xx / Kan

Annotation of OpenXM/src/kan96xx/Kan/poly2.c, Revision 1.1.1.1

1.1       maekawa     1: #include <stdio.h>
                      2: #include "datatype.h"
                      3: #include "stackm.h"
                      4: #include "extern.h"
                      5: #include "extern2.h"
                      6:
                      7: static POLY mapZmonom(POLY f,struct ring *ringp);
                      8:
                      9: POLY ppAdd(f,g)
                     10: POLY f; POLY g;  /* The result is read only. */
                     11: {
                     12:   POLY node;
                     13:   struct listPoly nod;
                     14:   POLY h;
                     15:   struct coeff *c;
                     16:   int gt;
                     17:
                     18:   node = &nod;
                     19:   node->next = POLYNULL;
                     20:   h = node;
                     21:   if (f == POLYNULL) return(g);
                     22:   if (g == POLYNULL) return(f);
                     23:   checkRing(f,g);
                     24:
                     25:   while (f != POLYNULL && g != POLYNULL) {
                     26:     /*printf("%s + %s\n",POLYToString(f,'*',1),POLYToString(g,'*',1));*/
                     27:     checkRing2(f,g); /* for debug */
                     28:     gt = (*mmLarger)(f,g);
                     29:     switch (gt) {
                     30:     case 1: /* f > g */
                     31:       h -> next = newCell(f->coeffp,f->m);
                     32:       h = h->next;
                     33:       f = f->next;
                     34:       if (f == POLYNULL) {
                     35:        h->next = g;
                     36:        return(node->next);
                     37:       }
                     38:       break;
                     39:     case 0: /* f < g */
                     40:       h->next = newCell(g->coeffp,g->m);
                     41:       h = h->next;
                     42:       g = g->next;
                     43:       if (g == POLYNULL) {
                     44:        h->next = f;
                     45:        return(node->next);
                     46:       }
                     47:       break;
                     48:     case 2:/* f == g */
                     49:       c = coeffCopy(f->coeffp);
                     50:       Cadd(c,c,g->coeffp);
                     51:       if (!isZero(c)) {
                     52:        h->next = newCell(c,f->m);
                     53:        h = h->next;
                     54:        f = f->next;
                     55:        g = g->next;
                     56:        if (f == POLYNULL) {
                     57:          h->next = g;
                     58:          return(node->next);
                     59:        }
                     60:        if (g == POLYNULL) {
                     61:          h->next = f;
                     62:          return(node->next);
                     63:        }
                     64:       }else{
                     65:        f = f->next;
                     66:        g = g->next;
                     67:        if (f == POLYNULL) {
                     68:          h->next = g;
                     69:          return(node->next);
                     70:        }
                     71:        if (g == POLYNULL) {
                     72:          h->next = f;
                     73:          return(node->next);
                     74:        }
                     75:       }
                     76:       break;
                     77:     default:
                     78:       errorPoly("ppAdd(). Internal error. Invalid value of mmLarger.");
                     79:       break;
                     80:     }
                     81:   }
                     82:   return(node->next);
                     83: }
                     84:
                     85: POLY ppSub(f,g)
                     86: POLY f; POLY g;  /* The result is read only. */
                     87: {
                     88:   POLY h;
                     89:   struct coeff *c;
                     90:
                     91:   if (g == POLYNULL) return(f);
                     92:   if (f == POLYNULL) return(cpMult(intToCoeff(-1,g->m->ringp),g));
                     93:   checkRing(f,g);
                     94:
                     95:   h = cpMult(intToCoeff(-1,g->m->ringp),g);
                     96:   return(ppAdd(f,h));
                     97: }
                     98:
                     99:
                    100: POLY cpMult(c,f)
                    101: struct coeff *c;
                    102: POLY f;
                    103: {
                    104:   POLY node;
                    105:   struct listPoly nod;
                    106:   POLY h;
                    107:   struct coeff *newc;
                    108:   int p;
                    109:   node = &nod;
                    110:   if (f == POLYNULL || isZero(c)) return(POLYNULL);
                    111:   p = f->m->ringp->p;
                    112:   node ->next = POLYNULL;
                    113:   h = node;
                    114:   while (f != POLYNULL) {
                    115:     newc = coeffCopy(c);
                    116:     Cmult(newc,newc,f->coeffp);
                    117:     if ((p==0) || !isZero(newc)) {
                    118:       h->next = newCell(newc,f->m);
                    119:       h = h->next;
                    120:     }
                    121:     f = f->next;
                    122:   }
                    123:   return(node->next);
                    124: }
                    125:
                    126: MONOMIAL monomialAdd_poly(m,m2)
                    127: MONOMIAL m,m2;
                    128: {
                    129:   extern int Msize;
                    130:   MONOMIAL f;
                    131:   int i;
                    132:   int n;
                    133:   n = m->ringp->n;
                    134:   f = (MONOMIAL) sGC_malloc(sizeof(struct smallMonomial)+n*Msize);
                    135:
                    136:   if (f == (MONOMIAL) NULL) errorPoly("No more memory.");
                    137:   f->ringp = m->ringp;
                    138:   for (i=0; i<n; i++) {
                    139:     (f->e)[i].x = (m->e)[i].x + (m2->e)[i].x;
                    140:     (f->e)[i].D = (m->e)[i].D + (m2->e)[i].D;
                    141:   }
                    142:   return(f);
                    143: }
                    144:
                    145: /* Note that mpMult_poly is called from mmLarger_tower! */
                    146: POLY mpMult_poly(f,g)
                    147: POLY f;
                    148: POLY g;
                    149: {
                    150:   POLY node;
                    151:   struct listPoly nod;
                    152:   struct coeff *c;
                    153:   int n,i;
                    154:   POLY h;
                    155:   MONOMIAL m;
                    156:   int p;
                    157:   node = &nod;
                    158:   if (f == POLYNULL || g == POLYNULL) return(POLYNULL);
                    159:   node->next = POLYNULL;
                    160:   h = node;
                    161:   checkRing(f,g);
                    162:   n = f->m->ringp->n; p = f->m->ringp->p;
                    163:   while(g != POLYNULL) {
                    164:     checkRing2(f,g);
                    165:     c = coeffCopy(f->coeffp);
                    166:     Cmult(c,c,g->coeffp);
                    167:     if ((p==0) || !isZero(c)) {
                    168:       m = (*monomialAdd)(f->m,g->m);
                    169:       h->next = newCell(c,m);
                    170:       h = h->next;
                    171:     }
                    172:     g = g->next;
                    173:   }
                    174:   return(node->next);
                    175: }
                    176:
                    177: POLY ppMult_old(f,g)
                    178: POLY f,g;
                    179: {
                    180:   POLY r;
                    181:   POLY tmp;
                    182:   r = POLYNULL;
                    183:   while( f != POLYNULL) {
                    184:     tmp = (*mpMult)(f,g);
                    185:     r = ppAddv(r,tmp); /* r and tmp will be broken */
                    186:     f = f->next;
                    187:   }
                    188:   return(r);
                    189: }
                    190:
                    191: POLY ppAddv(f,g)
                    192: POLY f; POLY g;  /* It breaks f and g. Use it just after calling mpMult() */
                    193: {
                    194:   POLY node;
                    195:   struct listPoly nod;
                    196:   POLY h;
                    197:   struct coeff *c;
                    198:   int gt;
                    199:
                    200:   node = &nod;
                    201:   /*printf("ppAddv:1%s + %s\n",POLYToString(f,'*',1),POLYToString(g,'*',1));*/
                    202:   node->next = POLYNULL;
                    203:   h = node;
                    204:   if (f == POLYNULL) return(g);
                    205:   if (g == POLYNULL) return(f);
                    206:   checkRing(f,g);
                    207:
                    208:   while (f != POLYNULL && g != POLYNULL) {
                    209:     checkRing2(f,g); /* for debug */
                    210:     /*printf("%s + %s\n",POLYToString(f,'*',1),POLYToString(g,'*',1));*/
                    211:     gt = (*mmLarger)(f,g);
                    212:     switch (gt) {
                    213:     case 1: /* f > g */
                    214:       h->next = f;
                    215:       h = h->next; f = f->next;;
                    216:       if (f == POLYNULL) {
                    217:        h->next = g;
                    218:        return(node->next);
                    219:       }
                    220:       break;
                    221:     case 0: /* f < g */
                    222:       h->next =  g;
                    223:       h = h->next; g = g->next;
                    224:       if (g == POLYNULL) {
                    225:        h->next = f;
                    226:        return(node->next);
                    227:       }
                    228:       break;
                    229:     case 2:/* f == g */
                    230:       c = f->coeffp;
                    231:       Cadd(c,c,g->coeffp);
                    232:       if (!isZero(c)) {
                    233:        h->next = f;
                    234:        h = h->next; f = f->next;;
                    235:        g = g->next;
                    236:        if (f == POLYNULL) {
                    237:          h->next = g;
                    238:          return(node->next);
                    239:        }
                    240:        if (g == POLYNULL) {
                    241:          h->next = f;
                    242:          return(node->next);
                    243:        }
                    244:       }else{
                    245:        f = f->next;
                    246:        g = g->next;
                    247:        if (f == POLYNULL) {
                    248:          h->next = g;
                    249:          return(node->next);
                    250:        }
                    251:        if (g == POLYNULL) {
                    252:          h->next = f;
                    253:          return(node->next);
                    254:        }
                    255:       }
                    256:       break;
                    257:     default:
                    258:       errorPoly("ppAddv(). Internal error. Invalid value of mmLarger.");
                    259:       break;
                    260:     }
                    261:   }
                    262:   return(node->next);
                    263: }
                    264:
                    265: POLY pPower(f,k)
                    266: POLY f;
                    267: int k;
                    268: {
                    269:   POLY r;
                    270:   int i,n;
                    271:   if (f == POLYNULL) return(POLYNULL); /* Is it ok? 0^0 = 0.*/
                    272:   if (k == 0) return(cxx(1,0,0,f->m->ringp));
                    273:   if (f->next == POLYNULL &&  k<0) {
                    274:     /* when f is monomial. */
                    275:     r = newCell(coeffCopy(f->coeffp),monomialCopy(f->m));
                    276:     n = r->m->ringp->n;
                    277:     for (i=0; i<n; i++) {
                    278:       r->m->e[i].x *= k;
                    279:       r->m->e[i].D *= k;
                    280:     }
                    281:     if (!isOne(r->coeffp)) {
                    282:       warningPoly("pPower(poly,negative integer) not implemented yet. Returns 1.");
                    283:       r = cxx(1,0,0,f->m->ringp);
                    284:     }
                    285:     return(r);
                    286:   }
                    287:   r = cxx(1,0,0,f->m->ringp);
                    288:   if (k < 0) {
                    289:     warningPoly("pPower(poly,negative integer) not implemented yet. Returns 1.");
                    290:   }
                    291:   for (i=0; i<k; i++) {
                    292:     r = ppMult(f,r);
                    293:   }
                    294:   return(r);
                    295: }
                    296:
                    297: POLY pPower_poly(f,k)
                    298: POLY f;
                    299: int k;
                    300: {
                    301:   POLY r;
                    302:   int i,n;
                    303:   if (f == POLYNULL) return(POLYNULL); /* Is it ok? 0^0 = 0.*/
                    304:   if (k == 0) return(cxx(1,0,0,f->m->ringp));
                    305:   if (f->next == POLYNULL &&  k<0) {
                    306:     /* when f is monomial. */
                    307:     r = newCell(coeffCopy(f->coeffp),monomialCopy(f->m));
                    308:     n = r->m->ringp->n;
                    309:     for (i=0; i<n; i++) {
                    310:       r->m->e[i].x *= k;
                    311:       r->m->e[i].D *= k;
                    312:     }
                    313:     if (!isOne(r->coeffp)) {
                    314:       warningPoly("pPower_poly(poly,negative integer) not implemented yet. Returns 1.");
                    315:       r = cxx(1,0,0,f->m->ringp);
                    316:     }
                    317:     return(r);
                    318:   }
                    319:   r = cxx(1,0,0,f->m->ringp);
                    320:   if (k < 0) {
                    321:     warningPoly("pPower_poly(poly,negative integer) not implemented yet. Returns 1.");
                    322:   }
                    323:   for (i=0; i<k; i++) {
                    324:     r = ppMult_poly(f,r);
                    325:   }
                    326:   return(r);
                    327: }
                    328:
                    329: POLY modulop_trash(f,ringp)
                    330: POLY f;
                    331: struct ring *ringp;
                    332: {
                    333:   int p;
                    334:   POLY h;
                    335:   MP_INT *c;
                    336:   int cc;
                    337:   POLY node;
                    338:   struct ring *nextRing;
                    339:   POLY fc;
                    340:
                    341:   if (f == POLYNULL) return(f);
                    342:   p = ringp->p;
                    343:   if (f->m->ringp->p != 0) {
                    344:     warningPoly("modulop(f,ringp) must be called with f in the characteristic 0 ring. Returns 0.");
                    345:     return(POLYNULL);
                    346:   }
                    347:   if (f->m->ringp->n != ringp->n) {
                    348:     warningPoly("modulop(f,ringp): f->m->ringp->n must be equal to ringp->n. Returns 0.");
                    349:     return(POLYNULL);
                    350:   }
                    351:
                    352:   /* The case of ringp->next != NULL */
                    353:   if (ringp->next != (struct ring *)NULL) {
                    354:     nextRing = ringp->next;
                    355:     node = newCell(newCoeff(),newMonomial(ringp));
                    356:     node->next = POLYNULL;
                    357:     h = node;
                    358:
                    359:     while (f != POLYNULL) {
                    360:       fc = bxx(f->coeffp->val.bigp,0,0,nextRing);
                    361:       h->next = newCell(newCoeff(),monomialCopy(f->m));
                    362:       h = h->next;
                    363:       h->m->ringp = ringp;
                    364:       h->coeffp->tag = POLY_COEFF;
                    365:       h->coeffp->p = p;
                    366:       h->coeffp->val.f = fc;
                    367:       f = f->next;
                    368:     }
                    369:     return(node->next);
                    370:   }
                    371:
                    372:
                    373:   /* In case of ringp->next == NULL */
                    374:   if (p != 0) {
                    375:     c = newMP_INT();
                    376:     node = newCell(newCoeff(),newMonomial(ringp));
                    377:     node->next = POLYNULL;
                    378:     h = node;
                    379:
                    380:     while (f != POLYNULL) {
                    381:       mpz_mod_ui(c,f->coeffp->val.bigp,(unsigned long int)p);
                    382:       cc = (int) mpz_get_si(c);
                    383:       if (cc != 0) {
                    384:        h->next = newCell(newCoeff(),monomialCopy(f->m));
                    385:        h = h->next;
                    386:        h->m->ringp = ringp;
                    387:        h->coeffp->tag = INTEGER;
                    388:        h->coeffp->p = p;
                    389:        h->coeffp->val.i = cc;
                    390:       }
                    391:       f = f->next;
                    392:     }
                    393:     return(node->next);
                    394:   }else{
                    395:     h = f = pcmCopy(f);
                    396:     while (f != POLYNULL) {
                    397:       f->m->ringp = ringp;
                    398:       f = f->next;
                    399:     }
                    400:     return(h);
                    401:   }
                    402:
                    403: }
                    404:
                    405: POLY modulop(f,ringp)
                    406: POLY f;
                    407: struct ring *ringp;
                    408: /* Z[x] ---> R[x] where R=Z, Z/Zp, ringp->next. */
                    409: {
                    410:   int p;
                    411:   POLY h;
                    412:   MP_INT *c;
                    413:   int cc;
                    414:   POLY node;
                    415:   POLY fc;
                    416:
                    417:   if (f == POLYNULL) return(f);
                    418:   p = ringp->p;
                    419:   if (f->m->ringp->p != 0 || f->m->ringp->next != (struct ring *)NULL) {
                    420:     warningPoly("modulop(f,ringp) must be called with f in the characteristic 0 ring Z[x]. Returns 0.");
                    421:     return(POLYNULL);
                    422:   }
                    423:   if (f->m->ringp->n != ringp->n) {
                    424:     warningPoly("modulop(f,ringp): f->m->ringp->n must be equal to ringp->n. Returns 0.");
                    425:     return(POLYNULL);
                    426:   }
                    427:
                    428:   /* [1] The case of R = ringp->next */
                    429:   if (ringp->next != (struct ring *)NULL) {
                    430:     h = ZERO;
                    431:     while (f != POLYNULL) {
                    432:       h = ppAdd(h,mapZmonom(f,ringp));
                    433:       f = f->next;
                    434:     }
                    435:     return(h);
                    436:   }
                    437:
                    438:   /* [2] The case of R = Z/Zp */
                    439:   if (p != 0) {
                    440:     c = newMP_INT();
                    441:     node = newCell(newCoeff(),newMonomial(ringp));
                    442:     node->next = POLYNULL;
                    443:     h = node;
                    444:
                    445:     while (f != POLYNULL) {
                    446:       mpz_mod_ui(c,f->coeffp->val.bigp,(unsigned long int)p);
                    447:       cc = (int) mpz_get_si(c);
                    448:       if (cc != 0) {
                    449:        h->next = newCell(newCoeff(),monomialCopy(f->m));
                    450:        h = h->next;
                    451:        h->m->ringp = ringp;
                    452:        h->coeffp->tag = INTEGER;
                    453:        h->coeffp->p = p;
                    454:        h->coeffp->val.i = cc;
                    455:       }
                    456:       f = f->next;
                    457:     }
                    458:     return(node->next);
                    459:   }
                    460:
                    461:   /* [3] The case of R = Z */
                    462:   h = f = pcmCopy(f);
                    463:   while (f != POLYNULL) {
                    464:     f->m->ringp = ringp;
                    465:     f = f->next;
                    466:   }
                    467:   return(h);
                    468:
                    469:
                    470: }
                    471:
                    472: POLY modulopZ(f,pcoeff)
                    473: POLY f;
                    474: struct coeff *pcoeff;
                    475: /* Z[x] ---> Z[x] , f ---> f mod pcoeff*/
                    476: {
                    477:   int p;
                    478:   POLY h;
                    479:   struct coeff *c;
                    480:   int cc;
                    481:   POLY node;
                    482:   POLY fc;
                    483:   MP_INT *bigp;
                    484:   MP_INT *tmp;
                    485:   struct ring *ringp;
                    486:
                    487:   if (f == POLYNULL) return(f);
                    488:   ringp = f->m->ringp;
                    489:   if (pcoeff->tag != MP_INTEGER) {
                    490:     warningPoly("modulopZ(): pcoeff must be a universalNumber.");
                    491:     warningPoly("Returns 0.");
                    492:     return(POLYNULL);
                    493:   }
                    494:   bigp = pcoeff->val.bigp;
                    495:   if (f->m->ringp->p != 0 || f->m->ringp->next != (struct ring *)NULL) {
                    496:     warningPoly("modulopZ(f,p) must be called with f in the characteristic 0 ring Z[x]. Returns 0.");
                    497:     return(POLYNULL);
                    498:   }
                    499:   if (f->m->ringp->n != ringp->n) {
                    500:     warningPoly("modulop(f,ringp): f->m->ringp->n must be equal to ringp->n. Returns 0.");
                    501:     return(POLYNULL);
                    502:   }
                    503:
                    504:   /* [1] The case of R = ringp->next */
                    505:   if (ringp->next != (struct ring *)NULL) {
                    506:     warningPoly("modulopZ workds only for flat polynomials. Returns 0.");
                    507:     return(POLYNULL);
                    508:   }
                    509:
                    510:   /* [2] The case of R = Z */
                    511:   node = newCell(newCoeff(),newMonomial(ringp));
                    512:   node->next = POLYNULL;
                    513:   h = node;
                    514:
                    515:   c = newCoeff();
                    516:   tmp = newMP_INT();
                    517:   while (f != POLYNULL) {
                    518:     mpz_mod(tmp,f->coeffp->val.bigp,bigp);
                    519:     if (mpz_sgn(tmp) != 0) {
                    520:       c->tag = MP_INTEGER;
                    521:       c->p = 0;
                    522:       c->val.bigp = tmp;
                    523:       h->next = newCell(c,monomialCopy(f->m));
                    524:       h = h->next;
                    525:       h->m->ringp = ringp;
                    526:
                    527:       c = newCoeff();
                    528:       tmp = newMP_INT();
                    529:     }
                    530:     f = f->next;
                    531:   }
                    532:   return(node->next);
                    533:
                    534: }
                    535:
                    536: struct pairOfPOLY quotientByNumber(f,pcoeff)
                    537: POLY f;
                    538: struct coeff *pcoeff;
                    539: /* Z[x] ---> Z[x],Z[x] ,  f = first*pcoeff + second */
                    540: {
                    541:   int p;
                    542:   POLY h;
                    543:   POLY h2;
                    544:   struct coeff *c;
                    545:   int cc;
                    546:   POLY node;
                    547:   struct coeff *c2;
                    548:   POLY node2;
                    549:   POLY fc;
                    550:   MP_INT *bigp;
                    551:   MP_INT *tmp;
                    552:   MP_INT *tmp2;
                    553:   struct ring *ringp;
                    554:   struct pairOfPOLY r;
                    555:
                    556:   if (f == POLYNULL) {
                    557:     r.first = f; r.second = f;
                    558:     return(r);
                    559:   }
                    560:   ringp = f->m->ringp;
                    561:   if (pcoeff->tag != MP_INTEGER) {
                    562:     warningPoly("quotientByNumber(): pcoeff must be a universalNumber.");
                    563:     warningPoly("Returns (0,0).");
                    564:     r.first = f; r.second = f;
                    565:     return(r);
                    566:   }
                    567:   bigp = pcoeff->val.bigp;
                    568:   if (f->m->ringp->p != 0 || f->m->ringp->next != (struct ring *)NULL) {
                    569:     warningPoly("quotientByNumber(f,p) must be called with f in the characteristic 0 ring Z[x]. Returns (0,0).");
                    570:     r.first = f; r.second = f;
                    571:     return(r);
                    572:   }
                    573:   if (f->m->ringp->n != ringp->n) {
                    574:     warningPoly("quotientByNumber(f,p): f->m->ringp->n must be equal to ringp->n. Returns 0.");
                    575:     r.first = f; r.second = f;
                    576:     return(r);
                    577:   }
                    578:
                    579:   /* [1] The case of R = ringp->next */
                    580:   if (ringp->next != (struct ring *)NULL) {
                    581:     warningPoly("quotientByNumber() workds only for flat polynomials. Returns 0.");
                    582:     r.first = f; r.second = f;
                    583:     return(r);
                    584:   }
                    585:
                    586:   /* [2] The case of R = Z */
                    587:   node = newCell(newCoeff(),newMonomial(ringp));
                    588:   node->next = POLYNULL;
                    589:   h = node;
                    590:   node2 = newCell(newCoeff(),newMonomial(ringp));
                    591:   node2->next = POLYNULL;
                    592:   h2 = node2;
                    593:
                    594:   c = newCoeff();
                    595:   tmp = newMP_INT();
                    596:   c2 = newCoeff();
                    597:   tmp2 = newMP_INT();
                    598:   while (f != POLYNULL) {
                    599:     mpz_mod(tmp,f->coeffp->val.bigp,bigp);
                    600:     if (mpz_sgn(tmp) != 0) {
                    601:       c->tag = MP_INTEGER;
                    602:       c->p = 0;
                    603:       c->val.bigp = tmp;
                    604:       h->next = newCell(c,monomialCopy(f->m));
                    605:       h = h->next;
                    606:       h->m->ringp = ringp;
                    607:
                    608:       c = newCoeff();
                    609:       tmp = newMP_INT();
                    610:     }
                    611:     mpz_tdiv_q(tmp2,f->coeffp->val.bigp,bigp);
                    612:     if (mpz_sgn(tmp2) != 0) {
                    613:       c2->tag = MP_INTEGER;
                    614:       c2->p = 0;
                    615:       c2->val.bigp = tmp2;
                    616:       h2->next = newCell(c2,monomialCopy(f->m));
                    617:       h2 = h2->next;
                    618:       h2->m->ringp = ringp;
                    619:
                    620:       c2 = newCoeff();
                    621:       tmp2 = newMP_INT();
                    622:     }
                    623:     f = f->next;
                    624:   }
                    625:   r.first = node2->next;
                    626:   r.second = node->next;
                    627:   return(r);
                    628:
                    629: }
                    630:
                    631:
                    632: POLY modulo0(f,ringp)
                    633: POLY f;
                    634: struct ring *ringp;
                    635: {
                    636:   int p;
                    637:   POLY h;
                    638:   struct coeff *c;
                    639:   POLY node;
                    640:   if (f == POLYNULL) return(f);
                    641:   p = ringp->p;
                    642:   if (p != 0) {
                    643:     warningPoly("modulo0(f,ringp) must be called with the characteristic 0 ring*ringp. Returns 0.");
                    644:     return(POLYNULL);
                    645:   }
                    646:   switch (f->coeffp->tag) {
                    647:   case MP_INTEGER:
                    648:     if (f->m->ringp->p == 0) {
                    649:       node = pcmCopy(f);
                    650:       f = node;
                    651:       while (f != POLYNULL) {
                    652:        f->m->ringp = ringp; /* Touch the monomial "ringp" field. */
                    653:        f = f->next;
                    654:       }
                    655:       return(node);
                    656:     }
                    657:     break;
                    658:   case POLY_COEFF:
                    659:     node = pcmCopy(f);
                    660:     f = node;
                    661:     while (f != POLYNULL) {
                    662:       f->m->ringp = ringp; /* Touch the monomial "ringp" field. */
                    663:       f = f->next;
                    664:     }
                    665:     return(node);
                    666:     break;
                    667:   case INTEGER:
                    668:     node = newCell(newCoeff(),newMonomial(ringp));
                    669:     node->next = POLYNULL;
                    670:     h = node;
                    671:
                    672:     while (f != POLYNULL) {
                    673:       c = newCoeff();
                    674:       c->tag = MP_INTEGER;
                    675:       c->p = 0;
                    676:       c->val.bigp = newMP_INT();
                    677:       mpz_set_si(c->val.bigp,f->coeffp->val.i);
                    678:       h->next = newCell(c,monomialCopy(f->m));
                    679:       h = h->next;
                    680:       h->m->ringp = ringp;
                    681:       f = f->next;
                    682:     }
                    683:     return(node->next);
                    684:     break;
                    685:   default:
                    686:     warningPoly("modulo0(): coefficients have to be MP_INTEGER or INTEGER. Returns 0");
                    687:     return(POLYNULL);
                    688:     break;
                    689:   }
                    690: }
                    691:
                    692:
                    693: struct object test(ob)  /* test3 */
                    694: struct object ob;
                    695: {
                    696:   struct object rob;
                    697:   int k;
                    698:   static POLY f0;
                    699:   static POLY f1;
                    700:
                    701:   POLY addNode;
                    702:   POLY f;
                    703:   int i;
                    704:   static int s=0;
                    705:   MP_INT *mp;
                    706:   extern struct ring *SmallRingp;
                    707:   extern struct ring *CurrentRingp;
                    708:   addNode = pMalloc(SmallRingp);
                    709:   k = ob.lc.ival;
                    710:   switch(s) {
                    711:   case 0:
                    712:     f0 = addNode;
                    713:     for (i=k; i>=0; i--) {
                    714:       f0->next = bxx(BiiPower(-k,i),0,i,CurrentRingp);
                    715:       if (f0->next != POLYNULL) {
                    716:        f0 = f0->next;
                    717:       }
                    718:     }
                    719:     f0 = addNode->next;
                    720:     s++;
                    721:     rob.lc.poly = f0;
                    722:     break;
                    723:   case 1:
                    724:     f1 = addNode;
                    725:     for (i=k; i>=0; i--) {
                    726:       f1->next = bxx(BiiPower(k,i),0,i,CurrentRingp);
                    727:       if (f1->next != POLYNULL) {
                    728:        f1 = f1->next;
                    729:       }
                    730:     }
                    731:     f1 = addNode->next;
                    732:     s = 0;
                    733:     rob.lc.poly = f1;
                    734:     break;
                    735:   default:
                    736:     rob.lc.poly = POLYNULL;
                    737:     s = 0;
                    738:     break;
                    739:   }
                    740:
                    741:
                    742:   rob.tag = Spoly;
                    743:   return(rob);
                    744: }
                    745:
                    746:
                    747: int pLength(f)
                    748: POLY f;
                    749: {
                    750:   int c=0;
                    751:   if (f ISZERO) return(0);
                    752:   while (f != POLYNULL) {
                    753:     c++;
                    754:     f = f->next;
                    755:   }
                    756:   return(c);
                    757: }
                    758:
                    759:
                    760: POLY ppAddv2(f,g,top,nexttop)
                    761: POLY f; POLY g;  /* It breaks f and g. Use it just after calling mpMult() */
                    762: POLY top;
                    763: POLY *nexttop;
                    764: /* top is the starting address in the list f.
                    765:    if top == POLYNULL, start from f.
                    766:
                    767:    *nexttop == 0
                    768:             == g
                    769:             == h or 0
                    770:
                    771:   It must be called as r = ppAddv2(r,g,...);
                    772: */
                    773: {
                    774:   POLY node;
                    775:   struct listPoly nod;
                    776:   POLY h;
                    777:   struct coeff *c;
                    778:   int gt;
                    779:   POLY g0;
                    780:   POLY f0; /* for debug */
                    781:
                    782:   node = &nod;
                    783:   /* printf("ppAddv:1%s + %s\n",POLYToString(f,'*',1),POLYToString(g,'*',1)); */
                    784:   node->next = POLYNULL;
                    785:   h = node;
                    786:   *nexttop = POLYNULL;
                    787:   if (f == POLYNULL) return(g);
                    788:   if (g == POLYNULL) return(f);
                    789:   checkRing(f,g);
                    790:
                    791:   f0 = f;
                    792:   if (top != POLYNULL) {
                    793:     while (f != top) {
                    794:       if (f == POLYNULL) {
                    795:        fprintf(stderr,"\nppAddv2(): Internal error.\n");fflush(stderr);
                    796:        fprintf(stderr,"f = %s\n",POLYToString(f0,'*',0));
                    797:        fprintf(stderr,"g = %s\n",POLYToString(g0,'*',0));
                    798:        fprintf(stderr,"top=%s\n",POLYToString(top,'*',0));
                    799:        errorPoly("ppAddv2(). Internal error=1.");
                    800:       }
                    801:       h->next = f;
                    802:       h = h->next;
                    803:       f = f->next;
                    804:     }
                    805:   }
                    806:   g0 = g;
                    807:   *nexttop = g0;
                    808:
                    809:   while (f != POLYNULL && g != POLYNULL) {
                    810:     checkRing2(f,g); /* for debug */
                    811:     /* printf("%s + %s\n",POLYToString(f,'*',1),POLYToString(g,'*',1)); */
                    812:     gt = (*mmLarger)(f,g);
                    813:     switch (gt) {
                    814:     case 1: /* f > g */
                    815:       h->next = f;
                    816:       h = h->next; f = f->next;;
                    817:       if (f == POLYNULL) {
                    818:        h->next = g;
                    819:        return(node->next);
                    820:       }
                    821:       break;
                    822:     case 0: /* f < g */
                    823:       h->next =  g;
                    824:       h = h->next; g = g->next;
                    825:       if (g == POLYNULL) {
                    826:        h->next = f;
                    827:        return(node->next);
                    828:       }
                    829:       break;
                    830:     case 2:/* f == g */
                    831:       c = g->coeffp;
                    832:       Cadd(c,f->coeffp,c);
                    833:       if (!isZero(c)) {
                    834:        h->next = g;
                    835:        h = h->next;
                    836:        f = f->next;;
                    837:        g = g->next;
                    838:        if (f == POLYNULL) {
                    839:          h->next = g;
                    840:          return(node->next);
                    841:        }
                    842:        if (g == POLYNULL) {
                    843:          h->next = f;
                    844:          return(node->next);
                    845:        }
                    846:       }else{
                    847:        if (g == g0) {
                    848:          if (h != node) {
                    849:            *nexttop = h;
                    850:          }else{
                    851:            *nexttop = POLYNULL;
                    852:          }
                    853:        }
                    854:
                    855:        f = f->next;
                    856:        g = g->next;
                    857:
                    858:        if (f == POLYNULL) {
                    859:          h->next = g;
                    860:          return(node->next);
                    861:        }
                    862:        if (g == POLYNULL) {
                    863:          h->next = f;
                    864:          return(node->next);
                    865:        }
                    866:       }
                    867:       break;
                    868:     default:
                    869:       errorPoly("ppAddv(). Internal error. Invalid value of mmLarger.");
                    870:       break;
                    871:     }
                    872:   }
                    873:   return(node->next);
                    874: }
                    875:
                    876: POLY ppMult(f,g)
                    877: POLY f,g;
                    878: {
                    879:   POLY r;
                    880:   POLY tmp;
                    881:   POLY top;
                    882:   POLY nexttop;
                    883:   r = POLYNULL; top = POLYNULL;
                    884:   while( f != POLYNULL) {
                    885:     /* tmp = (*mpMult)(f,g);  (*mpMult) is no more used. */
                    886:     tmp = (*(f->m->ringp->multiplication))(f,g);
                    887:     /*printf("mpMult(%s,%s) ->%s\n",POLYToString(f,'*',1),POLYToString(g,'*',1),POLYToString(tmp,'*',1)); */
                    888:     r = ppAddv2(r,tmp,top,&nexttop); /* r and tmp will be broken */
                    889:     top = nexttop;
                    890:     f = f->next;
                    891:   }
                    892:   return(r);
                    893: }
                    894:
                    895: POLY ppMult_poly(f,g)
                    896: POLY f,g;
                    897: {
                    898:   POLY r;
                    899:   POLY tmp;
                    900:   POLY top;
                    901:   POLY nexttop;
                    902:   r = POLYNULL; top = POLYNULL;
                    903:   while( f != POLYNULL) {
                    904:     tmp = mpMult_poly(f,g);
                    905:     r = ppAddv2(r,tmp,top,&nexttop); /* r and tmp will be broken */
                    906:     top = nexttop;
                    907:     f = f->next;
                    908:   }
                    909:   return(r);
                    910: }
                    911:
                    912: POLY mapZmonom(f,ringp)
                    913: POLY f; /* assumes monomial. f \in Z[x] */
                    914: struct ring *ringp;  /* R[x] */
                    915: {
                    916:   struct ring *nextRing;
                    917:   struct ring nextRing0;
                    918:   POLY ff;
                    919:   POLY node;
                    920:   POLY gg;
                    921:   int l,c,d;
                    922:
                    923:   nextRing = ringp->next;
                    924:   nextRing0 = *nextRing; nextRing0.p = 0; nextRing0.next = 0;
                    925:   /* nextRing0 = Z[y] where y is the variables of R. */
                    926:
                    927:   ff = bxx(f->coeffp->val.bigp,0,0,&nextRing0);
                    928:   ff = modulop(ff,nextRing);
                    929:
                    930:   node = newCell(newCoeff(),monomialCopy(f->m));
                    931:   node->next = POLYNULL;
                    932:   node->m->ringp = ringp;
                    933:
                    934:   node->coeffp->p = ringp->p;
                    935:
                    936:   l = ringp->l; c = ringp->c;
                    937:   /* If q-analog  q x ---> (q) x. */
                    938:   if (l-c > 0) {
                    939:     d = node->m->e[0].x;  /* degree of q in R[x].*/
                    940:     node->m->e[0].x = 0;
                    941:     gg = cxx(1,0,d,nextRing); /* q^d = x[0]^d */
                    942:     ff = ppMult(gg,ff);
                    943:   }
                    944:
                    945:   node->coeffp->tag = POLY_COEFF;
                    946:   node->coeffp->val.f = ff;
                    947:   return(node);
                    948: }
                    949:

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