[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

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>