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

Annotation of OpenXM_contrib2/asir2000/engine/D.c, Revision 1.1.1.1

1.1       noro        1: /* $OpenXM: OpenXM/src/asir99/engine/D.c,v 1.1.1.1 1999/11/10 08:12:26 noro Exp $ */
                      2: #include "ca.h"
                      3:
                      4: void dtest(f,list,hint,dcp)
                      5: P f;
                      6: ML list;
                      7: int hint;
                      8: DCP *dcp;
                      9: {
                     10:        int n,np,bound,q;
                     11:        int i,j,k;
                     12:        int *win;
                     13:        P g,factor,cofactor;
                     14:        Q csum,csumt;
                     15:        DCP dcf,dcf0;
                     16:        LUM *c;
                     17:        ML wlist;
                     18:        int z;
                     19:
                     20:        n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
                     21:        win = W_ALLOC(np+1);
                     22:        ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
                     23:        wlist = W_MLALLOC(np); wlist->n = list->n;
                     24:        wlist->mod = list->mod; wlist->bound = list->bound;
                     25:        c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
                     26:        for ( g = f, k = 1, dcf = dcf0 = 0, win[0] = 1, --np, z = 0; ; ) {
                     27: #if 0
                     28:                if ( !(++z % 10000) )
                     29:                        fprintf(stderr,"z=%d\n",z);
                     30: #endif
                     31:                if ( degtest(k,win,wlist,hint) &&
                     32:                        dtestmain(g,csum,wlist,k,win,&factor,&cofactor) ) {
                     33:                        NEXTDC(dcf0,dcf); DEG(dcf) = ONE; COEF(dcf) = factor;
                     34:                        g = cofactor;
                     35:                        ucsump(g,&csum); mulq(csum,(Q)COEF(DC(g)),&csumt); csum = csumt;
                     36:                        for ( i = 0; i < k - 1; i++ )
                     37:                                for ( j = win[i] + 1; j < win[i + 1]; j++ )
                     38:                                        c[j-i-1] = c[j];
                     39:                        for ( j = win[k-1] + 1; j <= np; j++ )
                     40:                                        c[j-k] = c[j];
                     41:                        if ( ( np -= k ) < k )
                     42:                                break;
                     43:                        if ( np - win[0] + 1 < k )
                     44:                                if ( ++k > np )
                     45:                                        break;
                     46:                                else
                     47:                                        for ( i = 0; i < k; i++ )
                     48:                                                win[i] = i + 1;
                     49:                        else
                     50:                                for ( i = 1; i < k; i++ )
                     51:                                        win[i] = win[0] + i;
                     52:                } else if ( !ncombi(1,np,k,win) )
                     53:                        if ( k == np )
                     54:                                break;
                     55:                        else
                     56:                                for ( i = 0, ++k; i < k; i++ )
                     57:                                        win[i] = i + 1;
                     58:        }
                     59:        NEXTDC(dcf0,dcf); COEF(dcf) = g;
                     60:        DEG(dcf) = ONE; NEXT(dcf) = 0;*dcp = dcf0;
                     61: }
                     62:
                     63: void dtestsql(f,list,dc,dcp)
                     64: P f;
                     65: ML list;
                     66: struct oDUM *dc;
                     67: DCP *dcp;
                     68: {
                     69:        int j,n,m,b;
                     70:        P t,s,fq,fr;
                     71:        P *true;
                     72:        Q tq;
                     73:        LUM *c;
                     74:        DCP dcr,dcr0;
                     75:
                     76:        n = list->n; m = list->mod; b = list->bound; c = (LUM *)list->c;
                     77:        true = (P*)ALLOCA(n*sizeof(P));
                     78:        for ( j = 0; j < n; j++ ) {
                     79:                dtestsq(m,b,f,c[j],&t);
                     80:                if ( t )
                     81:                        true[j] = t;
                     82:                else {
                     83:                        *dcp = 0;
                     84:                        return;
                     85:                }
                     86:        }
                     87:        for ( t = f, j = 0; j < n; j++ ) {
                     88:                STOQ(dc[j].n,tq); pwrp(CO,true[j],tq,&s); udivpz(t,s,&fq,&fr);
                     89:                if ( fq && !fr )
                     90:                        t = fq;
                     91:                else {
                     92:                        *dcp = 0;
                     93:                        return;
                     94:                }
                     95:        }
                     96:        for ( j = 0, dcr = dcr0 = 0; j < n; j++ ) {
                     97:                NEXTDC(dcr0,dcr); STOQ(dc[j].n,DEG(dcr)); COEF(dcr) = true[j];
                     98:        }
                     99:        NEXT(dcr) = 0; *dcp = dcr0;
                    100: }
                    101:
                    102: void dtestsq(q,bound,f,fl,g)
                    103: int q,bound;
                    104: P f;
                    105: LUM fl;
                    106: P *g;
                    107: {
                    108:        P lcf,t,fq,fr,s;
                    109:        struct oML list;
                    110:        int in = 0;
                    111:
                    112:        list.n = 1;
                    113:        list.mod = q;
                    114:        list.bound = bound;
                    115:        list.c[0] = (pointer)fl;
                    116:
                    117:        mullumarray(f,&list,1,&in,&t); mulp(CO,f,COEF(DC(f)),&lcf);
                    118:        udivpz(lcf,t,&fq,&fr);
                    119:        if( fq && !fr )
                    120:                ptozp(t,1,(Q *)&s,g);
                    121:        else
                    122:                *g = 0;
                    123: }
                    124:
                    125: void dtestroot(m,b,f,fl,dc,dcp)
                    126: int m,b;
                    127: P f;
                    128: LUM fl;
                    129: struct oDUM *dc;
                    130: DCP *dcp;
                    131: {
                    132:        P t,s,u;
                    133:        DCP dcr;
                    134:        Q q;
                    135:
                    136:        dtestroot1(m,b,f,fl,&t);
                    137:        if ( !t ) {
                    138:                *dcp = 0;
                    139:                return;
                    140:        }
                    141:        STOQ(dc[0].n,q); pwrp(CO,t,q,&s); subp(CO,s,f,&u);
                    142:        if ( u )
                    143:                *dcp = 0;
                    144:        else {
                    145:                NEWDC(dcr); STOQ(dc[0].n,DEG(dcr));
                    146:                COEF(dcr) = t; NEXT(dcr) = 0; *dcp = dcr;
                    147:        }
                    148: }
                    149:
                    150: void dtestroot1(q,bound,f,fl,g)
                    151: int q,bound;
                    152: P f;
                    153: LUM fl;
                    154: P *g;
                    155: {
                    156:        P fq,fr,t;
                    157:
                    158:        lumtop(VR(f),q,bound,fl,&t); udivpz(f,t,&fq,&fr);
                    159:        *g = (fq && !fr) ? t : 0;
                    160: }
                    161:
                    162: int dtestmain(g,csum,list,k,in,fp,cofp)
                    163: P g;
                    164: Q csum;
                    165: ML list;
                    166: int k;
                    167: int *in;
                    168: P *fp,*cofp;
                    169: {
                    170:        int mod;
                    171:        P fmul,lcg;
                    172:        Q csumg;
                    173:        N nq,nr;
                    174:        P fq,fr,t;
                    175:
                    176:        if (!ctest(g,list,k,in))
                    177:                return 0;
                    178:        mod = list->mod;
                    179:        mullumarray(g,list,k,in,&fmul); mulp(CO,g,COEF(DC(g)),&lcg);
                    180:        if ( csum ) {
                    181:                ucsump(fmul,&csumg);
                    182:                if ( csumg ) {
                    183:                        divn(NM(csum),NM(csumg),&nq,&nr);
                    184:                        if ( nr )
                    185:                                return 0;
                    186:                }
                    187:        }
                    188:        udivpz(lcg,fmul,&fq,&fr);
                    189:        if ( fq && !fr ) {
                    190:                ptozp(fq,1,(Q *)&t,cofp); ptozp(fmul,1,(Q *)&t,fp);
                    191:                return 1;
                    192:        } else
                    193:                return 0;
                    194: }
                    195:
                    196: int degtest(k,win,list,hint)
                    197: int k;
                    198: int *win;
                    199: ML list;
                    200: int hint;
                    201: {
                    202:        register int i,d;
                    203:        LUM *c;
                    204:
                    205:        if ( hint == 1 )
                    206:                return 1;
                    207:        for ( c = (LUM*)list->c, i = 0, d = 0; i < k; i++ )
                    208:                d += DEG(c[win[i]]);
                    209:        return !(d % hint);
                    210: }
                    211:
                    212: int ctest(g,list,k,in)
                    213: P g;
                    214: ML list;
                    215: int k;
                    216: int *in;
                    217: {
                    218:        register int i;
                    219:        int q,bound;
                    220:        int *wm,*wm1,*tmpp;
                    221:        DCP dc;
                    222:        Q dvr;
                    223:        N lcn,cstn,dndn,dmyn,rn;
                    224:        LUM *l;
                    225:
                    226:        for ( dc = DC(g); dc && DEG(dc); dc = NEXT(dc) );
                    227:        if ( dc )
                    228:                cstn = NM((Q)COEF(dc));
                    229:        else
                    230:                return 1;
                    231:        q = list->mod; bound = list->bound;
                    232:        ntobn(q,NM((Q)COEF(DC(g))),&lcn);;
                    233:        W_CALLOC(bound+1,int,wm); W_CALLOC(bound+1,int,wm1);
                    234:        for ( i = 0; i < PL(lcn); i++ )
                    235:                wm[i] = BD(lcn)[i];
                    236:        for ( i = 0, l = (LUM *)list->c; i < k; i++ ) {
                    237:                mulpadic(q,bound,wm,COEF(l[in[i]])[0],wm1);
                    238:                tmpp = wm; wm = wm1; wm1 = tmpp;
                    239:        }
                    240:        padictoq(q,bound,wm,&dvr);
                    241:        kmuln(NM((Q)COEF(DC(g))),cstn,&dndn); divn(dndn,NM(dvr),&dmyn,&rn);
                    242:        return rn ? 0 : 1;
                    243: }
                    244:
                    245: /*
                    246: int ncombi(n0,n,k,c)
                    247: int n0,n,k,*c;
                    248: {
                    249:        register int i,tmp;
                    250:
                    251:        if ( !k )
                    252:                return 0;
                    253:        if ( !ncombi(c[1],n,k-1,c+1) ) {
                    254:                if ( c[0] + k > n )
                    255:                        return 0;
                    256:                else {
                    257:                        for ( i = 0, tmp = c[0]; i < k; i++ )
                    258:                                c[i] = tmp + i + 1;
                    259:                        return 1;
                    260:                }
                    261:        } else
                    262:                return 1;
                    263: }
                    264: */
                    265:
                    266: int ncombi(n0,n,k,c)
                    267: int n0,n,k,*c;
                    268: {
                    269:        register int i,t;
                    270:
                    271:        if ( !k )
                    272:                return 0;
                    273:        for ( i = k-1; i >= 0 && c[i] == n+i-(k-1); i-- );
                    274:        if ( i < 0 )
                    275:                return 0;
                    276:        t = ++c[i++];
                    277:        for ( t++ ; i < k; i++, t++ )
                    278:                c[i] = t;
                    279:        return 1;
                    280: }
                    281:
                    282: void nthrootn(number,n,root)
                    283: int n;
                    284: N number,*root;
                    285: {
                    286:        N s,t,u,pn,base,n1,n2,q,r,gcd,num;
                    287:        int sgn,index,p,i,tmp,tp,mlr,num0;
                    288:
                    289:        for (  i = 0; !(n % 2); n /= 2, i++ );
                    290:        for ( index = 0, num = number; ; index++ ) {
                    291:                if ( n == 1 )
                    292:                        goto TAIL;
                    293:                p = lprime[index];
                    294:                if ( !p )
                    295:                        error("nthrootn : lprime[] exhausted.");
                    296:                if ( !(num0 = rem(num,p)) )
                    297:                        continue;
                    298:                STON(n,n1); STON(p-1,n2); gcdn(n1,n2,&gcd);
                    299:                if ( !UNIN(gcd) )
                    300:                        continue;
                    301:                tp = pwrm(p,num0,invm(n,p-1)); STON(tp,s);
                    302:                mlr = invm(dmb(p,n,pwrm(p,tp,n-1),&tmp),p);
                    303:                STON(p,base); STON(p,pn);
                    304:                while ( 1 ) {
                    305:                        pwrn(s,n,&t); sgn = subn(num,t,&u);
                    306:                        if ( !u ) {
                    307:                                num = s;
                    308:                                break;
                    309:                        }
                    310:                        if ( sgn < 0 ) {
                    311:                                *root = 0;
                    312:                                return;
                    313:                        }
                    314:                        divn(u,base,&q,&r);
                    315:                        if ( r ) {
                    316:                                *root = 0;
                    317:                                return;
                    318:                        }
                    319:                        STON(dmb(p,mlr,rem(q,p),&tmp),t);
                    320:                        kmuln(t,base,&u); addn(u,s,&t); s = t;
                    321:                        kmuln(base,pn,&t); base = t;
                    322:                }
                    323: TAIL :
                    324:                for ( ; i; i-- ) {
                    325:                        sqrtn(num,&t);
                    326:                        if ( !t ) {
                    327:                                *root = 0;
                    328:                                return;
                    329:                        }
                    330:                        num = t;
                    331:                }
                    332:                *root = num;
                    333:                return;
                    334:        }
                    335: }
                    336:
                    337: void sqrtn(number,root)
                    338: N number,*root;
                    339: {
                    340:        N a,s,r,q;
                    341:        int sgn;
                    342:
                    343:        for ( a = ONEN; ; ) {
                    344:                divn(number,a,&q,&r); sgn = subn(q,a,&s);
                    345:                if ( !s ) {
                    346:                        *root = !r ? a : 0;
                    347:                        return;
                    348:                } else if ( UNIN(s) ) {
                    349:                        *root = 0;
                    350:                        return;
                    351:                } else {
                    352:                        divin(s,2,&q);
                    353:                        if ( sgn > 0 )
                    354:                                addn(a,q,&r);
                    355:                        else
                    356:                                subn(a,q,&r);
                    357:                        a = r;
                    358:                }
                    359:        }
                    360: }
                    361:
                    362: void lumtop(v,mod,bound,f,g)
                    363: V v;
                    364: int mod;
                    365: int bound;
                    366: LUM f;
                    367: P *g;
                    368: {
                    369:        DCP dc,dc0;
                    370:        int **l;
                    371:        int i;
                    372:        Q q;
                    373:
                    374:        for ( dc0 = NULL, i = DEG(f), l = COEF(f); i >= 0; i-- ) {
                    375:                padictoq(mod,bound,l[i],&q);
                    376:                if ( q ) {
                    377:                        NEXTDC(dc0,dc);
                    378:                        if ( i )
                    379:                                STOQ(i,DEG(dc));
                    380:                        else
                    381:                                DEG(dc) = 0;
                    382:                        COEF(dc) = (P)q;
                    383:                }
                    384:        }
                    385:        if ( !dc0 )
                    386:                *g = 0;
                    387:        else {
                    388:                NEXT(dc) = 0; MKP(v,dc0,*g);
                    389:        }
                    390: }
                    391:
                    392: void padictoq(mod,bound,p,qp)
                    393: int mod,bound,*p;
                    394: Q *qp;
                    395: {
                    396:        register int h,i,t;
                    397:        int br,sgn;
                    398:        unsigned int *ptr;
                    399:        N n,tn;
                    400:        int *c;
                    401:
                    402:        c = W_ALLOC(bound);
                    403:        for ( i = 0; i < bound; i++ )
                    404:                c[i] = p[i];
                    405:        h = (mod%2?(mod-1)/2:mod/2); i = bound - 1;
                    406:        while ( i >= 0 && c[i] == h ) i--;
                    407:        if ( i == -1 || c[i] > h ) {
                    408:                for (i = 0, br = 0; i < bound; i++ )
                    409:                        if ( ( t = -(c[i] + br) ) < 0 ) {
                    410:                                c[i] = t + mod; br = 1;
                    411:                        } else {
                    412:                                c[i] = 0; br = 0;
                    413:                        }
                    414:                sgn = -1;
                    415:        } else
                    416:                sgn = 1;
                    417:        for ( i = bound - 1; ( i >= 0 ) && ( c[i] == 0 ); i--);
                    418:        if ( i == -1 )
                    419:                *qp = 0;
                    420:        else {
                    421:                n = NALLOC(i+1); PL(n) = i+1;
                    422:                for ( i = 0, ptr = BD(n); i < PL(n); i++ )
                    423:                        ptr[i] = c[i];
                    424:                bnton(mod,n,&tn); NTOQ(tn,sgn,*qp);
                    425:        }
                    426: }
                    427:
                    428: void mullumarray(f,list,k,in,g)
                    429: P f;
                    430: ML list;
                    431: int k;
                    432: int *in;
                    433: P *g;
                    434: {
                    435:        int np,bound,q,n,i,u;
                    436:        int *tmpp;
                    437:        LUM lclum,wb0,wb1,tlum;
                    438:        LUM *l;
                    439:        N lc;
                    440:
                    441:        n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
                    442:        W_LUMALLOC(n,bound,wb0); W_LUMALLOC(n,bound,wb1);
                    443:        W_LUMALLOC(0,bound,lclum);
                    444:        ntobn(q,NM((Q)COEF(DC(f))),&lc);
                    445:        for ( i = 0, tmpp = COEF(lclum)[0], u = MIN(bound,PL(lc));
                    446:                  i < u; i++ )
                    447:                tmpp[i] = BD(lc)[i];
                    448:        l = (LUM *)list->c;
                    449:        mullum(q,bound,lclum,l[in[0]],wb0);
                    450:        for ( i = 1; i < k; i++ ) {
                    451:                mullum(q,bound,l[in[i]],wb0,wb1);
                    452:                tlum = wb0; wb0 = wb1; wb1 = tlum;
                    453:        }
                    454:        lumtop(VR(f),q,bound,wb0,g);
                    455: }
                    456:
                    457: void ucsump(f,s)
                    458: P f;
                    459: Q *s;
                    460: {
                    461:        Q t,u;
                    462:        DCP dc;
                    463:
                    464:        for ( dc = DC(f), t = 0; dc; dc = NEXT(dc) ) {
                    465:                addq((Q)COEF(dc),t,&u); t = u;
                    466:        }
                    467:        *s = t;
                    468: }
                    469:

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