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

Annotation of OpenXM_contrib2/asir2000/builtin/poly.c, Revision 1.1

1.1     ! noro        1: /* $OpenXM: OpenXM/src/asir99/builtin/poly.c,v 1.1.1.1 1999/11/10 08:12:26 noro Exp $ */
        !             2: #include "ca.h"
        !             3: #include "parse.h"
        !             4: #include "base.h"
        !             5:
        !             6: void Pranp();
        !             7:
        !             8: void Pumul(),Pumul_ff(),Pusquare(),Pusquare_ff(),Putmul(),Putmul_ff();
        !             9: void Pkmul(),Pksquare(),Pktmul();
        !            10: void Pord(), Pcoef0(), Pcoef(), Pdeg(), Pmindeg(), Psetmod();
        !            11: void Pcoef_gf2n();
        !            12: void getcoef(), getdeglist(), mergedeglist(), change_mvar(), restore_mvar();
        !            13:
        !            14: void Pp_mag();
        !            15: void Pmergelist(), Pch_mv(), Pre_mv(), Pdeglist();
        !            16: void Pptomp(),Pmptop();
        !            17: void Pptolmp(),Plmptop();
        !            18: void Pptogf2n(),Pgf2ntop(),Pgf2ntovect();
        !            19: void Pptogfpn(),Pgfpntop();
        !            20: void Pfind_root_gf2n();
        !            21:
        !            22: void Pureverse(),Putrunc(),Pudecomp(),Purembymul(),Purembymul_precomp();
        !            23: void Puinvmod(),Purevinvmod();
        !            24: void Ppwrmod_ff(),Ppwrtab_ff(),Pgeneric_pwrmod_ff();
        !            25: void Pkpwrmod_lm(),Pkpwrtab_lm(),Pkgeneric_pwrmod_lm();
        !            26:
        !            27: void Pkmulum();
        !            28: void Pksquareum();
        !            29:
        !            30: void Pfmultest();
        !            31: void Phfmul_lm();
        !            32: void Plazy_lm();
        !            33:
        !            34: void Psetmod_ff();
        !            35: void Psimp_ff();
        !            36: void Pextdeg_ff();
        !            37: void Pcharacteristic_ff();
        !            38: void Pfield_type_ff();
        !            39: void Pfield_order_ff();
        !            40: void Prandom_ff();
        !            41:
        !            42: void Ptracemod_gf2n();
        !            43: void Psparsemod_gf2n();
        !            44: void Pmultest_gf2n();
        !            45: void Psquaretest_gf2n();
        !            46: void Pinvtest_gf2n();
        !            47: void Pbininv_gf2n();
        !            48: void Prinvtest_gf2n();
        !            49: void Pis_irred_gf2();
        !            50: void Pis_irred_ddd_gf2();
        !            51:
        !            52: void simp_ff(Obj,Obj *);
        !            53: void ranp(int,UP *);
        !            54: void field_order_ff(N *);
        !            55:
        !            56: extern int current_mod;
        !            57: extern GEN_UP2 current_mod_gf2n;
        !            58: extern int lm_lazy;
        !            59:
        !            60: int current_ff;
        !            61:
        !            62: struct ftab poly_tab[] = {
        !            63:        {"ranp",Pranp,2},
        !            64:        {"p_mag",Pp_mag,1},
        !            65:        {"ord",Pord,-1},
        !            66:        {"coef0",Pcoef0,-3},
        !            67:        {"coef",Pcoef,-3},
        !            68:        {"coef_gf2n",Pcoef_gf2n,2},
        !            69:        {"deg",Pdeg,2},
        !            70:        {"mindeg",Pmindeg,2},
        !            71:        {"setmod",Psetmod,-1},
        !            72:
        !            73:        {"sparsemod_gf2n",Psparsemod_gf2n,-1},
        !            74:
        !            75:        {"setmod_ff",Psetmod_ff,-2},
        !            76:        {"simp_ff",Psimp_ff,1},
        !            77:        {"extdeg_ff",Pextdeg_ff,0},
        !            78:        {"characteristic_ff",Pcharacteristic_ff,0},
        !            79:        {"field_type_ff",Pfield_type_ff,0},
        !            80:        {"field_order_ff",Pfield_order_ff,0},
        !            81:        {"random_ff",Prandom_ff,0},
        !            82:
        !            83:        {"deglist",Pdeglist,2},
        !            84:        {"mergelist",Pmergelist,2},
        !            85:        {"ch_mv",Pch_mv,2},
        !            86:        {"re_mv",Pre_mv,2},
        !            87:
        !            88:        {"ptomp",Pptomp,2},
        !            89:        {"mptop",Pmptop,1},
        !            90:
        !            91:        {"ptolmp",Pptolmp,1},
        !            92:        {"lmptop",Plmptop,1},
        !            93:
        !            94:        {"ptogf2n",Pptogf2n,1},
        !            95:        {"gf2ntop",Pgf2ntop,-2},
        !            96:        {"gf2ntovect",Pgf2ntovect,1},
        !            97:
        !            98:        {"ptogfpn",Pptogfpn,1},
        !            99:        {"gfpntop",Pgfpntop,-2},
        !           100:
        !           101:        {"kmul",Pkmul,2},
        !           102:        {"ksquare",Pksquare,1},
        !           103:        {"ktmul",Pktmul,3},
        !           104:
        !           105:        {"umul",Pumul,2},
        !           106:        {"usquare",Pusquare,1},
        !           107:        {"ureverse_inv_as_power_series",Purevinvmod,2},
        !           108:        {"uinv_as_power_series",Puinvmod,2},
        !           109:
        !           110:        {"utmul",Putmul,3},
        !           111:        {"umul_ff",Pumul_ff,2},
        !           112:        {"usquare_ff",Pusquare_ff,1},
        !           113:        {"utmul_ff",Putmul_ff,3},
        !           114:
        !           115:        /* for historical reason */
        !           116:        {"trunc",Putrunc,2},
        !           117:        {"decomp",Pudecomp,2},
        !           118:
        !           119:        {"utrunc",Putrunc,2},
        !           120:        {"udecomp",Pudecomp,2},
        !           121:        {"ureverse",Pureverse,1},
        !           122:        {"urembymul",Purembymul,2},
        !           123:        {"urembymul_precomp",Purembymul_precomp,3},
        !           124:
        !           125:        {"lazy_lm",Plazy_lm,1},
        !           126:        {"lazy_ff",Plazy_lm,1},
        !           127:
        !           128:        {"pwrmod_ff",Ppwrmod_ff,1},
        !           129:        {"generic_pwrmod_ff",Pgeneric_pwrmod_ff,3},
        !           130:        {"pwrtab_ff",Ppwrtab_ff,2},
        !           131:
        !           132:        {"tracemod_gf2n",Ptracemod_gf2n,3},
        !           133:        {"b_find_root_gf2n",Pfind_root_gf2n,1},
        !           134:
        !           135:        {"is_irred_gf2",Pis_irred_gf2,1},
        !           136:        {"is_irred_ddd_gf2",Pis_irred_ddd_gf2,1},
        !           137:
        !           138:        {"kpwrmod_lm",Pkpwrmod_lm,1},
        !           139:        {"kgeneric_pwrmod_lm",Pkgeneric_pwrmod_lm,3},
        !           140:        {"kpwrtab_lm",Pkpwrtab_lm,2},
        !           141:
        !           142:        {"kmulum",Pkmulum,3},
        !           143:        {"ksquareum",Pksquareum,2},
        !           144:
        !           145:        {"fmultest",Pfmultest,3},
        !           146:        {"hfmul_lm",Phfmul_lm,2},
        !           147:
        !           148:        {"multest_gf2n",Pmultest_gf2n,2},
        !           149:        {"squaretest_gf2n",Psquaretest_gf2n,1},
        !           150:        {"bininv_gf2n",Pbininv_gf2n,2},
        !           151:        {"invtest_gf2n",Pinvtest_gf2n,1},
        !           152:        {"rinvtest_gf2n",Prinvtest_gf2n,0},
        !           153:        {0,0,0},
        !           154: };
        !           155:
        !           156: extern V up_var;
        !           157:
        !           158: void Pranp(arg,rp)
        !           159: NODE arg;
        !           160: P *rp;
        !           161: {
        !           162:        int n;
        !           163:        UP c;
        !           164:
        !           165:        n = QTOS((Q)ARG0(arg));
        !           166:        ranp(n,&c);
        !           167:        if ( c ) {
        !           168:                up_var = VR((P)ARG1(arg));
        !           169:                uptop(c,rp);
        !           170:        } else
        !           171:                *rp = 0;
        !           172: }
        !           173:
        !           174: void ranp(n,nr)
        !           175: int n;
        !           176: UP *nr;
        !           177: {
        !           178:        int i;
        !           179:        unsigned int r;
        !           180:        Q q;
        !           181:        UP c;
        !           182:
        !           183:        *nr = c = UPALLOC(n);
        !           184:        for ( i = 0; i <= n; i++ ) {
        !           185:                r = random();
        !           186:                UTOQ(r,q);
        !           187:                c->c[i] = (Num)q;
        !           188:        }
        !           189:        for ( i = n; i >= 0 && !c->c[i]; i-- );
        !           190:        if ( i >= 0 )
        !           191:                c->d = i;
        !           192:        else
        !           193:                *nr = 0;
        !           194: }
        !           195:
        !           196: void Pp_mag(arg,rp)
        !           197: NODE arg;
        !           198: Q *rp;
        !           199: {
        !           200:        int l;
        !           201:        l = p_mag(ARG0(arg));
        !           202:        STOQ(l,*rp);
        !           203: }
        !           204:
        !           205: void Pord(arg,listp)
        !           206: NODE arg;
        !           207: LIST *listp;
        !           208: {
        !           209:        NODE n,tn;
        !           210:        LIST l;
        !           211:        VL vl,tvl,svl;
        !           212:        P t;
        !           213:        int i,j;
        !           214:        V *va;
        !           215:        V v;
        !           216:
        !           217:        if ( argc(arg) ) {
        !           218:                asir_assert(ARG0(arg),O_LIST,"ord");
        !           219:                for ( vl = 0, i = 0, n = BDY((LIST)ARG0(arg));
        !           220:                        n; n = NEXT(n), i++ ) {
        !           221:                        if ( !vl ) {
        !           222:                                NEWVL(vl); tvl = vl;
        !           223:                        } else {
        !           224:                                NEWVL(NEXT(tvl)); tvl = NEXT(tvl);
        !           225:                        }
        !           226:                        if ( !(t = (P)BDY(n)) || (OID(t) != O_P) )
        !           227:                                error("ord : invalid argument");
        !           228:                        VR(tvl) = VR(t);
        !           229:                }
        !           230:                va = (V *)ALLOCA(i*sizeof(V));
        !           231:                for ( j = 0, svl = vl; j < i; j++, svl = NEXT(svl) )
        !           232:                        va[j] = VR(svl);
        !           233:                for ( svl = CO; svl; svl = NEXT(svl) ) {
        !           234:                        v = VR(svl);
        !           235:                        for ( j = 0; j < i; j++ )
        !           236:                                if ( v == va[j] )
        !           237:                                        break;
        !           238:                        if ( j == i ) {
        !           239:                                if ( !vl ) {
        !           240:                                        NEWVL(vl); tvl = vl;
        !           241:                                } else {
        !           242:                                        NEWVL(NEXT(tvl)); tvl = NEXT(tvl);
        !           243:                                }
        !           244:                                VR(tvl) = v;
        !           245:                        }
        !           246:                }
        !           247:                if ( vl )
        !           248:                        NEXT(tvl) = 0;
        !           249:                CO = vl;
        !           250:        }
        !           251:        for ( n = 0, vl = CO; vl; vl = NEXT(vl) ) {
        !           252:                NEXTNODE(n,tn); MKV(VR(vl),t); BDY(tn) = (pointer)t;
        !           253:        }
        !           254:        NEXT(tn) = 0; MKLIST(l,n); *listp = l;
        !           255: }
        !           256:
        !           257: void Pcoef0(arg,rp)
        !           258: NODE arg;
        !           259: Obj *rp;
        !           260: {
        !           261:        Obj t,n;
        !           262:        P s;
        !           263:        DCP dc;
        !           264:        int id;
        !           265:        V v;
        !           266:        VL vl;
        !           267:
        !           268:        if ( !(t = (Obj)ARG0(arg)) || ((id = OID(ARG0(arg))) > O_P) )
        !           269:                *rp = 0;
        !           270:        else if ( (n = (Obj)ARG1(arg)) && (OID(n) > O_N) )
        !           271:                *rp = 0;
        !           272:        else if ( id == O_N )
        !           273:                if ( !n )
        !           274:                        *rp = t;
        !           275:                else
        !           276:                        *rp = 0;
        !           277:        else {
        !           278:                if ( argc(arg) == 3 ) {
        !           279:                        if ( (v = VR((P)ARG2(arg))) != VR((P)t) ) {
        !           280:                                reordvar(CO,v,&vl); reorderp(vl,CO,(P)t,&s);
        !           281:                        } else
        !           282:                                s = (P)t;
        !           283:                        if ( VR(s) != v ) {
        !           284:                                if ( n )
        !           285:                                        *rp = 0;
        !           286:                                else
        !           287:                                        *rp = t;
        !           288:                                return;
        !           289:                        }
        !           290:                } else
        !           291:                        s = (P)t;
        !           292:                for ( dc = DC(s); dc && cmpq(DEG(dc),(Q)n); dc = NEXT(dc) );
        !           293:                if ( dc )
        !           294:                        *rp = (Obj)COEF(dc);
        !           295:                else
        !           296:                        *rp = 0;
        !           297:        }
        !           298: }
        !           299:
        !           300: void Pcoef(arg,rp)
        !           301: NODE arg;
        !           302: Obj *rp;
        !           303: {
        !           304:        Obj t,n;
        !           305:        P s;
        !           306:        DCP dc;
        !           307:        int id;
        !           308:        V v;
        !           309:
        !           310:        if ( !(t = (Obj)ARG0(arg)) || ((id = OID(ARG0(arg))) > O_P) )
        !           311:                *rp = 0;
        !           312:        else if ( (n = (Obj)ARG1(arg)) && (OID(n) > O_N) )
        !           313:                *rp = 0;
        !           314:        else if ( id == O_N ) {
        !           315:                if ( !n )
        !           316:                        *rp = t;
        !           317:                else
        !           318:                        *rp = 0;
        !           319:        } else {
        !           320:                if ( argc(arg) == 3 ) {
        !           321:                        if ( (v = VR((P)ARG2(arg))) != VR((P)t) ) {
        !           322:                                getcoef(CO,(P)t,v,(Q)n,(P *)rp); return;
        !           323:                        } else
        !           324:                                s = (P)t;
        !           325:                        if ( VR(s) != v ) {
        !           326:                                if ( n )
        !           327:                                        *rp = 0;
        !           328:                                else
        !           329:                                        *rp = t;
        !           330:                                return;
        !           331:                        }
        !           332:                } else
        !           333:                        s = (P)t;
        !           334:                for ( dc = DC(s); dc && cmpq(DEG(dc),(Q)n); dc = NEXT(dc) );
        !           335:                if ( dc )
        !           336:                        *rp = (Obj)COEF(dc);
        !           337:                else
        !           338:                        *rp = 0;
        !           339:        }
        !           340: }
        !           341:
        !           342: void Pcoef_gf2n(arg,rp)
        !           343: NODE arg;
        !           344: Obj *rp;
        !           345: {
        !           346:        Obj t,n;
        !           347:        int id,d;
        !           348:        UP2 up2;
        !           349:
        !           350:        if ( !(t = (Obj)ARG0(arg)) || ((id = OID(ARG0(arg))) > O_P) )
        !           351:                *rp = 0;
        !           352:        else if ( (n = (Obj)ARG1(arg)) && (OID(n) > O_N) )
        !           353:                *rp = 0;
        !           354:        else if ( id == O_N && NID((Num)t) == N_GF2N ) {
        !           355:                d = QTOS((Q)n);
        !           356:                up2 = ((GF2N)t)->body;
        !           357:                if ( d > degup2(up2) )
        !           358:                        *rp = 0;
        !           359:                else
        !           360:                        *rp = (Obj)(up2->b[d/BSH]&(((unsigned long)1)<<(d%BSH))?ONE:0);
        !           361:        } else
        !           362:                *rp = 0;
        !           363: }
        !           364:
        !           365: void Pdeg(arg,rp)
        !           366: NODE arg;
        !           367: Q *rp;
        !           368: {
        !           369:        Obj t,v;
        !           370:        int d;
        !           371:
        !           372: #if 0
        !           373:        if ( !(t = (Obj)ARG0(arg)) || (OID(t) != O_P) )
        !           374:                *rp = 0;
        !           375:        else if ( !(v = (Obj)ARG1(arg)) || (VR((P)v) != VR((P)t)) )
        !           376:                *rp = 0;
        !           377:        else
        !           378:                *rp = (Obj)DEG(DC((P)t));
        !           379: #endif
        !           380:        if ( !(t = (Obj)ARG0(arg)) )
        !           381:                STOQ(-1,*rp);
        !           382:        else if ( OID(t) != O_P ) {
        !           383:                if ( OID(t) == O_N && NID(t) == N_GF2N
        !           384:                        && (v=(Obj)ARG1(arg)) && OID(v)== O_N && NID(v) == N_GF2N ) {
        !           385:                        d = degup2(((GF2N)t)->body);
        !           386:                        STOQ(d,*rp);
        !           387:                } else
        !           388:                        *rp = 0;
        !           389:        } else
        !           390:                degp(VR((P)ARG1(arg)),(P)ARG0(arg),rp);
        !           391: }
        !           392:
        !           393: void Pmindeg(arg,rp)
        !           394: NODE arg;
        !           395: Q *rp;
        !           396: {
        !           397:        Obj t;
        !           398:
        !           399:        if ( !(t = (Obj)ARG0(arg)) || (OID(t) != O_P) )
        !           400:                *rp = 0;
        !           401:        else
        !           402:                getmindeg(VR((P)ARG1(arg)),(P)ARG0(arg),rp);
        !           403: }
        !           404:
        !           405: void Psetmod(arg,rp)
        !           406: NODE arg;
        !           407: Q *rp;
        !           408: {
        !           409:        if ( arg ) {
        !           410:                asir_assert(ARG0(arg),O_N,"setmod");
        !           411:                current_mod = QTOS((Q)ARG0(arg));
        !           412:        }
        !           413:        STOQ(current_mod,*rp);
        !           414: }
        !           415:
        !           416: void Psparsemod_gf2n(arg,rp)
        !           417: NODE arg;
        !           418: Q *rp;
        !           419: {
        !           420:        int id;
        !           421:
        !           422:        if ( arg && current_mod_gf2n )
        !           423:                current_mod_gf2n->id = ARG0(arg)?1:0;
        !           424:        if ( !current_mod_gf2n )
        !           425:                id = -1;
        !           426:        else
        !           427:                id = current_mod_gf2n->id;
        !           428:        STOQ(id,*rp);
        !           429: }
        !           430:
        !           431: void Pmultest_gf2n(arg,rp)
        !           432: NODE arg;
        !           433: GF2N *rp;
        !           434: {
        !           435:        GF2N a,b,c;
        !           436:        int i;
        !           437:
        !           438:        a = (GF2N)ARG0(arg); b = (GF2N)ARG0(arg);
        !           439:        for ( i = 0; i < 10000; i++ )
        !           440:                mulgf2n(a,b,&c);
        !           441:        *rp = c;
        !           442: }
        !           443:
        !           444: void Psquaretest_gf2n(arg,rp)
        !           445: NODE arg;
        !           446: GF2N *rp;
        !           447: {
        !           448:        GF2N a,c;
        !           449:        int i;
        !           450:
        !           451:        a = (GF2N)ARG0(arg);
        !           452:        for ( i = 0; i < 10000; i++ )
        !           453:                squaregf2n(a,&c);
        !           454:        *rp = c;
        !           455: }
        !           456:
        !           457: void Pinvtest_gf2n(arg,rp)
        !           458: NODE arg;
        !           459: GF2N *rp;
        !           460: {
        !           461:        GF2N a,c;
        !           462:        int i;
        !           463:
        !           464:        a = (GF2N)ARG0(arg);
        !           465:        for ( i = 0; i < 10000; i++ )
        !           466:                invgf2n(a,&c);
        !           467:        *rp = c;
        !           468: }
        !           469:
        !           470: void Pbininv_gf2n(arg,rp)
        !           471: NODE arg;
        !           472: GF2N *rp;
        !           473: {
        !           474:        UP2 a,inv;
        !           475:        int n;
        !           476:
        !           477:        a = ((GF2N)ARG0(arg))->body;
        !           478:        n = QTOS((Q)ARG1(arg));
        !           479:        type1_bin_invup2(a,n,&inv);
        !           480:        MKGF2N(inv,*rp);
        !           481: }
        !           482:
        !           483: void Prinvtest_gf2n(rp)
        !           484: Real *rp;
        !           485: {
        !           486:        GF2N *a;
        !           487:        GF2N c;
        !           488:        double t0,t1,r;
        !           489:        int i;
        !           490:        double get_clock();
        !           491:
        !           492:        a = (GF2N *)ALLOCA(1000*sizeof(GF2N));
        !           493:        for ( i = 0; i < 1000; i++ ) {
        !           494:                randomgf2n(&a[i]);
        !           495:        }
        !           496:        t0 = get_clock();
        !           497:        for ( i = 0; i < 1000; i++ )
        !           498:                invgf2n(a[i],&c);
        !           499:        t1 = get_clock();
        !           500:        r = (t1-t0)/1000;
        !           501:        MKReal(r,*rp);
        !           502: }
        !           503:
        !           504: void Pfind_root_gf2n(arg,rp)
        !           505: NODE arg;
        !           506: GF2N *rp;
        !           507: {
        !           508:
        !           509: #if 0
        !           510:        UP p;
        !           511:
        !           512:        ptoup((P)ARG0(arg),&p);
        !           513:        find_root_gf2n(p,rp);
        !           514: #else
        !           515:        UP2 p;
        !           516:
        !           517:        ptoup2((P)ARG0(arg),&p);
        !           518:        find_root_up2(p,rp);
        !           519: #endif
        !           520: }
        !           521:
        !           522: void Pis_irred_gf2(arg,rp)
        !           523: NODE arg;
        !           524: Q *rp;
        !           525: {
        !           526:        UP2 t;
        !           527:
        !           528:        ptoup2(ARG0(arg),&t);
        !           529:        *rp = irredcheckup2(t) ? ONE : 0;
        !           530: }
        !           531:
        !           532: void Pis_irred_ddd_gf2(arg,rp)
        !           533: NODE arg;
        !           534: Q *rp;
        !           535: {
        !           536:        UP2 t;
        !           537:        int ret;
        !           538:
        !           539:        ptoup2(ARG0(arg),&t);
        !           540:        ret = irredcheck_dddup2(t);
        !           541:        STOQ(ret,*rp);
        !           542: }
        !           543:
        !           544: void Psetmod_ff(arg,rp)
        !           545: NODE arg;
        !           546: Obj *rp;
        !           547: {
        !           548:        int ac;
        !           549:        Obj mod,defpoly;
        !           550:        N n;
        !           551:        UP up;
        !           552:        UP2 up2;
        !           553:        Q q;
        !           554:        P p;
        !           555:        NODE n0,n1;
        !           556:        LIST list;
        !           557:
        !           558:        ac = argc(arg);
        !           559:        if ( ac == 1 ) {
        !           560:                mod = (Obj)ARG0(arg);
        !           561:                if ( !mod )
        !           562:                        error("setmod_ff : invalid argument");
        !           563:                switch ( OID(mod) ) {
        !           564:                        case O_N:
        !           565:                                current_ff = FF_GFP;
        !           566:                                setmod_lm(NM((Q)mod)); break;
        !           567:                        case O_P:
        !           568:                                current_ff = FF_GF2N;
        !           569:                                setmod_gf2n((P)mod); break;
        !           570:                        default:
        !           571:                                error("setmod_ff : invalid argument");
        !           572:                }
        !           573:        } else if ( ac == 2 ) {
        !           574:                current_ff = FF_GFPN;
        !           575:                defpoly = (Obj)ARG0(arg);
        !           576:                mod = (Obj)ARG1(arg);
        !           577:                if ( !mod || !defpoly )
        !           578:                        error("setmod_ff : invalid argument");
        !           579:                setmod_lm(NM((Q)mod));
        !           580:                setmod_gfpn((P)defpoly);
        !           581:        }
        !           582:        switch ( current_ff ) {
        !           583:                case FF_GFP:
        !           584:                        getmod_lm(&n); NTOQ(n,1,q); *rp = (Obj)q; break;
        !           585:                case FF_GF2N:
        !           586:                        getmod_gf2n(&up2); up2top(up2,&p); *rp = (Obj)p; break;
        !           587:                case FF_GFPN:
        !           588:                        getmod_lm(&n); NTOQ(n,1,q);
        !           589:                        getmod_gfpn(&up); uptop(up,&p);
        !           590:                        MKNODE(n1,q,0); MKNODE(n0,p,n1);
        !           591:                        MKLIST(list,n0);
        !           592:                        *rp = (Obj)list; break;
        !           593:                default:
        !           594:                        *rp = 0; break;
        !           595:        }
        !           596: }
        !           597:
        !           598: void Pextdeg_ff(rp)
        !           599: Q *rp;
        !           600: {
        !           601:        int d;
        !           602:        UP2 up2;
        !           603:        UP up;
        !           604:
        !           605:        switch ( current_ff ) {
        !           606:                case FF_GFP:
        !           607:                        *rp = ONE; break;
        !           608:                case FF_GF2N:
        !           609:                        getmod_gf2n(&up2); d = degup2(up2); STOQ(d,*rp); break;
        !           610:                case FF_GFPN:
        !           611:                        getmod_gfpn(&up); STOQ(up->d,*rp); break;
        !           612:                default:
        !           613:                        error("extdeg_ff : current_ff is not set");
        !           614:        }
        !           615: }
        !           616:
        !           617: void Pcharacteristic_ff(rp)
        !           618: Q *rp;
        !           619: {
        !           620:        N lm;
        !           621:
        !           622:        switch ( current_ff ) {
        !           623:                case FF_GFP:
        !           624:                case FF_GFPN:
        !           625:                        getmod_lm(&lm); NTOQ(lm,1,*rp); break;
        !           626:                case FF_GF2N:
        !           627:                        STOQ(2,*rp); break;
        !           628:                default:
        !           629:                        error("characteristic_ff : current_ff is not set");
        !           630:        }
        !           631: }
        !           632:
        !           633: void Pfield_type_ff(rp)
        !           634: Q *rp;
        !           635: {
        !           636:        STOQ(current_ff,*rp);
        !           637: }
        !           638:
        !           639: void Pfield_order_ff(rp)
        !           640: Q *rp;
        !           641: {
        !           642:        N n;
        !           643:
        !           644:        field_order_ff(&n);
        !           645:        NTOQ(n,1,*rp);
        !           646: }
        !           647:
        !           648: void field_order_ff(order)
        !           649: N *order;
        !           650: {
        !           651:        UP2 up2;
        !           652:        UP up;
        !           653:        N m;
        !           654:        int d,w;
        !           655:
        !           656:        switch ( current_ff ) {
        !           657:                case FF_GFP:
        !           658:                        getmod_lm(order); break;
        !           659:                case FF_GF2N:
        !           660:                        getmod_gf2n(&up2); d = degup2(up2);
        !           661:                        w = (d>>5)+1;
        !           662:                        *order = m = NALLOC(w);
        !           663:                        PL(m)=w;
        !           664:                        bzero((char *)BD(m),w*sizeof(unsigned int));
        !           665:                        BD(m)[d>>5] |= 1<<(d&31);
        !           666:                        break;
        !           667:                case FF_GFPN:
        !           668:                        getmod_lm(&m);
        !           669:                        getmod_gfpn(&up); pwrn(m,up->d,order); break;
        !           670:                default:
        !           671:                        error("field_order_ff : current_ff is not set");
        !           672:        }
        !           673: }
        !           674:
        !           675: void Prandom_ff(rp)
        !           676: Obj *rp;
        !           677: {
        !           678:        LM l;
        !           679:        GF2N g;
        !           680:        GFPN p;
        !           681:
        !           682:        switch ( current_ff ) {
        !           683:                case FF_GFP:
        !           684:                        random_lm(&l); *rp = (Obj)l; break;
        !           685:                case FF_GF2N:
        !           686:                        randomgf2n(&g); *rp = (Obj)g; break;
        !           687:                case FF_GFPN:
        !           688:                        randomgfpn(&p); *rp = (Obj)p; break;
        !           689:                default:
        !           690:                        error("random_ff : current_ff is not set");
        !           691:        }
        !           692: }
        !           693:
        !           694: void Psimp_ff(arg,rp)
        !           695: NODE arg;
        !           696: Obj *rp;
        !           697: {
        !           698:        LM r;
        !           699:        GF2N rg;
        !           700:        extern lm_lazy;
        !           701:
        !           702:        simp_ff((Obj)ARG0(arg),rp);
        !           703: }
        !           704:
        !           705: void simp_ff(p,rp)
        !           706: Obj p;
        !           707: Obj *rp;
        !           708: {
        !           709:        Num n;
        !           710:        LM r,s;
        !           711:        DCP dc,dcr0,dcr;
        !           712:        GF2N rg,sg;
        !           713:        GFPN rpn,spn;
        !           714:        P t;
        !           715:        Obj obj;
        !           716:
        !           717:        lm_lazy = 0;
        !           718:        if ( !p )
        !           719:                *rp = 0;
        !           720:        else if ( OID(p) == O_N ) {
        !           721:                switch ( current_ff ) {
        !           722:                        case FF_GFP:
        !           723:                                ptolmp((P)p,&t); simplm((LM)t,&s); *rp = (Obj)s;
        !           724:                                break;
        !           725:                        case FF_GF2N:
        !           726:                                ptogf2n((Obj)p,&rg); simpgf2n((GF2N)rg,&sg); *rp = (Obj)sg;
        !           727:                                break;
        !           728:                        case FF_GFPN:
        !           729:                                ntogfpn((Obj)p,&rpn); simpgfpn((GFPN)rpn,&spn); *rp = (Obj)spn;
        !           730:                                break;
        !           731:                        default:
        !           732:                                *rp = (Obj)p;
        !           733:                                break;
        !           734:                }
        !           735:        } else if ( OID(p) == O_P ) {
        !           736:                for ( dc = DC((P)p), dcr0 = 0; dc; dc = NEXT(dc) ) {
        !           737:                        simp_ff((Obj)COEF(dc),&obj);
        !           738:                        if ( obj ) {
        !           739:                                NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = (P)obj;
        !           740:                        }
        !           741:                }
        !           742:                if ( !dcr0 )
        !           743:                        *rp = 0;
        !           744:                else {
        !           745:                        NEXT(dcr) = 0; MKP(VR((P)p),dcr0,t); *rp = (Obj)t;
        !           746:                }
        !           747:        } else
        !           748:                error("simp_ff : not implemented yet");
        !           749: }
        !           750:
        !           751: void getcoef(vl,p,v,d,r)
        !           752: VL vl;
        !           753: P p;
        !           754: V v;
        !           755: Q d;
        !           756: P *r;
        !           757: {
        !           758:        P s,t,u,a,b,x;
        !           759:        DCP dc;
        !           760:        V w;
        !           761:
        !           762:        if ( !p )
        !           763:                *r = 0;
        !           764:        else if ( NUM(p) )
        !           765:                *r = d ? 0 : p;
        !           766:        else if ( (w=VR(p)) == v ) {
        !           767:                for ( dc = DC(p); dc && cmpq(DEG(dc),d); dc = NEXT(dc) );
        !           768:                *r = dc ? COEF(dc) : 0;
        !           769:        } else {
        !           770:                MKV(w,x);
        !           771:                for ( dc = DC(p), s = 0; dc; dc = NEXT(dc) ) {
        !           772:                        getcoef(vl,COEF(dc),v,d,&t);
        !           773:                        if ( t ) {
        !           774:                                pwrp(vl,x,DEG(dc),&u); mulp(vl,t,u,&a);
        !           775:                                addp(vl,s,a,&b); s = b;
        !           776:                        }
        !           777:                }
        !           778:                *r = s;
        !           779:        }
        !           780: }
        !           781:
        !           782: void Pdeglist(arg,rp)
        !           783: NODE arg;
        !           784: LIST *rp;
        !           785: {
        !           786:        NODE d;
        !           787:
        !           788:        getdeglist((P)ARG0(arg),VR((P)ARG1(arg)),&d);
        !           789:        MKLIST(*rp,d);
        !           790: }
        !           791:
        !           792: void Pch_mv(arg,rp)
        !           793: NODE arg;
        !           794: P *rp;
        !           795: {
        !           796:        change_mvar(CO,(P)ARG0(arg),VR((P)ARG1(arg)),rp);
        !           797: }
        !           798:
        !           799: void Pre_mv(arg,rp)
        !           800: NODE arg;
        !           801: P *rp;
        !           802: {
        !           803:        restore_mvar(CO,(P)ARG0(arg),VR((P)ARG1(arg)),rp);
        !           804: }
        !           805:
        !           806: void change_mvar(vl,p,v,r)
        !           807: VL vl;
        !           808: P p;
        !           809: V v;
        !           810: P *r;
        !           811: {
        !           812:        Q d;
        !           813:        DCP dc,dc0;
        !           814:        NODE dl;
        !           815:
        !           816:        if ( !p || NUM(p) || (VR(p) == v) )
        !           817:                *r = p;
        !           818:        else {
        !           819:                getdeglist(p,v,&dl);
        !           820:                for ( dc0 = 0; dl; dl = NEXT(dl) ) {
        !           821:                        NEXTDC(dc0,dc); DEG(dc) = d = (Q)BDY(dl);
        !           822:                        getcoef(vl,p,v,d,&COEF(dc));
        !           823:                }
        !           824:                NEXT(dc) = 0; MKP(v,dc0,*r);
        !           825:        }
        !           826: }
        !           827:
        !           828: void restore_mvar(vl,p,v,r)
        !           829: VL vl;
        !           830: P p;
        !           831: V v;
        !           832: P *r;
        !           833: {
        !           834:        P s,u,a,b,x;
        !           835:        DCP dc;
        !           836:
        !           837:        if ( !p || NUM(p) || (VR(p) != v) )
        !           838:                *r = p;
        !           839:        else {
        !           840:                MKV(v,x);
        !           841:                for ( dc = DC(p), s = 0; dc; dc = NEXT(dc) ) {
        !           842:                        pwrp(vl,x,DEG(dc),&u); mulp(vl,COEF(dc),u,&a);
        !           843:                        addp(vl,s,a,&b); s = b;
        !           844:                }
        !           845:                *r = s;
        !           846:        }
        !           847: }
        !           848:
        !           849: void getdeglist(p,v,d)
        !           850: P p;
        !           851: V v;
        !           852: NODE *d;
        !           853: {
        !           854:        NODE n,n0,d0,d1,d2;
        !           855:        DCP dc;
        !           856:
        !           857:        if ( !p || NUM(p) ) {
        !           858:                MKNODE(n,0,0); *d = n;
        !           859:        } else if ( VR(p) == v ) {
        !           860:                for ( n0 = 0, dc = DC(p); dc; dc = NEXT(dc) ) {
        !           861:                        NEXTNODE(n0,n); BDY(n) = (pointer)DEG(dc);
        !           862:                }
        !           863:                NEXT(n) = 0; *d = n0;
        !           864:        } else {
        !           865:                for ( dc = DC(p), d0 = 0; dc; dc = NEXT(dc) ) {
        !           866:                        getdeglist(COEF(dc),v,&d1); mergedeglist(d0,d1,&d2); d0 = d2;
        !           867:                }
        !           868:                *d = d0;
        !           869:        }
        !           870: }
        !           871: void Pmergelist(arg,rp)
        !           872: NODE arg;
        !           873: LIST *rp;
        !           874: {
        !           875:     NODE n;
        !           876:
        !           877:        asir_assert(ARG0(arg),O_LIST,"mergelist");
        !           878:        asir_assert(ARG1(arg),O_LIST,"mergelist");
        !           879:        mergedeglist(BDY((LIST)ARG0(arg)),BDY((LIST)ARG1(arg)),&n);
        !           880:        MKLIST(*rp,n);
        !           881: }
        !           882:
        !           883: void mergedeglist(d0,d1,dr)
        !           884: NODE d0,d1,*dr;
        !           885: {
        !           886:        NODE t0,t,dt;
        !           887:        Q d;
        !           888:        int c;
        !           889:
        !           890:        if ( !d0 )
        !           891:                *dr = d1;
        !           892:        else {
        !           893:                while ( d1 ) {
        !           894:                        dt = d1; d1 = NEXT(d1); d = (Q)BDY(dt);
        !           895:                        for ( t0 = 0, t = d0; t; t0 = t, t = NEXT(t) ) {
        !           896:                                c = cmpq(d,(Q)BDY(t));
        !           897:                                if ( !c )
        !           898:                                        break;
        !           899:                                else if ( c > 0 ) {
        !           900:                                        if ( !t0 ) {
        !           901:                                                NEXT(dt) = d0; d0 = dt;
        !           902:                                        } else {
        !           903:                                                NEXT(t0) = dt; NEXT(dt) = t;
        !           904:                                        }
        !           905:                                        break;
        !           906:                                }
        !           907:                        }
        !           908:                        if ( !t ) {
        !           909:                                NEXT(t0) = dt; *dr = d0; return;
        !           910:                        }
        !           911:                }
        !           912:                *dr = d0;
        !           913:        }
        !           914: }
        !           915:
        !           916: void Pptomp(arg,rp)
        !           917: NODE arg;
        !           918: P *rp;
        !           919: {
        !           920:        ptomp(QTOS((Q)ARG1(arg)),(P)ARG0(arg),rp);
        !           921: }
        !           922:
        !           923: void Pmptop(arg,rp)
        !           924: NODE arg;
        !           925: P *rp;
        !           926: {
        !           927:        mptop((P)ARG0(arg),rp);
        !           928: }
        !           929:
        !           930: void Pptolmp(arg,rp)
        !           931: NODE arg;
        !           932: P *rp;
        !           933: {
        !           934:        ptolmp((P)ARG0(arg),rp);
        !           935: }
        !           936:
        !           937: void Plmptop(arg,rp)
        !           938: NODE arg;
        !           939: P *rp;
        !           940: {
        !           941:        lmptop((P)ARG0(arg),rp);
        !           942: }
        !           943:
        !           944: void Pptogf2n(arg,rp)
        !           945: NODE arg;
        !           946: GF2N *rp;
        !           947: {
        !           948:        ptogf2n((Obj)ARG0(arg),rp);
        !           949: }
        !           950:
        !           951: void Pgf2ntop(arg,rp)
        !           952: NODE arg;
        !           953: P *rp;
        !           954: {
        !           955:        extern V up2_var;
        !           956:
        !           957:        if ( argc(arg) == 2 )
        !           958:                up2_var = VR((P)ARG1(arg));
        !           959:        gf2ntop((GF2N)ARG0(arg),rp);
        !           960: }
        !           961:
        !           962: void Pgf2ntovect(arg,rp)
        !           963: NODE arg;
        !           964: VECT *rp;
        !           965: {
        !           966:        gf2ntovect((GF2N)ARG0(arg),rp);
        !           967: }
        !           968:
        !           969: void Pptogfpn(arg,rp)
        !           970: NODE arg;
        !           971: GF2N *rp;
        !           972: {
        !           973:        ptogfpn((Obj)ARG0(arg),rp);
        !           974: }
        !           975:
        !           976: void Pgfpntop(arg,rp)
        !           977: NODE arg;
        !           978: P *rp;
        !           979: {
        !           980:        extern V up_var;
        !           981:
        !           982:        if ( argc(arg) == 2 )
        !           983:                up_var = VR((P)ARG1(arg));
        !           984:        gfpntop((GFPN)ARG0(arg),rp);
        !           985: }
        !           986:
        !           987: void Pureverse(arg,rp)
        !           988: NODE arg;
        !           989: P *rp;
        !           990: {
        !           991:        UP p,r;
        !           992:
        !           993:        ptoup((P)ARG0(arg),&p);
        !           994:        reverseup(p,p->d,&r);
        !           995:        uptop(r,rp);
        !           996: }
        !           997:
        !           998: void Putrunc(arg,rp)
        !           999: NODE arg;
        !          1000: P *rp;
        !          1001: {
        !          1002:        UP p,r;
        !          1003:
        !          1004:        ptoup((P)ARG0(arg),&p);
        !          1005:        truncup(p,QTOS((Q)ARG1(arg))+1,&r);
        !          1006:        uptop(r,rp);
        !          1007: }
        !          1008:
        !          1009: void Pudecomp(arg,rp)
        !          1010: NODE arg;
        !          1011: LIST *rp;
        !          1012: {
        !          1013:        P u,l;
        !          1014:        UP p,up,low;
        !          1015:        NODE n0,n1;
        !          1016:
        !          1017:        ptoup((P)ARG0(arg),&p);
        !          1018:        decompup(p,QTOS((Q)ARG1(arg))+1,&low,&up);
        !          1019:        uptop(low,&l);
        !          1020:        uptop(up,&u);
        !          1021:        MKNODE(n1,u,0); MKNODE(n0,l,n1);
        !          1022:        MKLIST(*rp,n0);
        !          1023: }
        !          1024:
        !          1025: void Purembymul(arg,rp)
        !          1026: NODE arg;
        !          1027: P *rp;
        !          1028: {
        !          1029:        UP p1,p2,r;
        !          1030:
        !          1031:        if ( !ARG0(arg) || !ARG1(arg) )
        !          1032:                *rp = 0;
        !          1033:        else {
        !          1034:                ptoup((P)ARG0(arg),&p1);
        !          1035:                ptoup((P)ARG1(arg),&p2);
        !          1036:                rembymulup(p1,p2,&r);
        !          1037:                uptop(r,rp);
        !          1038:        }
        !          1039: }
        !          1040:
        !          1041: /*
        !          1042:  * d1 = deg(p1), d2 = deg(p2)
        !          1043:  * d1 <= 2*d2-1
        !          1044:  * p2*inv = 1 mod x^d2
        !          1045:  */
        !          1046:
        !          1047: void Purembymul_precomp(arg,rp)
        !          1048: NODE arg;
        !          1049: P *rp;
        !          1050: {
        !          1051:        UP p1,p2,inv,r;
        !          1052:
        !          1053:        if ( !ARG0(arg) || !ARG1(arg) )
        !          1054:                *rp = 0;
        !          1055:        else {
        !          1056:                ptoup((P)ARG0(arg),&p1);
        !          1057:                ptoup((P)ARG1(arg),&p2);
        !          1058:                ptoup((P)ARG2(arg),&inv);
        !          1059:                if ( p1->d >= 2*p2->d ) {
        !          1060:                        error("urembymul_precomp : degree of 1st arg is too large");
        !          1061: /*                     fprintf(stderr,"urembymul_precomp : degree of 1st arg is too large"); */
        !          1062:                        remup(p1,p2,&r);
        !          1063:                } else
        !          1064:                        hybrid_rembymulup_special(current_ff,p1,p2,inv,&r);
        !          1065:                uptop(r,rp);
        !          1066:        }
        !          1067: }
        !          1068:
        !          1069: void Puinvmod(arg,rp)
        !          1070: NODE arg;
        !          1071: P *rp;
        !          1072: {
        !          1073:        UP p,r;
        !          1074:
        !          1075:        ptoup((P)ARG0(arg),&p);
        !          1076:        invmodup(p,QTOS((Q)ARG1(arg)),&r);
        !          1077:        uptop(r,rp);
        !          1078: }
        !          1079:
        !          1080: void Purevinvmod(arg,rp)
        !          1081: NODE arg;
        !          1082: P *rp;
        !          1083: {
        !          1084:        UP p,pr,r;
        !          1085:
        !          1086:        ptoup((P)ARG0(arg),&p);
        !          1087:        reverseup(p,p->d,&pr);
        !          1088:        invmodup(pr,QTOS((Q)ARG1(arg)),&r);
        !          1089:        uptop(r,rp);
        !          1090: }
        !          1091:
        !          1092: void Ppwrmod_ff(arg,rp)
        !          1093: NODE arg;
        !          1094: P *rp;
        !          1095: {
        !          1096:        UP p1,p2;
        !          1097:
        !          1098:        ptoup((P)ARG0(arg),&p1);
        !          1099:        switch ( current_ff ) {
        !          1100:                case FF_GFP:
        !          1101:                        hybrid_powermodup(p1,&p2); break;
        !          1102:                case FF_GF2N:
        !          1103:                        powermodup_gf2n(p1,&p2); break;
        !          1104:                case FF_GFPN:
        !          1105:                        powermodup(p1,&p2); break;
        !          1106:                default:
        !          1107:                        error("pwrmod_ff : current_ff is not set");
        !          1108:        }
        !          1109:        uptop(p2,rp);
        !          1110: }
        !          1111:
        !          1112: void Pgeneric_pwrmod_ff(arg,rp)
        !          1113: NODE arg;
        !          1114: P *rp;
        !          1115: {
        !          1116:        UP g,f,r;
        !          1117:
        !          1118:        ptoup((P)ARG0(arg),&g);
        !          1119:        ptoup((P)ARG1(arg),&f);
        !          1120:        switch ( current_ff ) {
        !          1121:                case FF_GFP:
        !          1122:                        hybrid_generic_powermodup(g,f,(Q)ARG2(arg),&r); break;
        !          1123:                case FF_GF2N:
        !          1124:                        generic_powermodup_gf2n(g,f,(Q)ARG2(arg),&r); break;
        !          1125:                case FF_GFPN:
        !          1126:                        generic_powermodup(g,f,(Q)ARG2(arg),&r); break;
        !          1127:                default:
        !          1128:                        error("generic_pwrmod_ff : current_ff is not set");
        !          1129:        }
        !          1130:        uptop(r,rp);
        !          1131: }
        !          1132:
        !          1133: void Ppwrtab_ff(arg,rp)
        !          1134: NODE arg;
        !          1135: VECT *rp;
        !          1136: {
        !          1137:        UP f,xp;
        !          1138:        UP *tab;
        !          1139:        VECT r;
        !          1140:        int i,d;
        !          1141:
        !          1142:        ptoup((P)ARG0(arg),&f);
        !          1143:        ptoup((P)ARG1(arg),&xp);
        !          1144:        d = f->d;
        !          1145:
        !          1146:        tab = (UP *)ALLOCA(d*sizeof(UP));
        !          1147:        switch ( current_ff ) {
        !          1148:                case FF_GFP:
        !          1149:                        hybrid_powertabup(f,xp,tab); break;
        !          1150:                case FF_GF2N:
        !          1151:                        powertabup_gf2n(f,xp,tab); break;
        !          1152:                case FF_GFPN:
        !          1153:                        powertabup(f,xp,tab); break;
        !          1154:                default:
        !          1155:                        error("pwrtab_ff : current_ff is not set");
        !          1156:        }
        !          1157:        MKVECT(r,d); *rp = r;
        !          1158:        for ( i = 0; i < d; i++ )
        !          1159:                uptop(tab[i],(P *)&BDY(r)[i]);
        !          1160: }
        !          1161:
        !          1162: void Pkpwrmod_lm(arg,rp)
        !          1163: NODE arg;
        !          1164: P *rp;
        !          1165: {
        !          1166:        UP p1,p2;
        !          1167:
        !          1168:        ptoup((P)ARG0(arg),&p1);
        !          1169:        powermodup(p1,&p2);
        !          1170:        uptop(p2,rp);
        !          1171: }
        !          1172:
        !          1173: void Pkgeneric_pwrmod_lm(arg,rp)
        !          1174: NODE arg;
        !          1175: P *rp;
        !          1176: {
        !          1177:        UP g,f,r;
        !          1178:
        !          1179:        ptoup((P)ARG0(arg),&g);
        !          1180:        ptoup((P)ARG1(arg),&f);
        !          1181:        generic_powermodup(g,f,(Q)ARG2(arg),&r);
        !          1182:        uptop(r,rp);
        !          1183: }
        !          1184:
        !          1185: void Pkpwrtab_lm(arg,rp)
        !          1186: NODE arg;
        !          1187: VECT *rp;
        !          1188: {
        !          1189:        UP f,xp;
        !          1190:        UP *tab;
        !          1191:        VECT r;
        !          1192:        int i,d;
        !          1193:
        !          1194:        ptoup((P)ARG0(arg),&f);
        !          1195:        ptoup((P)ARG1(arg),&xp);
        !          1196:        d = f->d;
        !          1197:
        !          1198:        tab = (UP *)ALLOCA(d*sizeof(UP));
        !          1199:        powertabup(f,xp,tab);
        !          1200:        MKVECT(r,d); *rp = r;
        !          1201:        for ( i = 0; i < d; i++ )
        !          1202:                uptop(tab[i],(P *)&BDY(r)[i]);
        !          1203: }
        !          1204:
        !          1205: void Plazy_lm(arg,rp)
        !          1206: NODE arg;
        !          1207: Q *rp;
        !          1208: {
        !          1209:        lm_lazy = QTOS((Q)ARG0(arg));
        !          1210:        *rp = 0;
        !          1211: }
        !          1212:
        !          1213: void Pkmul(arg,rp)
        !          1214: NODE arg;
        !          1215: P *rp;
        !          1216: {
        !          1217:        P n1,n2;
        !          1218:
        !          1219:        n1 = (P)ARG0(arg); n2 = (P)ARG1(arg);
        !          1220:        asir_assert(n1,O_P,"kmul");
        !          1221:        asir_assert(n2,O_P,"kmul");
        !          1222:        kmulp(CO,n1,n2,rp);
        !          1223: }
        !          1224:
        !          1225: void Pksquare(arg,rp)
        !          1226: NODE arg;
        !          1227: P *rp;
        !          1228: {
        !          1229:        P n1;
        !          1230:
        !          1231:        n1 = (P)ARG0(arg);
        !          1232:        asir_assert(n1,O_P,"ksquare");
        !          1233:        ksquarep(CO,n1,rp);
        !          1234: }
        !          1235:
        !          1236: void Pktmul(arg,rp)
        !          1237: NODE arg;
        !          1238: P *rp;
        !          1239: {
        !          1240:        UP p1,p2,r;
        !          1241:
        !          1242:        ptoup((P)ARG0(arg),&p1);
        !          1243:        ptoup((P)ARG1(arg),&p2);
        !          1244:        tkmulup(p1,p2,QTOS((Q)ARG2(arg))+1,&r);
        !          1245:        uptop(r,rp);
        !          1246: }
        !          1247:
        !          1248: void Pumul(arg,rp)
        !          1249: NODE arg;
        !          1250: P *rp;
        !          1251: {
        !          1252:        P a1,a2;
        !          1253:        UP p1,p2,r;
        !          1254:
        !          1255:        a1 = (P)ARG0(arg); a2 = (P)ARG1(arg);
        !          1256:        if ( !a1 || !a2 || NUM(a1) || NUM(a2) )
        !          1257:                mulp(CO,a1,a2,rp);
        !          1258:        else {
        !          1259:                if ( !uzpcheck(a1) || !uzpcheck(a2) || VR(a1) != VR(a2) )
        !          1260:                        error("umul : invalid argument");
        !          1261:                ptoup(a1,&p1);
        !          1262:                ptoup(a2,&p2);
        !          1263:                hybrid_mulup(0,p1,p2,&r);
        !          1264:                uptop(r,rp);
        !          1265:        }
        !          1266: }
        !          1267:
        !          1268: void Pusquare(arg,rp)
        !          1269: NODE arg;
        !          1270: P *rp;
        !          1271: {
        !          1272:        UP p1,p2,r;
        !          1273:
        !          1274:        ptoup((P)ARG0(arg),&p1);
        !          1275:        hybrid_squareup(0,p1,&r);
        !          1276:        uptop(r,rp);
        !          1277: }
        !          1278:
        !          1279: void Putmul(arg,rp)
        !          1280: NODE arg;
        !          1281: P *rp;
        !          1282: {
        !          1283:        UP p1,p2,r;
        !          1284:
        !          1285:        ptoup((P)ARG0(arg),&p1);
        !          1286:        ptoup((P)ARG1(arg),&p2);
        !          1287:        hybrid_tmulup(0,p1,p2,QTOS((Q)ARG2(arg))+1,&r);
        !          1288:        uptop(r,rp);
        !          1289: }
        !          1290:
        !          1291: void Pumul_ff(arg,rp)
        !          1292: NODE arg;
        !          1293: Obj *rp;
        !          1294: {
        !          1295:        P a1,a2;
        !          1296:        UP p1,p2,r;
        !          1297:        P p;
        !          1298:
        !          1299:        a1 = (P)ARG0(arg); a2 = (P)ARG1(arg);
        !          1300:        ptoup(a1,&p1);
        !          1301:        ptoup(a2,&p2);
        !          1302:        hybrid_mulup(current_ff,p1,p2,&r);
        !          1303:        uptop(r,&p);
        !          1304:        simp_ff((Obj)p,rp);
        !          1305: }
        !          1306:
        !          1307: void Pusquare_ff(arg,rp)
        !          1308: NODE arg;
        !          1309: Obj *rp;
        !          1310: {
        !          1311:        UP p1,p2,r;
        !          1312:        P p;
        !          1313:
        !          1314:        ptoup((P)ARG0(arg),&p1);
        !          1315:        hybrid_squareup(current_ff,p1,&r);
        !          1316:        uptop(r,&p);
        !          1317:        simp_ff((Obj)p,rp);
        !          1318: }
        !          1319:
        !          1320: void Putmul_ff(arg,rp)
        !          1321: NODE arg;
        !          1322: Obj *rp;
        !          1323: {
        !          1324:        UP p1,p2,r;
        !          1325:        P p;
        !          1326:
        !          1327:        ptoup((P)ARG0(arg),&p1);
        !          1328:        ptoup((P)ARG1(arg),&p2);
        !          1329:        hybrid_tmulup(current_ff,p1,p2,QTOS((Q)ARG2(arg))+1,&r);
        !          1330:        uptop(r,&p);
        !          1331:        simp_ff((Obj)p,rp);
        !          1332: }
        !          1333:
        !          1334: void Phfmul_lm(arg,rp)
        !          1335: NODE arg;
        !          1336: P *rp;
        !          1337: {
        !          1338:        UP p1,p2,r;
        !          1339:        UP hi,lo,mid,t,s,p10,p11,p20,p21;
        !          1340:        unsigned int m,d;
        !          1341:        int i;
        !          1342:
        !          1343:        ptoup((P)ARG0(arg),&p1);
        !          1344:        ptoup((P)ARG1(arg),&p2);
        !          1345:        d = MAX(p1->d,p2->d);
        !          1346:        for ( m = 1; m < d; m <<= 1 );
        !          1347:        if ( m > d )
        !          1348:                m >>= 1;
        !          1349:        if ( d-m < 10000 ) {
        !          1350:                decompup(p1,m,&p10,&p11); /* p1 = p11*x^m+p10 */
        !          1351:                decompup(p2,m,&p20,&p21); /* p2 = p21*x^m+p20 */
        !          1352:                fft_mulup_lm(p10,p20,&lo);
        !          1353:                kmulup(p11,p21,&hi);
        !          1354:                kmulup(p11,p20,&t); kmulup(p10,p21,&s); addup(t,s,&mid);
        !          1355:                r = UPALLOC(2*d);
        !          1356:                bzero((char *)COEF(r),(2*d+1)*sizeof(Num));
        !          1357:                if ( lo )
        !          1358:                        bcopy((char *)COEF(lo),(char *)COEF(r),(DEG(lo)+1)*sizeof(Num));
        !          1359:                if ( hi )
        !          1360:                        bcopy((char *)COEF(hi),(char *)(COEF(r)+2*m),(DEG(hi)+1)*sizeof(Num));
        !          1361:                for ( i = 2*d; i >= 0 && !COEF(r)[i]; i-- );
        !          1362:                if ( i < 0 )
        !          1363:                        r = 0;
        !          1364:                else {
        !          1365:                        DEG(r) = i;
        !          1366:                        t = UPALLOC(DEG(mid)+m); DEG(t) = DEG(mid)+m;
        !          1367:                        bzero((char *)COEF(t),(DEG(mid)+m+1)*sizeof(Num));
        !          1368:                        bcopy((char *)COEF(mid),(char *)(COEF(t)+m),(DEG(mid)+1)*sizeof(Num));
        !          1369:                        addup(t,r,&s);
        !          1370:                        r = s;
        !          1371:                }
        !          1372:        } else
        !          1373:                fft_mulup_lm(p1,p2,&r);
        !          1374:        uptop(r,rp);
        !          1375: }
        !          1376:
        !          1377: void Pfmultest(arg,rp)
        !          1378: NODE arg;
        !          1379: LIST *rp;
        !          1380: {
        !          1381:        P p1,p2,r;
        !          1382:        int d1,d2;
        !          1383:        UM w1,w2,wr;
        !          1384:        unsigned int *f1,*f2,*fr,*w;
        !          1385:        int index,mod,root,d,maxint,i;
        !          1386:        int cond;
        !          1387:        Q prime;
        !          1388:        NODE n0,n1;
        !          1389:
        !          1390:        p1 = (P)ARG0(arg); p2 = (P)ARG1(arg); index = QTOS((Q)ARG2(arg));
        !          1391:        FFT_primes(index,&mod,&root,&d);
        !          1392:        maxint = 1<<d;
        !          1393:        d1 = UDEG(p1); d2 = UDEG(p2);
        !          1394:        if ( maxint < d1+d2+1 )
        !          1395:                *rp = 0;
        !          1396:        else {
        !          1397:                w1 = W_UMALLOC(d1); w2 = W_UMALLOC(d2);
        !          1398:                wr = W_UMALLOC(d1+d2);
        !          1399:                ptoum(mod,p1,w1); ptoum(mod,p2,w2);
        !          1400:                f1 = (unsigned int *)ALLOCA(maxint*sizeof(unsigned int));
        !          1401:                f2 = (unsigned int *)ALLOCA(maxint*sizeof(unsigned int));
        !          1402:                fr = (unsigned int *)ALLOCA(maxint*sizeof(unsigned int));
        !          1403:                w = (unsigned int *)ALLOCA(12*maxint*sizeof(unsigned int));
        !          1404:
        !          1405:                for ( i = 0; i <= d1; i++ )
        !          1406:                        f1[i] = (unsigned int)w1->c[i];
        !          1407:                for ( i = 0; i <= d2; i++ )
        !          1408:                        f2[i] = (unsigned int)w2->c[i];
        !          1409:
        !          1410:                cond = FFT_pol_product(d1,f1,d2,f2,fr,index,w);
        !          1411:                if ( cond )
        !          1412:                        error("fmultest : ???");
        !          1413:                wr->d = d1+d2;
        !          1414:                for ( i = 0; i <= d1+d2; i++ )
        !          1415:                        wr->c[i] = (unsigned int)fr[i];
        !          1416:                umtop(VR(p1),wr,&r);
        !          1417:                STOQ(mod,prime);
        !          1418:                MKNODE(n1,prime,0);
        !          1419:                MKNODE(n0,r,n1);
        !          1420:                MKLIST(*rp,n0);
        !          1421:        }
        !          1422: }
        !          1423:
        !          1424: void Pkmulum(arg,rp)
        !          1425: NODE arg;
        !          1426: P *rp;
        !          1427: {
        !          1428:        P p1,p2;
        !          1429:        int d1,d2,mod;
        !          1430:        UM w1,w2,wr;
        !          1431:
        !          1432:        p1 = (P)ARG0(arg); p2 = (P)ARG1(arg); mod = QTOS((Q)ARG2(arg));
        !          1433:        d1 = UDEG(p1); d2 = UDEG(p2);
        !          1434:        w1 = W_UMALLOC(d1); w2 = W_UMALLOC(d2);
        !          1435:        wr = W_UMALLOC(d1+d2);
        !          1436:        ptoum(mod,p1,w1); ptoum(mod,p2,w2);
        !          1437:        kmulum(mod,w1,w2,wr);
        !          1438:        umtop(VR(p1),wr,rp);
        !          1439: }
        !          1440:
        !          1441: void Pksquareum(arg,rp)
        !          1442: NODE arg;
        !          1443: P *rp;
        !          1444: {
        !          1445:        P p1;
        !          1446:        int d1,mod;
        !          1447:        UM w1,wr;
        !          1448:
        !          1449:        p1 = (P)ARG0(arg); mod = QTOS((Q)ARG1(arg));
        !          1450:        d1 = UDEG(p1);
        !          1451:        w1 = W_UMALLOC(d1);
        !          1452:        wr = W_UMALLOC(2*d1);
        !          1453:        ptoum(mod,p1,w1);
        !          1454:        kmulum(mod,w1,w1,wr);
        !          1455:        umtop(VR(p1),wr,rp);
        !          1456: }
        !          1457:
        !          1458: void Ptracemod_gf2n(arg,rp)
        !          1459: NODE arg;
        !          1460: P *rp;
        !          1461: {
        !          1462:        UP g,f,r;
        !          1463:
        !          1464:        ptoup((P)ARG0(arg),&g);
        !          1465:        ptoup((P)ARG1(arg),&f);
        !          1466:        tracemodup_gf2n(g,f,(Q)ARG2(arg),&r);
        !          1467:        uptop(r,rp);
        !          1468: }

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