[BACK]Return to puref.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2018 / parse

Annotation of OpenXM_contrib2/asir2018/parse/puref.c, Revision 1.1

1.1     ! noro        1: /*
        !             2:  * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
        !             6:  * non-exclusive and royalty-free license to use, copy, modify and
        !             7:  * redistribute, solely for non-commercial and non-profit purposes, the
        !             8:  * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
        !             9:  * conditions of this Agreement. For the avoidance of doubt, you acquire
        !            10:  * only a limited right to use the SOFTWARE hereunder, and FLL or any
        !            11:  * third party developer retains all rights, including but not limited to
        !            12:  * copyrights, in and to the SOFTWARE.
        !            13:  *
        !            14:  * (1) FLL does not grant you a license in any way for commercial
        !            15:  * purposes. You may use the SOFTWARE only for non-commercial and
        !            16:  * non-profit purposes only, such as academic, research and internal
        !            17:  * business use.
        !            18:  * (2) The SOFTWARE is protected by the Copyright Law of Japan and
        !            19:  * international copyright treaties. If you make copies of the SOFTWARE,
        !            20:  * with or without modification, as permitted hereunder, you shall affix
        !            21:  * to all such copies of the SOFTWARE the above copyright notice.
        !            22:  * (3) An explicit reference to this SOFTWARE and its copyright owner
        !            23:  * shall be made on your publication or presentation in any form of the
        !            24:  * results obtained by use of the SOFTWARE.
        !            25:  * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
        !            26:  * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
        !            27:  * for such modification or the source code of the modified part of the
        !            28:  * SOFTWARE.
        !            29:  *
        !            30:  * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
        !            31:  * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
        !            32:  * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
        !            33:  * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
        !            34:  * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
        !            35:  * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
        !            36:  * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
        !            37:  * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
        !            38:  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
        !            39:  * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
        !            40:  * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
        !            41:  * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
        !            42:  * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
        !            43:  * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
        !            44:  * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
        !            45:  * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
        !            46:  * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
        !            47:  *
        !            48:  * $OpenXM$
        !            49: */
        !            50: #include "ca.h"
        !            51: #include "parse.h"
        !            52:
        !            53: void instoobj(PFINS ins,Obj *rp);
        !            54:
        !            55: NODE pflist;
        !            56:
        !            57: void searchpf(char *name,FUNC *fp)
        !            58: {
        !            59:   NODE node;
        !            60:   PF pf;
        !            61:   FUNC t;
        !            62:
        !            63:   for ( node = pflist; node; node = NEXT(node) )
        !            64:     if ( !strcmp(name,((PF)node->body)->name) ) {
        !            65:       pf = (PF)node->body;
        !            66:       *fp = t = (FUNC)MALLOC(sizeof(struct oFUNC));
        !            67:       t->name = name; t->id = A_PURE; t->argc = pf->argc;
        !            68:       t->f.puref = pf; t->fullname = name;
        !            69:       return;
        !            70:     }
        !            71:   *fp = 0;
        !            72: }
        !            73:
        !            74: void searchc(char *name,FUNC *fp)
        !            75: {
        !            76:   NODE node;
        !            77:   PF pf;
        !            78:   FUNC t;
        !            79:
        !            80:   for ( node = pflist; node; node = NEXT(node) )
        !            81:     if ( !strcmp(name,((PF)node->body)->name)
        !            82:       && !((PF)node->body)->argc ) {
        !            83:       pf = (PF)node->body;
        !            84:       *fp = t = (FUNC)MALLOC(sizeof(struct oFUNC));
        !            85:       t->name = name; t->id = A_PURE; t->argc = pf->argc;
        !            86:       t->f.puref = pf; t->fullname = name;
        !            87:       return;
        !            88:     }
        !            89:   *fp = 0;
        !            90: }
        !            91:
        !            92: void mkpf(char *name,Obj body,int argc,V *args,
        !            93:   int (*parif)(),double (*libmf)(), int (*simp)(),PF *pfp)
        !            94: {
        !            95:   PF pf;
        !            96:   NODE node;
        !            97:
        !            98:   NEWPF(pf); pf->name = name; pf->body = body;
        !            99:   pf->argc = argc; pf->args = args; pf->pari = parif; pf->simplify = simp;
        !           100:   pf->libm = libmf;
        !           101:   for ( node = pflist; node; node = NEXT(node) )
        !           102:     if ( !strcmp(((PF)BDY(node))->name,name) )
        !           103:       break;
        !           104:   if ( !node ) {
        !           105:     NEWNODE(node); NEXT(node) = pflist; pflist = node;
        !           106: /*    fprintf(stderr,"%s() defined.\n",name); */
        !           107:   } else
        !           108:     fprintf(stderr,"%s() redefined.\n",name);
        !           109:   BDY(node) = (pointer)pf; *pfp = pf;
        !           110: }
        !           111:
        !           112: /*
        !           113:    create an instance of a pure function. args are given
        !           114:    as an array of V. So we have to create a P object for
        !           115:    each arg.
        !           116:  */
        !           117:
        !           118: void mkpfins(PF pf,V *args,V *vp)
        !           119: {
        !           120:   V v;
        !           121:   PFINS ins;
        !           122:   PFAD ad;
        !           123:   int i;
        !           124:   P t;
        !           125:
        !           126:   NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;
        !           127:   ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));
        !           128:   bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));
        !           129:   ins->pf = pf;
        !           130:   v->priv = (pointer)ins;
        !           131:   for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {
        !           132:     ad[i].d = 0; MKV(args[i],t); ad[i].arg = (Obj)t;
        !           133:   }
        !           134:   appendpfins(v,vp);
        !           135: }
        !           136:
        !           137: /* the same as above. Argements are given as an array of Obj */
        !           138:
        !           139: void _mkpfins(PF pf,Obj *args,V *vp)
        !           140: {
        !           141:   V v;
        !           142:   PFINS ins;
        !           143:   PFAD ad;
        !           144:   int i;
        !           145:
        !           146:   NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;
        !           147:   ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));
        !           148:   bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));
        !           149:   ins->pf = pf;
        !           150:   v->priv = (pointer)ins;
        !           151:   for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {
        !           152:     ad[i].d = 0; ad[i].arg = args[i];
        !           153:   }
        !           154:   appendpfins(v,vp);
        !           155: }
        !           156:
        !           157: /* the same as above. darray is also given */
        !           158:
        !           159: void _mkpfins_with_darray(PF pf,Obj *args,int *darray,V *vp)
        !           160: {
        !           161:   V v;
        !           162:   PFINS ins;
        !           163:   PFAD ad;
        !           164:   int i;
        !           165:
        !           166:   NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;
        !           167:   ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));
        !           168:   bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));
        !           169:   ins->pf = pf;
        !           170:   v->priv = (pointer)ins;
        !           171:   for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {
        !           172:     ad[i].d = darray[i]; ad[i].arg = args[i];
        !           173:   }
        !           174:   appendpfins(v,vp);
        !           175: }
        !           176:
        !           177: void appendpfins(V v,V *vp)
        !           178: {
        !           179:   PF fdef;
        !           180:   PFAD ad,tad;
        !           181:   NODE node;
        !           182:   int i;
        !           183:
        !           184:   fdef = ((PFINS)v->priv)->pf; ad = ((PFINS)v->priv)->ad;
        !           185:   for ( node = fdef->ins; node; node = NEXT(node) ) {
        !           186:     for ( i = 0, tad = ((PFINS)((V)node->body)->priv)->ad;
        !           187:       i < fdef->argc; i++ )
        !           188:       if ( (ad[i].d != tad[i].d) || !equalr(CO,ad[i].arg,tad[i].arg) )
        !           189:         break;
        !           190:     if ( i == fdef->argc ) {
        !           191:       *vp = (V)node->body;
        !           192:       return;
        !           193:     }
        !           194:   }
        !           195:   NEWNODE(node); node->body = (pointer)v; NEXT(node) = fdef->ins;
        !           196:   fdef->ins = node; appendvar(CO,v); *vp = v;
        !           197: }
        !           198:
        !           199: void duppfins(V v,V *vp)
        !           200: {
        !           201:   V tv;
        !           202:   PFINS tins;
        !           203:   int size;
        !           204:
        !           205:   NEWV(tv); tv->name = v->name; tv->attr = v->attr;
        !           206:   size = sizeof(PF)+((PFINS)v->priv)->pf->argc*sizeof(struct oPFAD);
        !           207:   tins = (PFINS)MALLOC(size); bcopy((char *)v->priv,(char *)tins,size);
        !           208:   tv->priv = (pointer)tins;
        !           209:   *vp = tv;
        !           210: }
        !           211:
        !           212: void derivvar(VL vl,V pf,V v,Obj *a)
        !           213: {
        !           214:   Obj t,s,u,w,u1;
        !           215:   P p;
        !           216:   V tv,sv;
        !           217:   PF fdef;
        !           218:   PFAD ad;
        !           219:   int i,j;
        !           220:
        !           221:   fdef = ((PFINS)pf->priv)->pf; ad = ((PFINS)pf->priv)->ad;
        !           222:   if ( fdef->deriv ) {
        !           223:     for ( t = 0, i = 0; i < fdef->argc; i++ ) {
        !           224:       derivr(vl,ad[i].arg,v,&s);
        !           225:       for ( j = 0, u = fdef->deriv[i]; j < fdef->argc; j++ ) {
        !           226:         substr(vl,0,u,fdef->args[j],ad[j].arg,&u1); u = u1;
        !           227:       }
        !           228:       mulr(vl,s,u,&w); addr(vl,t,w,&s); t = s;
        !           229:     }
        !           230:     *a = t;
        !           231:   } else {
        !           232:     for ( t = 0, i = 0; i < fdef->argc; i++ ) {
        !           233:       derivr(vl,ad[i].arg,v,&s);
        !           234:       duppfins(pf,&tv); (((PFINS)tv->priv)->ad)[i].d++;
        !           235:       appendpfins(tv,&sv);
        !           236:       MKV(sv,p); mulr(vl,s,(Obj)p,&w); addr(vl,t,w,&s); t = s;
        !           237:     }
        !           238:     *a = t;
        !           239:   }
        !           240: }
        !           241:
        !           242: void derivr(VL vl,Obj a,V v,Obj *b)
        !           243: {
        !           244:   VL tvl,svl;
        !           245:   Obj r,s,t,u,nm,dn,dnm,ddn,m;
        !           246:
        !           247:   if ( !a )
        !           248:     *b = 0;
        !           249:   else
        !           250:     switch ( OID(a) ) {
        !           251:       case O_N:
        !           252:         *b = 0; break;
        !           253:       case O_P:
        !           254:         clctvr(vl,a,&tvl);
        !           255:         for ( dnm = 0, svl = tvl; svl; svl = NEXT(svl) ) {
        !           256:           if ( svl->v == v ) {
        !           257:             pderivr(vl,a,v,&s); addr(vl,s,dnm,&u); dnm = u;
        !           258:           } else if ( (vid)svl->v->attr == V_PF ) {
        !           259:             pderivr(vl,a,svl->v,&s); derivvar(vl,svl->v,v,&r);
        !           260:             mulr(vl,s,r,&u); addr(vl,u,dnm,&s); dnm = s;
        !           261:           }
        !           262:         }
        !           263:         *b = (Obj)dnm; break;
        !           264:       case O_R:
        !           265:         clctvr(vl,a,&tvl);
        !           266:         nm = (Obj)NM((R)a); dn = (Obj)DN((R)a);
        !           267:         for ( dnm = ddn = 0, svl = tvl; svl; svl = NEXT(svl) ) {
        !           268:           if ( svl->v == v ) {
        !           269:             pderivr(vl,nm,v,&s); addr(vl,s,dnm,&u); dnm = u;
        !           270:             pderivr(vl,dn,v,&s); addr(vl,s,ddn,&u); ddn = u;
        !           271:           } else if ( (vid)svl->v->attr == V_PF ) {
        !           272:             pderivr(vl,nm,svl->v,&s); derivvar(vl,svl->v,v,&r);
        !           273:             mulr(vl,s,r,&u); addr(vl,u,dnm,&s); dnm = s;
        !           274:             pderivr(vl,dn,svl->v,&s); derivvar(vl,svl->v,v,&r);
        !           275:             mulr(vl,s,r,&u); addr(vl,u,ddn,&s); ddn = s;
        !           276:           }
        !           277:         }
        !           278:         mulr(vl,dnm,dn,&t); mulr(vl,ddn,nm,&s);
        !           279:         subr(vl,t,s,&u); reductr(vl,u,&t);
        !           280:         if ( !t )
        !           281:           *b = 0;
        !           282:         else {
        !           283:           mulp(vl,(P)dn,(P)dn,(P *)&m); divr(vl,t,m,b);
        !           284:         }
        !           285:         break;
        !           286:   }
        !           287: }
        !           288:
        !           289: void simple_derivr(VL vl,Obj a,V v,Obj *b)
        !           290: {
        !           291:   Obj r,s,t,u,nm,dn;
        !           292:
        !           293:   if ( !a || NUM(a) )
        !           294:     *b = 0;
        !           295:   else
        !           296:     switch ( OID(a) ) {
        !           297:       case O_P:
        !           298:         pderivr(vl,a,v,b); break;
        !           299:       case O_R:
        !           300:         nm = (Obj)NM((R)a); dn = (Obj)DN((R)a);
        !           301:         /* (nm/dn)' = nm'/dn - dn'/dn*nm/dn */
        !           302:         pderivr(vl,nm,v,&s); divr(vl,s,dn,&u); reductr(vl,u,&t);
        !           303:         pderivr(vl,dn,v,&s); divr(vl,s,dn,&u); reductr(vl,u,&s); mulr(vl,s,a,&u);
        !           304:         subr(vl,t,u,&s); reductr(vl,s,b);
        !           305:         break;
        !           306:       default:
        !           307:         error("simple_derivr : invalid argument");
        !           308:   }
        !           309: }
        !           310:
        !           311: int obj_is_dependent(Obj a,V v)
        !           312: {
        !           313:   if ( !a || OID(a) <= O_N ) return 0;
        !           314:   else if ( OID(a) == O_P ) return poly_is_dependent((P)a,v);
        !           315:   else if ( OID(a) == O_R ) return poly_is_dependent(NM((R)a),v)
        !           316:     || poly_is_dependent(DN((R)a),v);
        !           317:   else
        !           318:     error("obj_is_dependent : not implemented");
        !           319: }
        !           320:
        !           321: int poly_is_dependent(P p,V v)
        !           322: {
        !           323:   DCP dc;
        !           324:
        !           325:   if ( !p || OID(p) <= O_N ) return 0;
        !           326:   else if ( v == VR(p) ) return 1;
        !           327:   else {
        !           328:     for ( dc = DC(p); dc; dc = NEXT(dc) )
        !           329:       if ( poly_is_dependent(COEF(dc),v) ) return 1;
        !           330:     return 0;
        !           331:   }
        !           332: }
        !           333:
        !           334: void gen_pwrr(VL vl,Obj a,Obj d,Obj *r)
        !           335: {
        !           336:   if ( INT(d) )
        !           337:     pwrr(vl,a,d,r);
        !           338:   else
        !           339:     mkpow(vl,a,d,r);
        !           340: }
        !           341:
        !           342: void substr(VL vl,int partial,Obj a,V v,Obj b,Obj *c)
        !           343: {
        !           344:   Obj nm,dn,t;
        !           345:
        !           346:   if ( !a )
        !           347:     *c = 0;
        !           348:   else {
        !           349:     switch ( OID(a) ) {
        !           350:       case O_N:
        !           351:         *c = a; break;
        !           352:       case O_P:
        !           353:         substpr(vl,partial,a,v,b,c); break;
        !           354:       case O_R:
        !           355:         substpr(vl,partial,(Obj)NM((R)a),v,b,&nm);
        !           356:         substpr(vl,partial,(Obj)DN((R)a),v,b,&dn);
        !           357:         divr(vl,nm,dn,&t); reductr(vl,t,c);
        !           358:         break;
        !           359:       default:
        !           360:         *c = 0; break;
        !           361:     }
        !           362:   }
        !           363: }
        !           364:
        !           365: void substpr(VL vl,int partial,Obj p,V v0,Obj p0,Obj *pr)
        !           366: {
        !           367:   P x;
        !           368:   Obj t,m,c,s,a;
        !           369:   DCP dc;
        !           370:   Z d;
        !           371:   V v;
        !           372:   PF pf;
        !           373:   PFAD ad,tad;
        !           374:   PFINS tins;
        !           375:   int i;
        !           376:
        !           377:   if ( !p )
        !           378:     *pr = 0;
        !           379:   else if ( NUM(p) )
        !           380:     *pr = (Obj)p;
        !           381:   else if ( (v = VR((P)p)) != v0 ) {
        !           382:     if ( !partial && ((vid)v->attr == V_PF) ) {
        !           383:       ad = ((PFINS)v->priv)->ad; pf = ((PFINS)v->priv)->pf;
        !           384:       tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
        !           385:       tins->pf = pf;
        !           386:       for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {
        !           387:         tad[i].d = ad[i].d;
        !           388:         substr(vl,partial,ad[i].arg,v0,p0,&tad[i].arg);
        !           389:       }
        !           390:       simplify_ins(tins,(Obj *)&x);
        !           391:     } else
        !           392:       MKV(VR((P)p),x);
        !           393:     for ( c = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {
        !           394:       substpr(vl,partial,(Obj)COEF(dc),v0,p0,&t);
        !           395:       if ( DEG(dc) ) {
        !           396:         gen_pwrr(vl,(Obj)x,(Obj)DEG(dc),&s);
        !           397:         mulr(vl,s,t,&m);
        !           398:         addr(vl,m,c,&a); c = a;
        !           399:       } else {
        !           400:         addr(vl,t,c,&a); c = a;
        !           401:       }
        !           402:     }
        !           403:     *pr = c;
        !           404:   } else {
        !           405:     dc = DC((P)p);
        !           406:     if ( !partial )
        !           407:       substpr(vl,partial,(Obj)COEF(dc),v0,p0,&c);
        !           408:     else
        !           409:       c = (Obj)COEF(dc);
        !           410:     for ( d = DEG(dc), dc = NEXT(dc); dc; d = DEG(dc), dc = NEXT(dc) ) {
        !           411:         subz(d,DEG(dc),(Z *)&t);
        !           412:         gen_pwrr(vl,p0,t,&s); mulr(vl,s,c,&m);
        !           413:         if ( !partial )
        !           414:           substpr(vl,partial,(Obj)COEF(dc),v0,p0,&t);
        !           415:         else
        !           416:           t = (Obj)COEF(dc);
        !           417:         addr(vl,m,t,&c);
        !           418:     }
        !           419:     if ( d ) {
        !           420:       gen_pwrr(vl,p0,(Obj)d,&t);
        !           421:       mulr(vl,t,c,&m);
        !           422:       c = m;
        !           423:     }
        !           424:     *pr = c;
        !           425:   }
        !           426: }
        !           427:
        !           428: void evalr(VL vl,Obj a,int prec,Obj *c)
        !           429: {
        !           430:   Obj nm,dn;
        !           431:
        !           432:   if ( !a )
        !           433:     *c = 0;
        !           434:   else {
        !           435:     switch ( OID(a) ) {
        !           436:       case O_N:
        !           437:         *c = a; break;
        !           438:       case O_P:
        !           439:         evalp(vl,(P)a,prec,(P *)c); break;
        !           440:       case O_R:
        !           441:         evalp(vl,NM((R)a),prec,(P *)&nm); evalp(vl,DN((R)a),prec,(P *)&dn);
        !           442:         divr(vl,nm,dn,c);
        !           443:         break;
        !           444:       default:
        !           445:         error("evalr : not implemented"); break;
        !           446:     }
        !           447:   }
        !           448: }
        !           449:
        !           450: void evalp(VL vl,P p,int prec,P *pr)
        !           451: {
        !           452:   P t;
        !           453:   DCP dc,dcr0,dcr;
        !           454:   Obj u;
        !           455:
        !           456:   if ( !p || NUM(p) )
        !           457:     *pr = p;
        !           458:   else {
        !           459:     for ( dcr0 = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {
        !           460:       evalp(vl,COEF(dc),prec,&t);
        !           461:       if ( t ) {
        !           462:         NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = t;
        !           463:       }
        !           464:     }
        !           465:     if ( !dcr0 ) {
        !           466:       *pr = 0; return;
        !           467:     } else {
        !           468:       NEXT(dcr) = 0; MKP(VR(p),dcr0,t);
        !           469:     }
        !           470:     if ( NUM(t) || (VR(t) != VR(p)) || ((vid)VR(p)->attr != V_PF) ) {
        !           471:       *pr = t; return;
        !           472:     } else {
        !           473:       evalv(vl,VR(p),prec,&u); substr(vl,1,(Obj)t,VR(p),u,(Obj *)pr);
        !           474:     }
        !           475:   }
        !           476: }
        !           477:
        !           478: void evalv(VL vl,V v,int prec,Obj *rp)
        !           479: {
        !           480:   PFINS ins,tins;
        !           481:   PFAD ad,tad;
        !           482:   PF pf;
        !           483:   P t;
        !           484:   int i;
        !           485:
        !           486:   if ( (vid)v->attr != V_PF ) {
        !           487:     MKV(v,t); *rp = (Obj)t;
        !           488:   } else {
        !           489:     ins = (PFINS)v->priv; ad = ins->ad; pf = ins->pf;
        !           490:     tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
        !           491:     tins->pf = pf;
        !           492:     for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {
        !           493:       tad[i].d = ad[i].d; evalr(vl,ad[i].arg,prec,&tad[i].arg);
        !           494:     }
        !           495:     evalins(tins,prec,rp);
        !           496:   }
        !           497: }
        !           498:
        !           499: void evalins(PFINS ins,int prec,Obj *rp)
        !           500: {
        !           501:   PF pf;
        !           502:   PFINS tins;
        !           503:   PFAD ad,tad;
        !           504:   int i;
        !           505:   Z q;
        !           506:   V v;
        !           507:   P x;
        !           508:   NODE n0,n;
        !           509:
        !           510:   pf = ins->pf; ad = ins->ad;
        !           511:   tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
        !           512:   tins->pf = pf; tad = tins->ad;
        !           513:   for ( i = 0; i < pf->argc; i++ ) {
        !           514:     tad[i].d = ad[i].d; evalr(CO,ad[i].arg,prec,&tad[i].arg);
        !           515:    }
        !           516:   for ( i = 0; i < pf->argc; i++ )
        !           517:     if ( tad[i].d || (tad[i].arg && !NUM(tad[i].arg)) ) break;
        !           518:   if ( (i != pf->argc) || !pf->pari ) {
        !           519:     instoobj(tins,rp);
        !           520:   } else {
        !           521:     for ( n0 = 0, i = 0; i < pf->argc; i++ ) {
        !           522:       NEXTNODE(n0,n); BDY(n) = (pointer)tad[i].arg;
        !           523:     }
        !           524:     if ( prec ) {
        !           525:       NEXTNODE(n0,n); STOQ(prec,q); BDY(n) = (pointer)q;
        !           526:     }
        !           527:     if ( n0 )
        !           528:       NEXT(n) = 0;
        !           529:     (*pf->pari)(n0,rp);
        !           530:   }
        !           531: }
        !           532:
        !           533: void devalr(VL vl,Obj a,Obj *c)
        !           534: {
        !           535:   Obj nm,dn;
        !           536:   double d;
        !           537:   Real r,re,im;
        !           538:   C z;
        !           539:   int nid;
        !           540:
        !           541:   if ( !a )
        !           542:     *c = 0;
        !           543:   else {
        !           544:     switch ( OID(a) ) {
        !           545:       case O_N:
        !           546:         nid = NID((Num)a);
        !           547:         if ( nid == N_C ) {
        !           548:           d = ToReal(((C)a)->r); MKReal(d,re);
        !           549:           d = ToReal(((C)a)->i); MKReal(d,im);
        !           550:           reimtocplx((Num)re,(Num)im,(Num *)&z);
        !           551:           *c = (Obj)z;
        !           552:         } else if ( nid == N_Q || nid == N_R || nid == N_B ) {
        !           553:           d = ToReal(a);
        !           554:           MKReal(d,r);
        !           555:           *c = (Obj)r;
        !           556:         } else
        !           557:           error("devalr : unsupported");
        !           558:         break;
        !           559:       case O_P:
        !           560:         devalp(vl,(P)a,(P *)c); break;
        !           561:       case O_R:
        !           562:         devalp(vl,NM((R)a),(P *)&nm);
        !           563:         devalp(vl,DN((R)a),(P *)&dn);
        !           564:         divr(vl,nm,dn,c);
        !           565:         break;
        !           566:       default:
        !           567:         error("devalr : not implemented"); break;
        !           568:     }
        !           569:   }
        !           570: }
        !           571:
        !           572: void devalp(VL vl,P p,P *pr)
        !           573: {
        !           574:   P t;
        !           575:   DCP dc,dcr0,dcr;
        !           576:   Obj u,s;
        !           577:   double d;
        !           578:   Real r;
        !           579:
        !           580:   if ( !p || NUM(p) ) {
        !           581:     d = ToReal(p);
        !           582:     MKReal(d,r);
        !           583:     *pr = (P)r;
        !           584:   } else {
        !           585:     for ( dcr0 = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {
        !           586:       devalp(vl,COEF(dc),&t);
        !           587:       if ( t ) {
        !           588:         NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = t;
        !           589:       }
        !           590:     }
        !           591:     if ( !dcr0 )
        !           592:       *pr = 0;
        !           593:     else {
        !           594:       NEXT(dcr) = 0; MKP(VR(p),dcr0,t);
        !           595:       if ( NUM(t) ) {
        !           596:         d = ToReal((Num)t);
        !           597:         MKReal(d,r);
        !           598:         *pr = (P)r;
        !           599:       } else if ( (VR(t) != VR(p)) || (VR(p)->attr != (pointer)V_PF) )
        !           600:         *pr = t;
        !           601:       else {
        !           602:         devalv(vl,VR(p),&u);
        !           603:         substr(vl,1,(Obj)t,VR(p),u,&s);
        !           604:         if ( s && NUM(s) ) {
        !           605:           d = ToReal((Num)s);
        !           606:           MKReal(d,r);
        !           607:           *pr = (P)r;
        !           608:         } else
        !           609:           *pr = (P)s;
        !           610:       }
        !           611:     }
        !           612:   }
        !           613: }
        !           614:
        !           615: void devalv(VL vl,V v,Obj *rp)
        !           616: {
        !           617:   PFINS ins,tins;
        !           618:   PFAD ad,tad;
        !           619:   PF pf;
        !           620:   P t;
        !           621:   int i;
        !           622:
        !           623:   if ( (vid)v->attr != V_PF ) {
        !           624:     MKV(v,t); *rp = (Obj)t;
        !           625:   } else {
        !           626:     ins = (PFINS)v->priv; ad = ins->ad; pf = ins->pf;
        !           627:     tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
        !           628:     tins->pf = pf;
        !           629:     for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {
        !           630:       tad[i].d = ad[i].d; devalr(vl,ad[i].arg,&tad[i].arg);
        !           631:     }
        !           632:     devalins(tins,rp);
        !           633:   }
        !           634: }
        !           635:
        !           636: void devalins(PFINS ins,Obj *rp)
        !           637: {
        !           638:   PFINS tins;
        !           639:   PF pf;
        !           640:   PFAD ad,tad;
        !           641:   int i;
        !           642:   Real r;
        !           643:   double d;
        !           644:   V v;
        !           645:   P x;
        !           646:
        !           647:   pf = ins->pf; ad = ins->ad;
        !           648:   tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
        !           649:   tins->pf = pf; tad = tins->ad;
        !           650:   for ( i = 0; i < pf->argc; i++ ) {
        !           651:     tad[i].d = ad[i].d; devalr(CO,ad[i].arg,&tad[i].arg);
        !           652:    }
        !           653:   for ( i = 0; i < pf->argc; i++ )
        !           654:     if ( tad[i].d || (tad[i].arg && !NUM(tad[i].arg)) ) break;
        !           655:   if ( (i != pf->argc) || !pf->libm ) {
        !           656:     instoobj(tins,rp);
        !           657:   } else {
        !           658:     for ( i = 0; i < pf->argc; i++ )
        !           659:       if ( tad[i].arg && NID((Num)tad[i].arg) == N_C )
        !           660:         error("devalins : not supported");
        !           661:     switch ( pf->argc ) {
        !           662:       case 0:
        !           663:         d = (*pf->libm)(); break;
        !           664:       case 1:
        !           665:         d = (*pf->libm)(ToReal(tad[0].arg)); break;
        !           666:       case 2:
        !           667:         d = (*pf->libm)(ToReal(tad[0].arg),ToReal(tad[1].arg)); break;
        !           668:       case 3:
        !           669:         d = (*pf->libm)(ToReal(tad[0].arg),ToReal(tad[1].arg),
        !           670:           ToReal(tad[2].arg)); break;
        !           671:       case 4:
        !           672:         d = (*pf->libm)(ToReal(tad[0].arg),ToReal(tad[1].arg),
        !           673:           ToReal(tad[2].arg),ToReal(tad[3].arg)); break;
        !           674:       default:
        !           675:         error("devalins : not supported");
        !           676:     }
        !           677:     MKReal(d,r); *rp = (Obj)r;
        !           678:   }
        !           679: }
        !           680:
        !           681: extern int evalef,bigfloat;
        !           682:
        !           683: void simplify_elemfunc_ins(PFINS ins,Obj *rp)
        !           684: {
        !           685:   if ( evalef ) {
        !           686:     if ( bigfloat ) evalins(ins,0,rp);
        !           687:     else devalins(ins,rp);
        !           688:   } else instoobj(ins,rp);
        !           689: }
        !           690:
        !           691: void simplify_factorial_ins(PFINS ins,Obj *rp)
        !           692: {
        !           693:   PFAD ad;
        !           694:   Obj a;
        !           695:   Z q;
        !           696:
        !           697:   ad = ins->ad;
        !           698:   a = ad[0].arg;
        !           699:   if ( !ad[0].d && INT(a) && smallz((Z)a) ) {
        !           700:     factorialz(QTOS((Z)a),&q);
        !           701:     *rp = (Obj)q;
        !           702:   } else simplify_elemfunc_ins(ins,rp);
        !           703: }
        !           704:
        !           705: void simplify_abs_ins(PFINS ins,Obj *rp)
        !           706: {
        !           707:   PFAD ad;
        !           708:   Obj a;
        !           709:   Q q;
        !           710:   double t;
        !           711:   Real r;
        !           712:   struct oNODE arg0;
        !           713:
        !           714:   ad = ins->ad;
        !           715:   a = ad[0].arg;
        !           716:   if ( !ad[0].d && NUM(a) && (!a || RATN(a)) ) {
        !           717:     if ( !a || sgnq((Q)a) > 0 ) *rp = (Obj)a;
        !           718:     else {
        !           719:       chsgnq((Q)a,&q); *rp = (Obj)q;
        !           720:     }
        !           721:   } else if ( !ad[0].d && REAL(a) ) {
        !           722:     t = fabs(((Real)a)->body);
        !           723:     MKReal(t,r); *rp = (Obj)r;
        !           724:   } else if ( !ad[0].d && BIGFLOAT(a) ) {
        !           725:     arg0.body = (pointer)a; arg0.next = 0;
        !           726:     mp_abs(&arg0,(Num *)rp);
        !           727:   } else simplify_elemfunc_ins(ins,rp);
        !           728: }
        !           729:
        !           730: void simplify_ins(PFINS ins,Obj *rp)
        !           731: {
        !           732:   V v;
        !           733:   P t;
        !           734:
        !           735:   if ( ins->pf->simplify )
        !           736:     (*ins->pf->simplify)(ins,rp);
        !           737:   else {
        !           738:     instoobj(ins,rp);
        !           739:   }
        !           740: }
        !           741:
        !           742: void instoobj(PFINS ins,Obj *rp)
        !           743: {
        !           744:   V v,newv;
        !           745:   P t;
        !           746:
        !           747:   NEWV(v); NAME(v) = 0;
        !           748:   v->attr = (pointer)V_PF; v->priv = (pointer)ins;
        !           749:   appendpfins(v,&newv);
        !           750:   MKV(newv,t);
        !           751:   *rp = (Obj)t;
        !           752: }
        !           753:
        !           754: void substfr(VL vl,Obj a,PF u,PF f,Obj *c)
        !           755: {
        !           756:   Obj nm,dn;
        !           757:
        !           758:   if ( !a )
        !           759:     *c = 0;
        !           760:   else {
        !           761:     switch ( OID(a) ) {
        !           762:       case O_N:
        !           763:         *c = a; break;
        !           764:       case O_P:
        !           765:         substfp(vl,a,u,f,c); break;
        !           766:       case O_R:
        !           767:         substfp(vl,(Obj)NM((R)a),u,f,&nm); substfp(vl,(Obj)DN((R)a),u,f,&dn);
        !           768:         divr(vl,nm,dn,c);
        !           769:         break;
        !           770:       default:
        !           771:         error("substfr : not implemented"); break;
        !           772:     }
        !           773:   }
        !           774: }
        !           775:
        !           776: void substfp(VL vl,Obj p,PF u,PF f,Obj *pr)
        !           777: {
        !           778:   V v;
        !           779:   DCP dc;
        !           780:   Obj a,c,m,s,t,p0;
        !           781:   Z d;
        !           782:   P x;
        !           783:
        !           784:   if ( !p )
        !           785:     *pr = 0;
        !           786:   else if ( NUM(p) )
        !           787:     *pr = (Obj)p;
        !           788:   else {
        !           789:     v = VR((P)p); dc = DC((P)p);
        !           790:     if ( (long)v->attr != V_PF ) {
        !           791:       MKV(VR((P)p),x);
        !           792:       for ( c = 0; dc; dc = NEXT(dc) ) {
        !           793:         substfp(vl,(Obj)COEF(dc),u,f,&t);
        !           794:         if ( DEG(dc) ) {
        !           795:           gen_pwrr(vl,(Obj)x,(Obj)DEG(dc),&s);
        !           796:           mulr(vl,s,t,&m);
        !           797:           addr(vl,m,c,&a); c = a;
        !           798:         } else {
        !           799:           addr(vl,t,c,&a); c = a;
        !           800:         }
        !           801:       }
        !           802:     } else {
        !           803:       substfv(vl,v,u,f,&p0);
        !           804:       substfp(vl,(Obj)COEF(dc),u,f,&c);
        !           805:       for ( d = DEG(dc), dc = NEXT(dc); dc; d = DEG(dc), dc = NEXT(dc) ) {
        !           806:           subz(d,DEG(dc),(Z *)&t);
        !           807:           gen_pwrr(vl,p0,t,&s); mulr(vl,s,c,&m);
        !           808:           substfp(vl,(Obj)COEF(dc),u,f,&t); addr(vl,m,t,&c);
        !           809:       }
        !           810:       if ( d ) {
        !           811:         gen_pwrr(vl,p0,(Obj)d,&t); mulr(vl,t,c,&m);
        !           812:         c = m;
        !           813:       }
        !           814:     }
        !           815:     *pr = c;
        !           816:   }
        !           817: }
        !           818:
        !           819: void substfv(VL vl,V v,PF u,PF f,Obj *c)
        !           820: {
        !           821:   P t;
        !           822:   Obj r,s,w;
        !           823:   int i,j;
        !           824:   PFINS ins,tins;
        !           825:   PFAD ad,tad;
        !           826:
        !           827:   ins = (PFINS)v->priv; ad = ins->ad;
        !           828:   if ( ins->pf == u ) {
        !           829:     if ( u->argc != f->argc )
        !           830:       error("substfv : argument mismatch");
        !           831:     if ( !f->body ) {
        !           832:       mkpfins(f,f->args,&v); MKV(v,t); r = (Obj)t;
        !           833:     } else
        !           834:       r = f->body;
        !           835:     for ( i = 0; i < f->argc; i++ )
        !           836:       for ( j = 0; j < ad[i].d; j++ ) {
        !           837:         derivr(vl,r,f->args[i],&s); r = s;
        !           838:       }
        !           839:     for ( i = 0; i < f->argc; i++ ) {
        !           840:       substfr(vl,ad[i].arg,u,f,&w);
        !           841:       substr(vl,0,r,f->args[i],w,&s); r = s;
        !           842:     }
        !           843:     *c = r;
        !           844:   } else {
        !           845:     tins = (PFINS)MALLOC(sizeof(PF)+f->argc*sizeof(struct oPFAD));
        !           846:     tins->pf = ins->pf; tad = tins->ad;
        !           847:     for ( i = 0; i < f->argc; i++ ) {
        !           848:       tad[i].d = ad[i].d; substfr(vl,ad[i].arg,u,f,&tad[i].arg);
        !           849:     }
        !           850:     instoobj(tins,c);
        !           851:   }
        !           852: }

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