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>