[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.3

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

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