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

Annotation of OpenXM_contrib2/asir2000/parse/puref.c, Revision 1.11

1.2       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
1.3       noro       26:  * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.2       noro       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:  *
1.11    ! fujimoto   48:  * $OpenXM: OpenXM_contrib2/asir2000/parse/puref.c,v 1.10 2014/09/19 01:26:00 noro Exp $
1.2       noro       49: */
1.1       noro       50: #include "ca.h"
                     51: #include "parse.h"
                     52:
                     53: NODE pflist;
                     54:
1.4       noro       55: void searchpf(char *name,FUNC *fp)
1.1       noro       56: {
                     57:        NODE node;
                     58:        PF pf;
                     59:        FUNC t;
                     60:
                     61:        for ( node = pflist; node; node = NEXT(node) )
                     62:                if ( !strcmp(name,((PF)node->body)->name) ) {
                     63:                        pf = (PF)node->body;
                     64:                        *fp = t = (FUNC)MALLOC(sizeof(struct oFUNC));
                     65:                        t->name = name; t->id = A_PURE; t->argc = pf->argc;
1.5       noro       66:                        t->f.puref = pf; t->fullname = name;
1.1       noro       67:                        return;
                     68:                }
                     69:        *fp = 0;
                     70: }
                     71:
1.4       noro       72: void searchc(char *name,FUNC *fp)
1.1       noro       73: {
                     74:        NODE node;
                     75:        PF pf;
                     76:        FUNC t;
                     77:
                     78:        for ( node = pflist; node; node = NEXT(node) )
                     79:                if ( !strcmp(name,((PF)node->body)->name)
                     80:                        && !((PF)node->body)->argc ) {
                     81:                        pf = (PF)node->body;
                     82:                        *fp = t = (FUNC)MALLOC(sizeof(struct oFUNC));
                     83:                        t->name = name; t->id = A_PURE; t->argc = pf->argc;
1.5       noro       84:                        t->f.puref = pf; t->fullname = name;
1.1       noro       85:                        return;
                     86:                }
                     87:        *fp = 0;
                     88: }
                     89:
1.4       noro       90: void mkpf(char *name,Obj body,int argc,V *args,
                     91:        int (*parif)(),double (*libmf)(), int (*simp)(),PF *pfp)
1.1       noro       92: {
                     93:        PF pf;
                     94:        NODE node;
                     95:
                     96:        NEWPF(pf); pf->name = name; pf->body = body;
                     97:        pf->argc = argc; pf->args = args; pf->pari = parif; pf->simplify = simp;
                     98:        pf->libm = libmf;
                     99:        for ( node = pflist; node; node = NEXT(node) )
                    100:                if ( !strcmp(((PF)BDY(node))->name,name) )
                    101:                        break;
                    102:        if ( !node ) {
                    103:                NEWNODE(node); NEXT(node) = pflist; pflist = node;
                    104: /*             fprintf(stderr,"%s() defined.\n",name); */
                    105:        } else
                    106:                fprintf(stderr,"%s() redefined.\n",name);
1.11    ! fujimoto  107: #if defined(__MINGW32__) || defined(__MINGW64__)
        !           108:        fflush(stderr);
        !           109: #endif
1.1       noro      110:        BDY(node) = (pointer)pf; *pfp = pf;
                    111: }
                    112:
                    113: /*
                    114:    create an instance of a pure function. args are given
                    115:    as an array of V. So we have to create a P object for
                    116:    each arg.
                    117:  */
                    118:
1.4       noro      119: void mkpfins(PF pf,V *args,V *vp)
1.1       noro      120: {
                    121:        V v;
                    122:        PFINS ins;
                    123:        PFAD ad;
                    124:        int i;
                    125:        P t;
                    126:
                    127:        NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;
                    128:        ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));
                    129:        bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));
                    130:        ins->pf = pf;
                    131:        v->priv = (pointer)ins;
                    132:        for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {
                    133:                ad[i].d = 0; MKV(args[i],t); ad[i].arg = (Obj)t;
                    134:        }
                    135:        appendpfins(v,vp);
                    136: }
                    137:
                    138: /* the same as above. Argements are given as an array of Obj */
                    139:
1.4       noro      140: void _mkpfins(PF pf,Obj *args,V *vp)
1.1       noro      141: {
                    142:        V v;
                    143:        PFINS ins;
                    144:        PFAD ad;
                    145:        int i;
                    146:
                    147:        NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;
                    148:        ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));
                    149:        bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));
                    150:        ins->pf = pf;
                    151:        v->priv = (pointer)ins;
                    152:        for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {
                    153:                ad[i].d = 0; ad[i].arg = args[i];
                    154:        }
                    155:        appendpfins(v,vp);
                    156: }
                    157:
                    158: /* the same as above. darray is also given */
                    159:
1.4       noro      160: void _mkpfins_with_darray(PF pf,Obj *args,int *darray,V *vp)
1.1       noro      161: {
                    162:        V v;
                    163:        PFINS ins;
                    164:        PFAD ad;
                    165:        int i;
                    166:
                    167:        NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;
                    168:        ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));
                    169:        bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));
                    170:        ins->pf = pf;
                    171:        v->priv = (pointer)ins;
                    172:        for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {
                    173:                ad[i].d = darray[i]; ad[i].arg = args[i];
                    174:        }
                    175:        appendpfins(v,vp);
                    176: }
                    177:
1.4       noro      178: void appendpfins(V v,V *vp)
1.1       noro      179: {
                    180:        PF fdef;
                    181:        PFAD ad,tad;
                    182:        NODE node;
                    183:        int i;
                    184:
                    185:        fdef = ((PFINS)v->priv)->pf; ad = ((PFINS)v->priv)->ad;
                    186:        for ( node = fdef->ins; node; node = NEXT(node) ) {
                    187:                for ( i = 0, tad = ((PFINS)((V)node->body)->priv)->ad;
                    188:                        i < fdef->argc; i++ )
1.6       noro      189:                        if ( (ad[i].d != tad[i].d) || !equalr(CO,ad[i].arg,tad[i].arg) )
1.1       noro      190:                                break;
                    191:                if ( i == fdef->argc ) {
                    192:                        *vp = (V)node->body;
                    193:                        return;
                    194:                }
                    195:        }
                    196:        NEWNODE(node); node->body = (pointer)v; NEXT(node) = fdef->ins;
                    197:        fdef->ins = node; appendvar(CO,v); *vp = v;
                    198: }
                    199:
1.4       noro      200: void duppfins(V v,V *vp)
1.1       noro      201: {
                    202:        V tv;
                    203:        PFINS tins;
                    204:        int size;
                    205:
                    206:        NEWV(tv); tv->name = v->name; tv->attr = v->attr;
                    207:        size = sizeof(PF)+((PFINS)v->priv)->pf->argc*sizeof(struct oPFAD);
                    208:        tins = (PFINS)MALLOC(size); bcopy((char *)v->priv,(char *)tins,size);
                    209:        tv->priv = (pointer)tins;
                    210:        *vp = tv;
                    211: }
                    212:
1.4       noro      213: void derivvar(VL vl,V pf,V v,Obj *a)
1.1       noro      214: {
                    215:        Obj t,s,u,w,u1;
                    216:        P p;
                    217:        V tv,sv;
                    218:        PF fdef;
                    219:        PFAD ad;
                    220:        int i,j;
                    221:
                    222:        fdef = ((PFINS)pf->priv)->pf; ad = ((PFINS)pf->priv)->ad;
                    223:        if ( fdef->deriv ) {
                    224:                for ( t = 0, i = 0; i < fdef->argc; i++ ) {
                    225:                        derivr(vl,ad[i].arg,v,&s);
                    226:                        for ( j = 0, u = fdef->deriv[i]; j < fdef->argc; j++ ) {
                    227:                                substr(vl,0,u,fdef->args[j],ad[j].arg,&u1); u = u1;
                    228:                        }
                    229:                        mulr(vl,s,u,&w); addr(vl,t,w,&s); t = s;
                    230:                }
                    231:                *a = t;
                    232:        } else {
                    233:                for ( t = 0, i = 0; i < fdef->argc; i++ ) {
                    234:                        derivr(vl,ad[i].arg,v,&s);
                    235:                        duppfins(pf,&tv); (((PFINS)tv->priv)->ad)[i].d++;
                    236:                        appendpfins(tv,&sv);
                    237:                        MKV(sv,p); mulr(vl,s,(Obj)p,&w); addr(vl,t,w,&s); t = s;
                    238:                }
                    239:                *a = t;
                    240:        }
                    241: }
                    242:
1.4       noro      243: void derivr(VL vl,Obj a,V v,Obj *b)
1.1       noro      244: {
                    245:        VL tvl,svl;
                    246:        Obj r,s,t,u,nm,dn,dnm,ddn,m;
                    247:
                    248:        if ( !a )
                    249:                *b = 0;
                    250:        else
                    251:                switch ( OID(a) ) {
                    252:                        case O_N:
                    253:                                *b = 0; break;
                    254:                        case O_P:
                    255:                                clctvr(vl,a,&tvl);
                    256:                                for ( dnm = 0, svl = tvl; svl; svl = NEXT(svl) ) {
                    257:                                        if ( svl->v == v ) {
                    258:                                                pderivr(vl,a,v,&s); addr(vl,s,dnm,&u); dnm = u;
                    259:                                        } else if ( (vid)svl->v->attr == V_PF ) {
                    260:                                                pderivr(vl,a,svl->v,&s); derivvar(vl,svl->v,v,&r);
                    261:                                                mulr(vl,s,r,&u); addr(vl,u,dnm,&s); dnm = s;
                    262:                                        }
                    263:                                }
                    264:                                *b = (Obj)dnm; break;
                    265:                        case O_R:
                    266:                                clctvr(vl,a,&tvl);
                    267:                                nm = (Obj)NM((R)a); dn = (Obj)DN((R)a);
                    268:                                for ( dnm = ddn = 0, svl = tvl; svl; svl = NEXT(svl) ) {
                    269:                                        if ( svl->v == v ) {
                    270:                                                pderivr(vl,nm,v,&s); addr(vl,s,dnm,&u); dnm = u;
                    271:                                                pderivr(vl,dn,v,&s); addr(vl,s,ddn,&u); ddn = u;
                    272:                                        } else if ( (vid)svl->v->attr == V_PF ) {
                    273:                                                pderivr(vl,nm,svl->v,&s); derivvar(vl,svl->v,v,&r);
                    274:                                                mulr(vl,s,r,&u); addr(vl,u,dnm,&s); dnm = s;
                    275:                                                pderivr(vl,dn,svl->v,&s); derivvar(vl,svl->v,v,&r);
                    276:                                                mulr(vl,s,r,&u); addr(vl,u,ddn,&s); ddn = s;
                    277:                                        }
                    278:                                }
                    279:                                mulr(vl,dnm,dn,&t); mulr(vl,ddn,nm,&s);
                    280:                                subr(vl,t,s,&u); reductr(vl,u,&t);
                    281:                                if ( !t )
                    282:                                        *b = 0;
                    283:                                else {
                    284:                                        mulp(vl,(P)dn,(P)dn,(P *)&m); divr(vl,t,m,b);
                    285:                                }
                    286:                                break;
1.8       noro      287:        }
                    288: }
                    289:
1.9       noro      290: void simple_derivr(VL vl,Obj a,V v,Obj *b)
                    291: {
                    292:        Obj r,s,t,u,nm,dn;
                    293:
                    294:        if ( !a || NUM(a) )
                    295:                *b = 0;
                    296:        else
                    297:                switch ( OID(a) ) {
                    298:                        case O_P:
                    299:                                pderivr(vl,a,v,b); break;
                    300:                        case O_R:
                    301:                                nm = (Obj)NM((R)a); dn = (Obj)DN((R)a);
                    302:                                /* (nm/dn)' = nm'/dn - dn'/dn*nm/dn */
                    303:                                pderivr(vl,nm,v,&s); divr(vl,s,dn,&u); reductr(vl,u,&t);
                    304:                                pderivr(vl,dn,v,&s); divr(vl,s,dn,&u); reductr(vl,u,&s); mulr(vl,s,a,&u);
                    305:                                subr(vl,t,u,&s); reductr(vl,s,b);
                    306:                                break;
                    307:                        default:
                    308:                                error("simple_derivr : invalid argument");
                    309:        }
                    310: }
                    311:
1.8       noro      312: int obj_is_dependent(Obj a,V v)
                    313: {
                    314:        if ( !a || OID(a) <= O_N ) return 0;
                    315:        else if ( OID(a) == O_P ) return poly_is_dependent((P)a,v);
                    316:        else if ( OID(a) == O_R ) return poly_is_dependent(NM((R)a),v)
                    317:                || poly_is_dependent(DN((R)a),v);
                    318:        else
                    319:                error("obj_is_dependent : not implemented");
                    320: }
                    321:
                    322: int poly_is_dependent(P p,V v)
                    323: {
                    324:        DCP dc;
                    325:
                    326:        if ( !p || OID(p) <= O_N ) return 0;
                    327:        else if ( v == VR(p) ) return 1;
                    328:        else {
                    329:                for ( dc = DC(p); dc; dc = NEXT(dc) )
                    330:                        if ( poly_is_dependent(COEF(dc),v) ) return 1;
                    331:                return 0;
1.1       noro      332:        }
                    333: }
                    334:
1.7       noro      335: void gen_pwrr(VL vl,Obj a,Obj d,Obj *r)
                    336: {
                    337:        if ( INT(d) )
                    338:                pwrr(vl,a,d,r);
                    339:        else
                    340:                mkpow(vl,a,d,r);
                    341: }
                    342:
1.4       noro      343: void substr(VL vl,int partial,Obj a,V v,Obj b,Obj *c)
1.1       noro      344: {
                    345:        Obj nm,dn,t;
                    346:
                    347:        if ( !a )
                    348:                *c = 0;
                    349:        else {
                    350:                switch ( OID(a) ) {
                    351:                        case O_N:
                    352:                                *c = a; break;
                    353:                        case O_P:
                    354:                                substpr(vl,partial,a,v,b,c); break;
                    355:                        case O_R:
                    356:                                substpr(vl,partial,(Obj)NM((R)a),v,b,&nm);
                    357:                                substpr(vl,partial,(Obj)DN((R)a),v,b,&dn);
                    358:                                divr(vl,nm,dn,&t); reductr(vl,t,c);
                    359:                                break;
                    360:                        default:
                    361:                                *c = 0; break;
                    362:                }
                    363:        }
                    364: }
                    365:
1.4       noro      366: void substpr(VL vl,int partial,Obj p,V v0,Obj p0,Obj *pr)
1.1       noro      367: {
                    368:        P x;
                    369:        Obj t,m,c,s,a;
                    370:        DCP dc;
                    371:        Q d;
                    372:        V v;
                    373:        PF pf;
                    374:        PFAD ad,tad;
                    375:        PFINS tins;
                    376:        int i;
                    377:
                    378:        if ( !p )
                    379:                *pr = 0;
                    380:        else if ( NUM(p) )
                    381:                *pr = (Obj)p;
                    382:        else if ( (v = VR((P)p)) != v0 ) {
                    383:                if ( !partial && ((vid)v->attr == V_PF) ) {
                    384:                        ad = ((PFINS)v->priv)->ad; pf = ((PFINS)v->priv)->pf;
                    385:                        tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
                    386:                        tins->pf = pf;
                    387:                        for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {
                    388:                                tad[i].d = ad[i].d;
                    389:                                substr(vl,partial,ad[i].arg,v0,p0,&tad[i].arg);
                    390:                        }
                    391:                        simplify_ins(tins,(Obj *)&x);
                    392:                } else
                    393:                        MKV(VR((P)p),x);
                    394:                for ( c = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {
                    395:                        substpr(vl,partial,(Obj)COEF(dc),v0,p0,&t);
                    396:                        if ( DEG(dc) ) {
1.7       noro      397:                                gen_pwrr(vl,(Obj)x,(Obj)DEG(dc),&s);
                    398:                                mulr(vl,s,t,&m);
1.1       noro      399:                                addr(vl,m,c,&a); c = a;
                    400:                        } else {
                    401:                                addr(vl,t,c,&a); c = a;
                    402:                        }
                    403:                }
                    404:                *pr = c;
                    405:        } else {
                    406:                dc = DC((P)p);
                    407:                if ( !partial )
                    408:                        substpr(vl,partial,(Obj)COEF(dc),v0,p0,&c);
                    409:                else
                    410:                        c = (Obj)COEF(dc);
                    411:                for ( d = DEG(dc), dc = NEXT(dc); dc; d = DEG(dc), dc = NEXT(dc) ) {
1.7       noro      412:                                subq(d,DEG(dc),(Q *)&t);
                    413:                                gen_pwrr(vl,p0,t,&s); mulr(vl,s,c,&m);
1.1       noro      414:                                if ( !partial )
                    415:                                        substpr(vl,partial,(Obj)COEF(dc),v0,p0,&t);
                    416:                                else
                    417:                                        t = (Obj)COEF(dc);
                    418:                                addr(vl,m,t,&c);
                    419:                }
                    420:                if ( d ) {
1.7       noro      421:                        gen_pwrr(vl,p0,(Obj)d,&t);
                    422:                        mulr(vl,t,c,&m);
1.1       noro      423:                        c = m;
                    424:                }
                    425:                *pr = c;
                    426:        }
                    427: }
                    428:
1.4       noro      429: void evalr(VL vl,Obj a,int prec,Obj *c)
1.1       noro      430: {
                    431:        Obj nm,dn;
                    432:
                    433:        if ( !a )
                    434:                *c = 0;
                    435:        else {
                    436:                switch ( OID(a) ) {
                    437:                        case O_N:
                    438:                                *c = a; break;
                    439:                        case O_P:
                    440:                                evalp(vl,(P)a,prec,(P *)c); break;
                    441:                        case O_R:
                    442:                                evalp(vl,NM((R)a),prec,(P *)&nm); evalp(vl,DN((R)a),prec,(P *)&dn);
                    443:                                divr(vl,nm,dn,c);
                    444:                                break;
                    445:                        default:
                    446:                                error("evalr : not implemented"); break;
                    447:                }
                    448:        }
                    449: }
                    450:
1.4       noro      451: void evalp(VL vl,P p,int prec,P *pr)
1.1       noro      452: {
                    453:        P t;
                    454:        DCP dc,dcr0,dcr;
                    455:        Obj u;
                    456:
                    457:        if ( !p || NUM(p) )
                    458:                *pr = p;
                    459:        else {
                    460:                for ( dcr0 = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {
                    461:                        evalp(vl,COEF(dc),prec,&t);
                    462:                        if ( t ) {
                    463:                                NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = t;
                    464:                        }
                    465:                }
                    466:                if ( !dcr0 ) {
                    467:                        *pr = 0; return;
                    468:                } else {
                    469:                        NEXT(dcr) = 0; MKP(VR(p),dcr0,t);
                    470:                }
                    471:                if ( NUM(t) || (VR(t) != VR(p)) || ((vid)VR(p)->attr != V_PF) ) {
                    472:                        *pr = t; return;
                    473:                } else {
                    474:                        evalv(vl,VR(p),prec,&u); substr(vl,1,(Obj)t,VR(p),u,(Obj *)pr);
                    475:                }
                    476:        }
                    477: }
                    478:
1.4       noro      479: void evalv(VL vl,V v,int prec,Obj *rp)
1.1       noro      480: {
                    481:        PFINS ins,tins;
                    482:        PFAD ad,tad;
                    483:        PF pf;
                    484:        P t;
                    485:        int i;
                    486:
                    487:        if ( (vid)v->attr != V_PF ) {
                    488:                MKV(v,t); *rp = (Obj)t;
                    489:        } else {
                    490:                ins = (PFINS)v->priv; ad = ins->ad; pf = ins->pf;
                    491:                tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
                    492:                tins->pf = pf;
                    493:                for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {
                    494:                        tad[i].d = ad[i].d; evalr(vl,ad[i].arg,prec,&tad[i].arg);
                    495:                }
                    496:                evalins(tins,prec,rp);
                    497:        }
                    498: }
                    499:
1.4       noro      500: void evalins(PFINS ins,int prec,Obj *rp)
1.1       noro      501: {
                    502:        PF pf;
                    503:        PFAD ad;
                    504:        int i;
                    505:        Q q;
                    506:        V v;
                    507:        P x;
                    508:        NODE n0,n;
                    509:
                    510:        pf = ins->pf; ad = ins->ad;
                    511:        for ( i = 0; i < pf->argc; i++ )
                    512:                if ( ad[i].d || (ad[i].arg && !NUM(ad[i].arg)) )
                    513:                        break;
                    514:        if ( (i != pf->argc) || !pf->pari ) {
                    515:                instov(ins,&v); MKV(v,x); *rp = (Obj)x;
                    516:        } else {
                    517:                for ( n0 = 0, i = 0; i < pf->argc; i++ ) {
                    518:                        NEXTNODE(n0,n); BDY(n) = (pointer)ad[i].arg;
                    519:                }
                    520:                if ( prec ) {
                    521:                        NEXTNODE(n0,n); STOQ(prec,q); BDY(n) = (pointer)q;
                    522:                }
                    523:                if ( n0 )
                    524:                        NEXT(n) = 0;
                    525:                (*pf->pari)(n0,rp);
                    526:        }
                    527: }
                    528:
1.4       noro      529: void devalr(VL vl,Obj a,Obj *c)
1.1       noro      530: {
                    531:        Obj nm,dn;
                    532:        double d;
                    533:        Real r;
                    534:
                    535:        if ( !a )
                    536:                *c = 0;
                    537:        else {
                    538:                switch ( OID(a) ) {
                    539:                        case O_N:
                    540:                                d = ToReal(a);
                    541:                                MKReal(d,r);
                    542:                                *c = (Obj)r;
                    543:                                break;
                    544:                        case O_P:
                    545:                                devalp(vl,(P)a,(P *)c); break;
                    546:                        case O_R:
                    547:                                devalp(vl,NM((R)a),(P *)&nm);
                    548:                                devalp(vl,DN((R)a),(P *)&dn);
                    549:                                divr(vl,nm,dn,c);
                    550:                                break;
                    551:                        default:
                    552:                                error("devalr : not implemented"); break;
                    553:                }
                    554:        }
                    555: }
                    556:
1.4       noro      557: void devalp(VL vl,P p,P *pr)
1.1       noro      558: {
                    559:        P t;
                    560:        DCP dc,dcr0,dcr;
                    561:        Obj u,s;
                    562:        double d;
                    563:        Real r;
                    564:
                    565:        if ( !p || NUM(p) ) {
                    566:                d = ToReal(p);
                    567:                MKReal(d,r);
                    568:                *pr = (P)r;
                    569:        } else {
                    570:                for ( dcr0 = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {
                    571:                        devalp(vl,COEF(dc),&t);
                    572:                        if ( t ) {
                    573:                                NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = t;
                    574:                        }
                    575:                }
                    576:                if ( !dcr0 )
                    577:                        *pr = 0;
                    578:                else {
                    579:                        NEXT(dcr) = 0; MKP(VR(p),dcr0,t);
                    580:                        if ( NUM(t) ) {
                    581:                                d = ToReal((Num)t);
                    582:                                MKReal(d,r);
                    583:                                *pr = (P)r;
                    584:                        } else if ( (VR(t) != VR(p)) || (VR(p)->attr != (pointer)V_PF) )
                    585:                                *pr = t;
                    586:                        else {
                    587:                                devalv(vl,VR(p),&u);
                    588:                                substr(vl,1,(Obj)t,VR(p),u,&s);
                    589:                                if ( s && NUM(s) ) {
                    590:                                        d = ToReal((Num)s);
                    591:                                        MKReal(d,r);
                    592:                                        *pr = (P)r;
                    593:                                } else
                    594:                                        *pr = (P)s;
                    595:                        }
                    596:                }
                    597:        }
                    598: }
                    599:
1.4       noro      600: void devalv(VL vl,V v,Obj *rp)
1.1       noro      601: {
                    602:        PFINS ins,tins;
                    603:        PFAD ad,tad;
                    604:        PF pf;
                    605:        P t;
                    606:        int i;
                    607:
                    608:        if ( (vid)v->attr != V_PF ) {
                    609:                MKV(v,t); *rp = (Obj)t;
                    610:        } else {
                    611:                ins = (PFINS)v->priv; ad = ins->ad; pf = ins->pf;
                    612:                tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
                    613:                tins->pf = pf;
                    614:                for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {
                    615:                        tad[i].d = ad[i].d; devalr(vl,ad[i].arg,&tad[i].arg);
                    616:                }
                    617:                devalins(tins,rp);
                    618:        }
                    619: }
                    620:
1.4       noro      621: void devalins(PFINS ins,Obj *rp)
1.1       noro      622: {
                    623:        PF pf;
                    624:        PFAD ad;
                    625:        int i;
                    626:        Real r;
                    627:        double d;
                    628:        V v;
                    629:        P x;
                    630:
                    631:        pf = ins->pf; ad = ins->ad;
                    632:        for ( i = 0; i < pf->argc; i++ )
                    633:                if ( ad[i].d || (ad[i].arg && !NUM(ad[i].arg)) )
                    634:                        break;
                    635:        if ( (i != pf->argc) || !pf->libm ) {
                    636:                instov(ins,&v); MKV(v,x); *rp = (Obj)x;
                    637:        } else {
                    638:                switch ( pf->argc ) {
                    639:                        case 0:
                    640:                                d = (*pf->libm)(); break;
                    641:                        case 1:
                    642:                                d = (*pf->libm)(ToReal(ad[0].arg)); break;
                    643:                        case 2:
                    644:                                d = (*pf->libm)(ToReal(ad[0].arg),ToReal(ad[1].arg)); break;
                    645:                        case 3:
                    646:                                d = (*pf->libm)(ToReal(ad[0].arg),ToReal(ad[1].arg),
                    647:                                        ToReal(ad[2].arg)); break;
                    648:                        case 4:
                    649:                                d = (*pf->libm)(ToReal(ad[0].arg),ToReal(ad[1].arg),
                    650:                                        ToReal(ad[2].arg),ToReal(ad[3].arg)); break;
                    651:                        default:
                    652:                                error("devalv : not supported");
                    653:                }
                    654:                MKReal(d,r); *rp = (Obj)r;
                    655:        }
                    656: }
                    657:
1.10      noro      658: extern int evalef;
                    659:
                    660: void simplify_elemfunc_ins(PFINS ins,Obj *rp)
                    661: {
                    662:        V v;
                    663:        P t;
                    664:
                    665:   if ( evalef )
                    666:     evalins(ins,0,rp);
                    667:   else {
                    668:          instov(ins,&v); MKV(v,t); *rp = (Obj)t;
                    669:   }
                    670: }
                    671:
1.4       noro      672: void simplify_ins(PFINS ins,Obj *rp)
1.1       noro      673: {
                    674:        V v;
                    675:        P t;
                    676:
                    677:        if ( ins->pf->simplify )
                    678:                (*ins->pf->simplify)(ins,rp);
                    679:        else {
                    680:                instov(ins,&v); MKV(v,t); *rp = (Obj)t;
                    681:        }
                    682: }
                    683:
1.4       noro      684: void instov(PFINS ins,V *vp)
1.1       noro      685: {
                    686:        V v;
                    687:
                    688:        NEWV(v); NAME(v) = 0;
                    689:        v->attr = (pointer)V_PF; v->priv = (pointer)ins;
                    690:        appendpfins(v,vp);
                    691: }
                    692:
1.4       noro      693: void substfr(VL vl,Obj a,PF u,PF f,Obj *c)
1.1       noro      694: {
                    695:        Obj nm,dn;
                    696:
                    697:        if ( !a )
                    698:                *c = 0;
                    699:        else {
                    700:                switch ( OID(a) ) {
                    701:                        case O_N:
                    702:                                *c = a; break;
                    703:                        case O_P:
                    704:                                substfp(vl,a,u,f,c); break;
                    705:                        case O_R:
                    706:                                substfp(vl,(Obj)NM((R)a),u,f,&nm); substfp(vl,(Obj)DN((R)a),u,f,&dn);
                    707:                                divr(vl,nm,dn,c);
                    708:                                break;
                    709:                        default:
                    710:                                error("substfr : not implemented"); break;
                    711:                }
                    712:        }
                    713: }
                    714:
1.4       noro      715: void substfp(VL vl,Obj p,PF u,PF f,Obj *pr)
1.1       noro      716: {
                    717:        V v;
                    718:        DCP dc;
                    719:        Obj a,c,m,s,t,p0;
                    720:        Q d;
                    721:        P x;
                    722:
                    723:        if ( !p )
                    724:                *pr = 0;
                    725:        else if ( NUM(p) )
                    726:                *pr = (Obj)p;
                    727:        else {
                    728:                v = VR((P)p); dc = DC((P)p);
                    729:                if ( (int)v->attr != V_PF ) {
                    730:                        MKV(VR((P)p),x);
                    731:                        for ( c = 0; dc; dc = NEXT(dc) ) {
                    732:                                substfp(vl,(Obj)COEF(dc),u,f,&t);
                    733:                                if ( DEG(dc) ) {
1.7       noro      734:                                        gen_pwrr(vl,(Obj)x,(Obj)DEG(dc),&s);
                    735:                                        mulr(vl,s,t,&m);
1.1       noro      736:                                        addr(vl,m,c,&a); c = a;
                    737:                                } else {
                    738:                                        addr(vl,t,c,&a); c = a;
                    739:                                }
                    740:                        }
                    741:                } else {
                    742:                        substfv(vl,v,u,f,&p0);
                    743:                        substfp(vl,(Obj)COEF(dc),u,f,&c);
                    744:                        for ( d = DEG(dc), dc = NEXT(dc); dc; d = DEG(dc), dc = NEXT(dc) ) {
1.7       noro      745:                                        subq(d,DEG(dc),(Q *)&t);
                    746:                                        gen_pwrr(vl,p0,t,&s); mulr(vl,s,c,&m);
1.1       noro      747:                                        substfp(vl,(Obj)COEF(dc),u,f,&t); addr(vl,m,t,&c);
                    748:                        }
                    749:                        if ( d ) {
1.7       noro      750:                                gen_pwrr(vl,p0,(Obj)d,&t); mulr(vl,t,c,&m);
1.1       noro      751:                                c = m;
                    752:                        }
                    753:                }
                    754:                *pr = c;
                    755:        }
                    756: }
                    757:
1.4       noro      758: void substfv(VL vl,V v,PF u,PF f,Obj *c)
1.1       noro      759: {
                    760:        P t;
                    761:        Obj r,s,w;
                    762:        int i,j;
                    763:        PFINS ins,tins;
                    764:        PFAD ad,tad;
                    765:
                    766:        ins = (PFINS)v->priv; ad = ins->ad;
                    767:        if ( ins->pf == u ) {
                    768:                if ( u->argc != f->argc )
                    769:                        error("substfv : argument mismatch");
                    770:                if ( !f->body ) {
                    771:                        mkpfins(f,f->args,&v); MKV(v,t); r = (Obj)t;
                    772:                } else
                    773:                        r = f->body;
                    774:                for ( i = 0; i < f->argc; i++ )
                    775:                        for ( j = 0; j < ad[i].d; j++ ) {
                    776:                                derivr(vl,r,f->args[i],&s); r = s;
                    777:                        }
                    778:                for ( i = 0; i < f->argc; i++ ) {
                    779:                        substfr(vl,ad[i].arg,u,f,&w);
                    780:                        substr(vl,0,r,f->args[i],w,&s); r = s;
                    781:                }
                    782:                *c = r;
                    783:        } else {
                    784:                tins = (PFINS)MALLOC(sizeof(PF)+f->argc*sizeof(struct oPFAD));
                    785:                tins->pf = ins->pf; tad = tins->ad;
                    786:                for ( i = 0; i < f->argc; i++ ) {
                    787:                        tad[i].d = ad[i].d; substfr(vl,ad[i].arg,u,f,&tad[i].arg);
                    788:                }
                    789:                instov(tins,&v); MKV(v,t); *c = (Obj)t;
                    790:        }
                    791: }

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