Annotation of OpenXM/src/kan96xx/Kan/poly2.c, Revision 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>