File: [local] / OpenXM / src / kan96xx / Kan / Kclass / indeterminate.c (download)
Revision 1.8, Thu Jun 16 05:07:23 2005 UTC (19 years, 3 months ago) by takayama
Branch: MAIN
CVS Tags: R_1_3_1-2, RELEASE_1_3_1_13b, RELEASE_1_2_3_12, KNOPPIX_2006, HEAD, DEB_REL_1_2_3-9 Changes since 1.7: +28 -18
lines
The initialization of the variables of the type struct object
are added. It is necessary to initialize the field "attr"
(object attribute) of stuct object. cf. misc-2005/06/gfan/opt.sm1 test2.
|
/* $OpenXM: OpenXM/src/kan96xx/Kan/Kclass/indeterminate.c,v 1.8 2005/06/16 05:07:23 takayama Exp $ */
/* Kclass/indeterminate.c */
/* This file handles indeterminate, recursivePolynomial,
polynomialInOneVariable
*/
#include <stdio.h>
#include "../datatype.h"
#include "../stackm.h"
#include "../extern.h"
#include "../gradedset.h"
#include "../extern2.h"
#include "../kclass.h"
/* Data conversion function : see KclassDataConversion*/
struct object KpoIndeterminate(struct object ob) {
struct object rob = OINIT;
struct object *newobp;
rob.tag = Sclass;
rob.lc.ival = CLASSNAME_indeterminate;
newobp = (struct object *) sGC_malloc(sizeof(struct object));
if (newobp == NULL) errorKan1("%s\n","Kclass/indeterminate.c, no more memory.");
if (ob.tag != Sdollar) {
errorKan1("%s\n","Kclass/indeterminate.c, only String object can be transformed into indeterminate.");
}
*newobp = ob;
rob.rc.voidp = newobp;
return(rob);
}
/* The second constructor. */
struct object KnewIndeterminate(char *s) {
struct object ob = OINIT;
ob = KpoString(s); /* We do not clone s */
return(KpoIndeterminate(ob));
}
/* Printing function : see fprintClass */
void fprintIndeterminate(FILE *fp,struct object op)
{
printObject(KopIndeterminate(op),0,fp);
}
/* Functions for trees are moved to tree.c */
/* ---------------------------------------------------- */
struct object KpoRecursivePolynomial(struct object ob) {
struct object rob = OINIT;
struct object *newobp;
rob.tag = Sclass;
rob.lc.ival = CLASSNAME_recursivePolynomial;
newobp = (struct object *) sGC_malloc(sizeof(struct object));
if (newobp == NULL) errorKan1("%s\n","Kclass/indeterminate.c, no more memory.");
if (ob.tag != Sarray) {
errorKan1("%s\n","Kclass/indeterminate.c, only array object can be transformed into recusivePolynomial.");
}
*newobp = ob;
rob.rc.voidp = newobp;
return(rob);
}
static void printBodyOfRecursivePolynomial(struct object body,
struct object vlist, FILE *fp)
{
int i,j;
int k;
if (ectag(body) != CLASSNAME_polynomialInOneVariable) {
printObject(body,0,fp);
return;
}
body = KopPolynomialInOneVariable(body);
if (body.tag != Sarray) {
errorKan1("%s\n","Kclass/indeterminate.c, format error for recursive polynomial.");
}
if (getoaSize(body) == 0) {
errorKan1("%s\n","printBodyOfRecursivePolynomial: format error for a recursive polynomial.");
}
i = KopInteger(getoa(body,0));
for (j=1; j<getoaSize(body); j = j+2) {
k = KopInteger(getoa(body,j));
if (k != 0) {
if (getoa(vlist,i).tag == Sdollar) {
fprintf(fp,"%s",KopString(getoa(vlist,i)));
}else if (ectag(getoa(vlist,i)) == CLASSNAME_tree) {
fprintClass(fp,getoa(vlist,i));
}else{
errorKan1("%s\n","printBodyOfRecursivePolynomial: format error.");
}
if (k > 1) {
fprintf(fp,"^%d ",k);
}else if (k == 1) {
}else{
fprintf(fp,"^(%d) ",k);
}
fprintf(fp," * ");
}
fprintf(fp,"(");
printBodyOfRecursivePolynomial(getoa(body,j+1),vlist,fp);
fprintf(fp,")");
if (j != getoaSize(body)-2) {
fprintf(fp," + ");
}
}
return;
}
void fprintRecursivePolynomial(FILE *fp,struct object op)
{
/* old code
printObject(KopRecursivePolynomial(op),0,fp); return;
*/
struct object ob = OINIT;
struct object vlist = OINIT;
struct object body = OINIT;
ob = KopRecursivePolynomial(op);
if (ob.tag != Sarray) {
printObject(ob,0,fp); return;
}
if (!isRecursivePolynomial2(op)) {
printObject(KopRecursivePolynomial(op),0,fp); return;
}
vlist = getoa(ob,0);
body = getoa(ob,1);
printBodyOfRecursivePolynomial(body,vlist,fp);
return;
}
/*------------------------------------------*/
struct object KpoPolynomialInOneVariable(struct object ob) {
struct object rob = OINIT;
struct object *newobp;
rob.tag = Sclass;
rob.lc.ival = CLASSNAME_polynomialInOneVariable;
newobp = (struct object *) sGC_malloc(sizeof(struct object));
if (newobp == NULL) errorKan1("%s\n","Kclass/indeterminate.c, no more memory.");
if (ob.tag != Sarray) {
errorKan1("%s\n","Kclass/indeterminate.c, only array object can be transformed into polynomialInOneVariable.");
}
*newobp = ob;
rob.rc.voidp = newobp;
return(rob);
}
void fprintPolynomialInOneVariable(FILE *fp,struct object op)
{
printObject(KopPolynomialInOneVariable(op),0,fp);
}
struct object polyToRecursivePoly(struct object p) {
struct object rob = NullObject;
int vx[N0], vd[N0];
int i,j,k,n,count;
POLY f;
struct object vlist = OINIT;
struct object vlist2 = OINIT;
struct object ob1 = OINIT;
struct object ob2 = OINIT;
struct object ob3 = OINIT;
struct object ob4 = OINIT;
int vn;
if (p.tag != Spoly) return(rob);
f = KopPOLY(p);
if (f == ZERO) {
rob = p; return(rob);
}
/* construct list of variables. */
for (i=0; i<N0; i++) {
vx[i] = vd[i] = 0;
}
n = f->m->ringp->n; count = 0;
for (i=0; i<n; i++) {
if (pDegreeWrtV(f,cxx(1,i,1,f->m->ringp))) {
vx[i] = 1; count++;
}
if (pDegreeWrtV(f,cdd(1,i,1,f->m->ringp))) {
vd[i] = 1; count++;
}
}
vlist = newObjectArray(count); k = 0;
vlist2 = newObjectArray(count); k = 0;
for (i=0; i<n; i++) {
if (vd[i]) {
putoa(vlist,k,KpoPOLY(cdd(1,i,1,f->m->ringp)));
putoa(vlist2,k,KpoString(POLYToString(cdd(1,i,1,f->m->ringp),'*',0)));
k++;
}
}
for (i=0; i<n; i++) {
if (vx[i]) {
putoa(vlist,k,KpoPOLY(cxx(1,i,1,f->m->ringp)));
putoa(vlist2,k,KpoString(POLYToString(cxx(1,i,1,f->m->ringp),'*',0)));
k++;
}
}
/* printObject(vlist,1,stdout); */
if (getoaSize(vlist) == 0) {
vn = -1;
}else{
vn = 0;
}
ob1 = polyToRecursivePoly2(p,vlist,vn);
rob = newObjectArray(2);
putoa(rob,0,vlist2); putoa(rob,1,ob1);
/* format of rob
[ list of variables, poly or universalNumber or yyy to express
a recursive polynomial. ]
format of yyy = CLASSNAME_polynomialInOneVariable
[Sinteger, Sinteger, coeff obj, Sinteger, coeff obj, .....]
name of var, exp, coeff, exp, coeff
This format is checked by isRecursivePolynomial2().
*/
rob = KpoRecursivePolynomial(rob);
if (isRecursivePolynomial2(rob)) {
return(rob);
}else{
errorKan1("%s\n","polyToRecursivePolynomial could not translate this object.");
}
}
static void objectFormatError_ind0(char *s) {
char tmp[1024];
sprintf(tmp,"polyToRecursivePoly2: object format error for the variable %s",s);
errorKan1("%s\n",tmp);
}
struct object polyToRecursivePoly2(struct object p,struct object vlist, int vn) {
struct object rob = NullObject;
POLY f;
POLY vv;
struct object v = OINIT;
struct object c = OINIT;
struct object e = OINIT;
int i;
if (p.tag != Spoly) return(rob);
f = KopPOLY(p);
if (f == ZERO) {
rob = p; return(rob);
}
if (vn < 0 || vn >= getoaSize(vlist)) {
return(coeffToObject(f->coeffp));
}
v = getoa(vlist,vn);
if (v.tag != Spoly) objectFormatError_ind0("v");
vv = KopPOLY(v);
c = parts2(f,vv);
e = getoa(c,0); /* exponents. Array of integer. */
if (e.tag != Sarray) objectFormatError_ind0("e");
c = getoa(c,1); /* coefficients. Array of POLY. */
if (c.tag != Sarray) objectFormatError_ind0("c");
rob = newObjectArray(getoaSize(e)*2+1);
putoa(rob,0,KpoInteger(vn)); /* put the variable number. */
for (i=0; i < getoaSize(e); i++) {
putoa(rob,1+i*2, getoa(e,i));
putoa(rob,1+i*2+1, polyToRecursivePoly2(getoa(c,i),vlist,vn+1));
}
/* printObject(rob,0,stderr); */
return(KpoPolynomialInOneVariable(rob));
}
static int isRecursivePolynomial2a(struct object ob2, int n) {
char *s = "Format error (isRecursivePolynomial2a) : ";
struct object tmp = OINIT;
int i;
if (ectag(ob2) == CLASSNAME_polynomialInOneVariable) {
ob2 = KopPolynomialInOneVariable(ob2);
}else if (ob2.tag == Sarray) {
fprintf(stderr,"isRecursivePolynomial2, argument is an array.\n");
printObject(ob2,0,stderr);
fprintf(stderr,"\n");
return(0); /* Array must be an error, but other objects are OK. */
}else {
return(1);
}
if (ob2.tag != Sarray) {
return(1);
/* coeff can be any. */
}
if (getoaSize(ob2) % 2 == 0) {
fprintf(stderr,"%s list body. The size of body must be odd.\n",s); printObject(ob2,1,stderr);
return(0);
}
tmp = getoa(ob2,0);
if (tmp.tag != Sinteger) {
fprintf(stderr,"%s list body. body[0] must be integer.\n",s); printObject(ob2,1,stderr);
return(0);
}
if (KopInteger(tmp) < 0 || KopInteger(tmp) >= n) {
fprintf(stderr,"%s list body. body[0] must be integer between 0 and the size of vlist -1.\n",s); printObject(ob2,1,stderr);
return(0);
}
for (i=1; i<getoaSize(ob2); i = i+2) {
tmp = getoa(ob2,i);
if (tmp.tag != Sinteger) {
fprintf(stderr,"%s [list vlist, list body]. body[%d] must be integer.\n",s,i);
printObject(ob2,1,stderr);
return(0);
}
}
for (i=2; i<getoaSize(ob2); i = i+2) {
tmp = getoa(ob2,i);
if (ectag(tmp) == CLASSNAME_polynomialInOneVariable) {
if (isRecursivePolynomial2a(tmp,n)) {
}else{
fprintf(stderr,"isRecursivePolynomial2a: entry is not a polynomial in one variable.\n");
printObject(tmp,0,stderr); fprintf(stderr,"\n");
return(0);
}
}
}
return(1);
}
int isRecursivePolynomial2(struct object ob) {
/* This checks only the top level */
char *s = "Format error (isRecursivePolynomial2) : ";
struct object ob1 = OINIT;
struct object ob2 = OINIT;
struct object tmp = OINIT;
int i;
int n;
if (ob.tag != Sclass) return(0);
if (ectag(ob) != CLASSNAME_recursivePolynomial) return(0);
ob = KopRecursivePolynomial(ob);
if (ob.tag != Sarray) {
fprintf(stderr,"%s [vlist, body]\n",s); printObject(ob,1,stderr);
return(0);
}
if (getoaSize(ob) != 2) {
fprintf(stderr,"%s [vlist, body]. The length must be 2. \n",s);
printObject(ob,1,stderr);
return(0);
}
ob1 = getoa(ob,0);
ob2 = getoa(ob,1);
if (ob1.tag != Sarray) {
fprintf(stderr,"%s [list vlist, body].\n",s); printObject(ob,1,stderr);
return(0);
}
n = getoaSize(ob1);
for (i=0; i<n; i++) {
tmp = getoa(ob1,i);
if (tmp.tag == Sdollar) {
}else if (ectag(tmp) == CLASSNAME_tree) {
}else{
fprintf(stderr,"%s [list vlist, body]. Element of the vlist must be a string or a tree.\n",s); printObject(ob,1,stderr);
return(0);
}
}
return(isRecursivePolynomial2a(ob2,n));
}
struct object coeffToObject(struct coeff *cp) {
struct object rob = NullObject;
switch(cp->tag) {
case INTEGER:
rob = KpoInteger( coeffToInt(cp) );
return(rob);
break;
case MP_INTEGER:
rob.tag = SuniversalNumber;
rob.lc.universalNumber = newUniversalNumber2((cp->val).bigp);
return(rob);
break;
case POLY_COEFF:
rob = KpoPOLY((cp->val).f);
return(rob);
break;
default:
return(rob);
}
}
struct object recursivePolyToPoly(struct object rp) {
struct object rob = NullObject;
POLY f;
errorKan1("%s\n","recursivePolyToPoly() has not yet been implemented. Use ascii parsing or sm1 macros to reconstruct a polynomial.");
return(rob);
}
struct object KrvtReplace(struct object rp_o,struct object v_o, struct object t_o) {
/* rp_o : recursive polynomial.
v_o : variable name (indeterminate).
t_o : tree.
*/
struct object rp = OINIT;
struct object vlist = OINIT;
struct object newvlist = OINIT;
struct object newrp = OINIT;
int i,m;
/* Check the data types. */
if (ectag(rp_o) != CLASSNAME_recursivePolynomial) {
errorKan1("%s\n","KrvtReplace() type mismatch in the first argument.");
}
if (ectag(v_o) != CLASSNAME_indeterminate) {
errorKan1("%s\n","KrvtReplace() type mismatch in the second argument.");
}
if (ectag(t_o) != CLASSNAME_tree) {
errorKan1("%s\n","KrvtReplace() type mismatch in the third argument.");
}
rp = KopRecursivePolynomial(rp_o);
vlist = getoa(rp,0);
m = getoaSize(vlist);
newvlist = newObjectArray(m);
for (i=0; i<m; i++) {
if (KooEqualQ(getoa(vlist,i),KopIndeterminate(v_o))) {
/* should be KooEqualQ(getoa(vlist,i),v_o). It's not a bug.
Internal expression of vlist is an array of string
(not indetermiante). */
putoa(newvlist,i,t_o);
}else{
putoa(newvlist,i,getoa(vlist,i));
}
}
newrp = newObjectArray(getoaSize(rp));
m = getoaSize(rp);
putoa(newrp,0,newvlist);
for (i=1; i<m; i++) {
putoa(newrp,i,getoa(rp,i));
}
return(KpoRecursivePolynomial(newrp));
}
struct object KreplaceRecursivePolynomial(struct object of,struct object rule) {
struct object rob = OINIT;
struct object f = OINIT;
int i;
int n;
struct object trule = OINIT;
if (rule.tag != Sarray) {
errorKan1("%s\n"," KreplaceRecursivePolynomial(): The second argument must be array.");
}
n = getoaSize(rule);
if (of.tag ==Sclass && ectag(of) == CLASSNAME_recursivePolynomial) {
}else{
errorKan1("%s\n"," KreplaceRecursivePolynomial(): The first argument must be a recursive polynomial.");
}
f = of;
for (i=0; i<n; i++) {
trule = getoa(rule,i);
if (trule.tag != Sarray) {
errorKan1("%s\n"," KreplaceRecursivePolynomial(): The second argument must be of the form [[a b] [c d] ....].");
}
if (getoaSize(trule) != 2) {
errorKan1("%s\n"," KreplaceRecursivePolynomial(): The second argument must be of the form [[a b] [c d] ....].");
}
if (ectag(getoa(trule,0)) != CLASSNAME_indeterminate) {
errorKan1("%s\n"," KreplaceRecursivePolynomial(): The second argument must be of the form [[a b] [c d] ....] where a,b,c,d,... are polynomials.");
}
/* Do not check the second argument. */
/*
if (getoa(trule,1).tag != Spoly) {
errorKan1("%s\n"," KreplaceRecursivePolynomial(): The second argument must be of the form [[a b] [c d] ....] where a,b,c,d,... are polynomials.");
}
*/
}
rob = f;
for (i=0; i<n; i++) {
trule = getoa(rule,i);
rob = KrvtReplace(rob,getoa(trule,0),getoa(trule,1));
}
return(rob);
}