Annotation of OpenXM/src/kan96xx/Kan/Kclass/indeterminate.c, Revision 1.7
1.7 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/Kan/Kclass/indeterminate.c,v 1.6 2001/09/01 01:37:48 takayama Exp $ */
1.1 maekawa 2: /* Kclass/indeterminate.c */
1.7 ! takayama 3: /* This file handles indeterminate, recursivePolynomial,
1.1 maekawa 4: polynomialInOneVariable
5: */
6: #include <stdio.h>
7: #include "../datatype.h"
8: #include "../stackm.h"
9: #include "../extern.h"
10: #include "../gradedset.h"
11: #include "../extern2.h"
12: #include "../kclass.h"
13:
14:
15: /* Data conversion function : see KclassDataConversion*/
16: struct object KpoIndeterminate(struct object ob) {
17: struct object rob;
18: struct object *newobp;
19: rob.tag = Sclass;
20: rob.lc.ival = CLASSNAME_indeterminate;
21: newobp = (struct object *) sGC_malloc(sizeof(struct object));
22: if (newobp == NULL) errorKan1("%s\n","Kclass/indeterminate.c, no more memory.");
23: if (ob.tag != Sdollar) {
24: errorKan1("%s\n","Kclass/indeterminate.c, only String object can be transformed into indeterminate.");
25: }
26: *newobp = ob;
27: rob.rc.voidp = newobp;
28: return(rob);
29: }
30:
31: /* The second constructor. */
32: struct object KnewIndeterminate(char *s) {
33: struct object ob;
34:
35: ob = KpoString(s); /* We do not clone s */
36: return(KpoIndeterminate(ob));
37: }
38:
39:
40: /* Printing function : see fprintClass */
41: void fprintIndeterminate(FILE *fp,struct object op)
42: {
43: printObject(KopIndeterminate(op),0,fp);
44: }
45:
1.7 ! takayama 46: /* Functions for trees are moved to tree.c */
1.1 maekawa 47: /* ---------------------------------------------------- */
48:
49: struct object KpoRecursivePolynomial(struct object ob) {
50: struct object rob;
51: struct object *newobp;
52: rob.tag = Sclass;
53: rob.lc.ival = CLASSNAME_recursivePolynomial;
54: newobp = (struct object *) sGC_malloc(sizeof(struct object));
55: if (newobp == NULL) errorKan1("%s\n","Kclass/indeterminate.c, no more memory.");
56: if (ob.tag != Sarray) {
57: errorKan1("%s\n","Kclass/indeterminate.c, only array object can be transformed into recusivePolynomial.");
58: }
59: *newobp = ob;
60: rob.rc.voidp = newobp;
61: return(rob);
62: }
63:
64: static void printBodyOfRecursivePolynomial(struct object body,
1.5 takayama 65: struct object vlist, FILE *fp)
1.1 maekawa 66: {
67: int i,j;
68: int k;
69: if (ectag(body) != CLASSNAME_polynomialInOneVariable) {
70: printObject(body,0,fp);
71: return;
72: }
73: body = KopPolynomialInOneVariable(body);
74: if (body.tag != Sarray) {
75: errorKan1("%s\n","Kclass/indeterminate.c, format error for recursive polynomial.");
76: }
77: if (getoaSize(body) == 0) {
78: errorKan1("%s\n","printBodyOfRecursivePolynomial: format error for a recursive polynomial.");
79: }
80: i = KopInteger(getoa(body,0));
81: for (j=1; j<getoaSize(body); j = j+2) {
82: k = KopInteger(getoa(body,j));
83: if (k != 0) {
1.5 takayama 84: if (getoa(vlist,i).tag == Sdollar) {
85: fprintf(fp,"%s",KopString(getoa(vlist,i)));
86: }else if (ectag(getoa(vlist,i)) == CLASSNAME_tree) {
87: fprintClass(fp,getoa(vlist,i));
88: }else{
89: errorKan1("%s\n","printBodyOfRecursivePolynomial: format error.");
90: }
1.1 maekawa 91: if (k > 1) {
1.5 takayama 92: fprintf(fp,"^%d ",k);
1.1 maekawa 93: }else if (k == 1) {
94: }else{
1.5 takayama 95: fprintf(fp,"^(%d) ",k);
1.1 maekawa 96: }
97: fprintf(fp," * ");
98: }
99: fprintf(fp,"(");
100: printBodyOfRecursivePolynomial(getoa(body,j+1),vlist,fp);
101: fprintf(fp,")");
102: if (j != getoaSize(body)-2) {
103: fprintf(fp," + ");
104: }
105: }
106: return;
107: }
108:
109: void fprintRecursivePolynomial(FILE *fp,struct object op)
110: {
111: /* old code
1.5 takayama 112: printObject(KopRecursivePolynomial(op),0,fp); return;
1.1 maekawa 113: */
114: struct object ob;
115: struct object vlist;
116: struct object body;
117: ob = KopRecursivePolynomial(op);
118: if (ob.tag != Sarray) {
119: printObject(ob,0,fp); return;
120: }
121: if (!isRecursivePolynomial2(op)) {
122: printObject(KopRecursivePolynomial(op),0,fp); return;
123: }
124: vlist = getoa(ob,0);
125: body = getoa(ob,1);
126: printBodyOfRecursivePolynomial(body,vlist,fp);
127: return;
128: }
129:
130: /*------------------------------------------*/
131:
132: struct object KpoPolynomialInOneVariable(struct object ob) {
133: struct object rob;
134: struct object *newobp;
135: rob.tag = Sclass;
136: rob.lc.ival = CLASSNAME_polynomialInOneVariable;
137: newobp = (struct object *) sGC_malloc(sizeof(struct object));
138: if (newobp == NULL) errorKan1("%s\n","Kclass/indeterminate.c, no more memory.");
139: if (ob.tag != Sarray) {
140: errorKan1("%s\n","Kclass/indeterminate.c, only array object can be transformed into polynomialInOneVariable.");
141: }
142: *newobp = ob;
143: rob.rc.voidp = newobp;
144: return(rob);
145: }
146:
147: void fprintPolynomialInOneVariable(FILE *fp,struct object op)
148: {
149: printObject(KopPolynomialInOneVariable(op),0,fp);
150: }
151:
152: struct object polyToRecursivePoly(struct object p) {
153: struct object rob = NullObject;
154: int vx[N0], vd[N0];
155: int i,j,k,n,count;
156: POLY f;
157: struct object vlist,vlist2;
158: struct object ob1,ob2,ob3,ob4;
159: int vn;
160:
161: if (p.tag != Spoly) return(rob);
162: f = KopPOLY(p);
163: if (f == ZERO) {
164: rob = p; return(rob);
165: }
166: /* construct list of variables. */
167: for (i=0; i<N0; i++) {
168: vx[i] = vd[i] = 0;
169: }
170: n = f->m->ringp->n; count = 0;
171: for (i=0; i<n; i++) {
172: if (pDegreeWrtV(f,cxx(1,i,1,f->m->ringp))) {
173: vx[i] = 1; count++;
174: }
175: if (pDegreeWrtV(f,cdd(1,i,1,f->m->ringp))) {
176: vd[i] = 1; count++;
177: }
178: }
179: vlist = newObjectArray(count); k = 0;
180: vlist2 = newObjectArray(count); k = 0;
181: for (i=0; i<n; i++) {
182: if (vd[i]) {
183: putoa(vlist,k,KpoPOLY(cdd(1,i,1,f->m->ringp)));
184: putoa(vlist2,k,KpoString(POLYToString(cdd(1,i,1,f->m->ringp),'*',0)));
185: k++;
186: }
187: }
188: for (i=0; i<n; i++) {
189: if (vx[i]) {
190: putoa(vlist,k,KpoPOLY(cxx(1,i,1,f->m->ringp)));
191: putoa(vlist2,k,KpoString(POLYToString(cxx(1,i,1,f->m->ringp),'*',0)));
192: k++;
193: }
194: }
195: /* printObject(vlist,1,stdout); */
196: if (getoaSize(vlist) == 0) {
197: vn = -1;
198: }else{
199: vn = 0;
200: }
201: ob1 = polyToRecursivePoly2(p,vlist,vn);
202: rob = newObjectArray(2);
203: putoa(rob,0,vlist2); putoa(rob,1,ob1);
204: /* format of rob
205: [ list of variables, poly or universalNumber or yyy to express
1.5 takayama 206: a recursive polynomial. ]
207: format of yyy = CLASSNAME_polynomialInOneVariable
1.1 maekawa 208: [Sinteger, Sinteger, coeff obj, Sinteger, coeff obj, .....]
1.5 takayama 209: name of var, exp, coeff, exp, coeff
210: This format is checked by isRecursivePolynomial2().
1.1 maekawa 211: */
212: rob = KpoRecursivePolynomial(rob);
213: if (isRecursivePolynomial2(rob)) {
214: return(rob);
215: }else{
216: errorKan1("%s\n","polyToRecursivePolynomial could not translate this object.");
217: }
218: }
219:
220: static void objectFormatError_ind0(char *s) {
221: char tmp[1024];
222: sprintf(tmp,"polyToRecursivePoly2: object format error for the variable %s",s);
223: errorKan1("%s\n",tmp);
224: }
225:
226: struct object polyToRecursivePoly2(struct object p,struct object vlist, int vn) {
227: struct object rob = NullObject;
228: POLY f;
229: POLY vv;
230: struct object v;
231: struct object c;
232: struct object e;
233: int i;
234:
235:
236: if (p.tag != Spoly) return(rob);
237: f = KopPOLY(p);
238: if (f == ZERO) {
239: rob = p; return(rob);
240: }
241: if (vn < 0 || vn >= getoaSize(vlist)) {
242: return(coeffToObject(f->coeffp));
243: }
244: v = getoa(vlist,vn);
245: if (v.tag != Spoly) objectFormatError_ind0("v");
246: vv = KopPOLY(v);
247: c = parts2(f,vv);
248: e = getoa(c,0); /* exponents. Array of integer. */
249: if (e.tag != Sarray) objectFormatError_ind0("e");
250: c = getoa(c,1); /* coefficients. Array of POLY. */
251: if (c.tag != Sarray) objectFormatError_ind0("c");
252: rob = newObjectArray(getoaSize(e)*2+1);
253:
254: putoa(rob,0,KpoInteger(vn)); /* put the variable number. */
255: for (i=0; i < getoaSize(e); i++) {
256: putoa(rob,1+i*2, getoa(e,i));
257: putoa(rob,1+i*2+1, polyToRecursivePoly2(getoa(c,i),vlist,vn+1));
258: }
259: /* printObject(rob,0,stderr); */
260: return(KpoPolynomialInOneVariable(rob));
261: }
262:
263: static int isRecursivePolynomial2a(struct object ob2, int n) {
264: char *s = "Format error (isRecursivePolynomial2a) : ";
265: struct object tmp;
266: int i;
267: if (ectag(ob2) == CLASSNAME_polynomialInOneVariable) {
268: ob2 = KopPolynomialInOneVariable(ob2);
269: }else if (ob2.tag == Sarray) {
270: fprintf(stderr,"isRecursivePolynomial2, argument is an array.\n");
271: printObject(ob2,0,stderr);
272: fprintf(stderr,"\n");
273: return(0); /* Array must be an error, but other objects are OK. */
274: }else {
275: return(1);
276: }
277: if (ob2.tag != Sarray) {
278: return(1);
279: /* coeff can be any. */
280: }
281: if (getoaSize(ob2) % 2 == 0) {
282: fprintf(stderr,"%s list body. The size of body must be odd.\n",s); printObject(ob2,1,stderr);
283: return(0);
284: }
285: tmp = getoa(ob2,0);
286: if (tmp.tag != Sinteger) {
287: fprintf(stderr,"%s list body. body[0] must be integer.\n",s); printObject(ob2,1,stderr);
288: return(0);
289: }
290: if (KopInteger(tmp) < 0 || KopInteger(tmp) >= n) {
291: fprintf(stderr,"%s list body. body[0] must be integer between 0 and the size of vlist -1.\n",s); printObject(ob2,1,stderr);
292: return(0);
293: }
294: for (i=1; i<getoaSize(ob2); i = i+2) {
295: tmp = getoa(ob2,i);
296: if (tmp.tag != Sinteger) {
297: fprintf(stderr,"%s [list vlist, list body]. body[%d] must be integer.\n",s,i);
298: printObject(ob2,1,stderr);
299: return(0);
300: }
301: }
302: for (i=2; i<getoaSize(ob2); i = i+2) {
303: tmp = getoa(ob2,i);
304: if (ectag(tmp) == CLASSNAME_polynomialInOneVariable) {
305: if (isRecursivePolynomial2a(tmp,n)) {
306: }else{
1.5 takayama 307: fprintf(stderr,"isRecursivePolynomial2a: entry is not a polynomial in one variable.\n");
308: printObject(tmp,0,stderr); fprintf(stderr,"\n");
309: return(0);
1.1 maekawa 310: }
311: }
312: }
313: return(1);
314: }
315:
316: int isRecursivePolynomial2(struct object ob) {
317: /* This checks only the top level */
318: char *s = "Format error (isRecursivePolynomial2) : ";
319: struct object ob1, ob2,tmp;
320: int i;
321: int n;
322: if (ob.tag != Sclass) return(0);
323: if (ectag(ob) != CLASSNAME_recursivePolynomial) return(0);
324: ob = KopRecursivePolynomial(ob);
325: if (ob.tag != Sarray) {
326: fprintf(stderr,"%s [vlist, body]\n",s); printObject(ob,1,stderr);
327: return(0);
328: }
329: if (getoaSize(ob) != 2) {
330: fprintf(stderr,"%s [vlist, body]. The length must be 2. \n",s);
331: printObject(ob,1,stderr);
332: return(0);
333: }
334: ob1 = getoa(ob,0);
335: ob2 = getoa(ob,1);
336: if (ob1.tag != Sarray) {
337: fprintf(stderr,"%s [list vlist, body].\n",s); printObject(ob,1,stderr);
338: return(0);
339: }
340: n = getoaSize(ob1);
341: for (i=0; i<n; i++) {
342: tmp = getoa(ob1,i);
1.4 takayama 343: if (tmp.tag == Sdollar) {
1.5 takayama 344: }else if (ectag(tmp) == CLASSNAME_tree) {
345: }else{
1.4 takayama 346: fprintf(stderr,"%s [list vlist, body]. Element of the vlist must be a string or a tree.\n",s); printObject(ob,1,stderr);
1.1 maekawa 347: return(0);
348: }
349: }
350: return(isRecursivePolynomial2a(ob2,n));
351: }
352:
353:
354: struct object coeffToObject(struct coeff *cp) {
355: struct object rob = NullObject;
356: switch(cp->tag) {
357: case INTEGER:
358: rob = KpoInteger( coeffToInt(cp) );
359: return(rob);
360: break;
361:
362: case MP_INTEGER:
363: rob.tag = SuniversalNumber;
364: rob.lc.universalNumber = newUniversalNumber2((cp->val).bigp);
365: return(rob);
366: break;
367:
368: case POLY_COEFF:
369: rob = KpoPOLY((cp->val).f);
370: return(rob);
371: break;
372:
373: default:
374: return(rob);
375: }
376: }
377:
378:
379: struct object recursivePolyToPoly(struct object rp) {
380: struct object rob = NullObject;
381: POLY f;
382: errorKan1("%s\n","recursivePolyToPoly() has not yet been implemented. Use ascii parsing or sm1 macros to reconstruct a polynomial.");
383:
384: return(rob);
385: }
386:
387:
1.4 takayama 388: struct object KrvtReplace(struct object rp_o,struct object v_o, struct object t_o) {
389: /* rp_o : recursive polynomial.
1.5 takayama 390: v_o : variable name (indeterminate).
1.4 takayama 391: t_o : tree.
392: */
393: struct object rp, vlist, newvlist, newrp;
394: int i,m;
395: /* Check the data types. */
396: if (ectag(rp_o) != CLASSNAME_recursivePolynomial) {
1.5 takayama 397: errorKan1("%s\n","KrvtReplace() type mismatch in the first argument.");
1.4 takayama 398: }
399: if (ectag(v_o) != CLASSNAME_indeterminate) {
1.5 takayama 400: errorKan1("%s\n","KrvtReplace() type mismatch in the second argument.");
1.4 takayama 401: }
402: if (ectag(t_o) != CLASSNAME_tree) {
1.5 takayama 403: errorKan1("%s\n","KrvtReplace() type mismatch in the third argument.");
1.4 takayama 404: }
405:
406: rp = KopRecursivePolynomial(rp_o);
407: vlist = getoa(rp,0);
408: m = getoaSize(vlist);
409: newvlist = newObjectArray(m);
410: for (i=0; i<m; i++) {
1.5 takayama 411: if (KooEqualQ(getoa(vlist,i),KopIndeterminate(v_o))) {
412: /* should be KooEqualQ(getoa(vlist,i),v_o). It's not a bug.
413: Internal expression of vlist is an array of string
414: (not indetermiante). */
415: putoa(newvlist,i,t_o);
416: }else{
417: putoa(newvlist,i,getoa(vlist,i));
418: }
1.4 takayama 419: }
420: newrp = newObjectArray(getoaSize(rp));
421: m = getoaSize(rp);
422: putoa(newrp,0,newvlist);
423: for (i=1; i<m; i++) {
1.5 takayama 424: putoa(newrp,i,getoa(rp,i));
1.4 takayama 425: }
426: return(KpoRecursivePolynomial(newrp));
427: }
1.1 maekawa 428:
429:
1.4 takayama 430: struct object KreplaceRecursivePolynomial(struct object of,struct object rule) {
431: struct object rob,f;
432: int i;
433: int n;
434: struct object trule;
435:
1.1 maekawa 436:
1.4 takayama 437: if (rule.tag != Sarray) {
438: errorKan1("%s\n"," KreplaceRecursivePolynomial(): The second argument must be array.");
439: }
440: n = getoaSize(rule);
441:
442: if (of.tag ==Sclass && ectag(of) == CLASSNAME_recursivePolynomial) {
443: }else{
444: errorKan1("%s\n"," KreplaceRecursivePolynomial(): The first argument must be a recursive polynomial.");
445: }
446: f = of;
1.1 maekawa 447:
1.4 takayama 448: for (i=0; i<n; i++) {
449: trule = getoa(rule,i);
450: if (trule.tag != Sarray) {
451: errorKan1("%s\n"," KreplaceRecursivePolynomial(): The second argument must be of the form [[a b] [c d] ....].");
452: }
453: if (getoaSize(trule) != 2) {
454: errorKan1("%s\n"," KreplaceRecursivePolynomial(): The second argument must be of the form [[a b] [c d] ....].");
455: }
456:
457: if (ectag(getoa(trule,0)) != CLASSNAME_indeterminate) {
458: errorKan1("%s\n"," KreplaceRecursivePolynomial(): The second argument must be of the form [[a b] [c d] ....] where a,b,c,d,... are polynomials.");
459: }
1.5 takayama 460: /* Do not check the second argument. */
461: /*
462: if (getoa(trule,1).tag != Spoly) {
1.4 takayama 463: errorKan1("%s\n"," KreplaceRecursivePolynomial(): The second argument must be of the form [[a b] [c d] ....] where a,b,c,d,... are polynomials.");
1.5 takayama 464: }
465: */
1.4 takayama 466:
467: }
468:
469: rob = f;
470: for (i=0; i<n; i++) {
471: trule = getoa(rule,i);
1.5 takayama 472: rob = KrvtReplace(rob,getoa(trule,0),getoa(trule,1));
1.4 takayama 473: }
474: return(rob);
475: }
1.1 maekawa 476:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>