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

Annotation of OpenXM_contrib2/asir2000/engine/F.c, Revision 1.8

1.3       noro        1: /*
                      2:  * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
                      3:  * All rights reserved.
                      4:  *
                      5:  * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
                      6:  * non-exclusive and royalty-free license to use, copy, modify and
                      7:  * redistribute, solely for non-commercial and non-profit purposes, the
                      8:  * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
                      9:  * conditions of this Agreement. For the avoidance of doubt, you acquire
                     10:  * only a limited right to use the SOFTWARE hereunder, and FLL or any
                     11:  * third party developer retains all rights, including but not limited to
                     12:  * copyrights, in and to the SOFTWARE.
                     13:  *
                     14:  * (1) FLL does not grant you a license in any way for commercial
                     15:  * purposes. You may use the SOFTWARE only for non-commercial and
                     16:  * non-profit purposes only, such as academic, research and internal
                     17:  * business use.
                     18:  * (2) The SOFTWARE is protected by the Copyright Law of Japan and
                     19:  * international copyright treaties. If you make copies of the SOFTWARE,
                     20:  * with or without modification, as permitted hereunder, you shall affix
                     21:  * to all such copies of the SOFTWARE the above copyright notice.
                     22:  * (3) An explicit reference to this SOFTWARE and its copyright owner
                     23:  * shall be made on your publication or presentation in any form of the
                     24:  * results obtained by use of the SOFTWARE.
                     25:  * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.4       noro       26:  * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.3       noro       27:  * for such modification or the source code of the modified part of the
                     28:  * SOFTWARE.
                     29:  *
                     30:  * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
                     31:  * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
                     32:  * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
                     33:  * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
                     34:  * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
                     35:  * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
                     36:  * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
                     37:  * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
                     38:  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
                     39:  * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
                     40:  * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
                     41:  * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
                     42:  * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
                     43:  * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
                     44:  * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
                     45:  * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
                     46:  * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
                     47:  *
1.8     ! noro       48:  * $OpenXM: OpenXM_contrib2/asir2000/engine/F.c,v 1.7 2001/04/20 02:46:55 noro Exp $
1.3       noro       49: */
1.1       noro       50: #include "ca.h"
                     51: #include <math.h>
                     52:
                     53: void homfctr();
1.8     ! noro       54: void mfctr_wrt_v();
1.1       noro       55:
                     56: void fctrp(vl,f,dcp)
                     57: VL vl;
                     58: P f;
                     59: DCP *dcp;
                     60: {
                     61:        VL nvl;
                     62:        DCP dc;
                     63:
                     64:        if ( !f || NUM(f) ) {
                     65:                NEWDC(dc); COEF(dc) = f; DEG(dc) = ONE;
                     66:                NEXT(dc) = 0; *dcp = dc;
                     67:                return;
                     68:        } else if ( !qpcheck((Obj)f) )
                     69:                error("fctrp : invalid argument");
                     70:        else {
                     71:                clctv(vl,f,&nvl);
                     72:                if ( !NEXT(nvl) )
                     73:                        ufctr(f,1,dcp);
                     74:                else
                     75:                        mfctr(nvl,f,dcp);
                     76:        }
                     77: }
                     78:
1.8     ! noro       79: void fctr_wrt_v_p(vl,f,v,dcp)
        !            80: VL vl;
        !            81: P f;
        !            82: V v;
        !            83: DCP *dcp;
        !            84: {
        !            85:        VL nvl;
        !            86:        DCP dc;
        !            87:
        !            88:        if ( !f || NUM(f) ) {
        !            89:                NEWDC(dc); COEF(dc) = f; DEG(dc) = ONE;
        !            90:                NEXT(dc) = 0; *dcp = dc;
        !            91:                return;
        !            92:        } else if ( !qpcheck((Obj)f) )
        !            93:                error("fctrp : invalid argument");
        !            94:        else {
        !            95:                clctv(vl,f,&nvl);
        !            96:                if ( !NEXT(nvl) )
        !            97:                        ufctr(f,1,dcp);
        !            98:                else
        !            99:                        mfctr_wrt_v(nvl,f,v,dcp);
        !           100:        }
        !           101: }
        !           102:
1.1       noro      103: void homfctr(vl,g,dcp)
                    104: VL vl;
                    105: P g;
                    106: DCP *dcp;
                    107: {
                    108:        P s,t,u,f,h,x;
                    109:        Q e;
                    110:        int d,d0;
                    111:        DCP dc,dct;
                    112:
                    113:        substp(vl,g,vl->v,(P)ONE,&t); fctrp(vl,t,&dc); MKV(vl->v,x);
                    114:        for ( dct = dc; dct; dct = NEXT(dct) )
                    115:                if ( !NUM(dc->c) ) {
                    116:                        for ( s = 0, f = dc->c, d = d0 = homdeg(f); f; d = homdeg(f) ) {
                    117:                                exthp(vl,f,d,&h); STOQ(d0-d,e); pwrp(vl,x,e,&t);
                    118:                                mulp(vl,t,h,&u); addp(vl,s,u,&t); s = t;
                    119:                                subp(vl,f,h,&u); f = u;
                    120:                        }
                    121:                        dc->c = s;
                    122:                }
                    123:        *dcp = dc;
                    124: }
                    125:
                    126: void mfctr(vl,f,dcp)
                    127: VL vl;
                    128: P f;
                    129: DCP *dcp;
                    130: {
                    131:        DCP dc,dc0,dct,dcs,dcr;
                    132:        P p,pmin,ppmin,cmin,t;
                    133:        VL mvl;
                    134:        Q c;
                    135:
                    136:        ptozp(f,1,&c,&p);
                    137:        NEWDC(dc0); dc = dc0; COEF(dc) = (P)c; DEG(dc) = ONE; NEXT(dc) = 0;
                    138:        msqfr(vl,p,&dct);
                    139:        for ( ; dct; dct = NEXT(dct) ) {
                    140:                mindegp(vl,COEF(dct),&mvl,&pmin);
                    141: #if 0
                    142:                minlcdegp(vl,COEF(dct),&mvl,&pmin);
                    143:                min_common_vars_in_coefp(vl,COEF(dct),&mvl,&pmin);
                    144: #endif
1.8     ! noro      145:                pcp(mvl,pmin,&ppmin,&cmin);
        !           146:                if ( !NUM(cmin) ) {
        !           147:                        mfctrmain(mvl,cmin,&dcs);
        !           148:                        for ( dcr = dcs; dcr; dcr = NEXT(dcr) ) {
        !           149:                                DEG(dcr) = DEG(dct);
        !           150:                                reorderp(vl,mvl,COEF(dcr),&t); COEF(dcr) = t;
        !           151:                        }
        !           152:                        for ( ; NEXT(dc); dc = NEXT(dc) );
        !           153:                        NEXT(dc) = dcs;
        !           154:                }
        !           155:                mfctrmain(mvl,ppmin,&dcs);
        !           156:                for ( dcr = dcs; dcr; dcr = NEXT(dcr) ) {
        !           157:                        DEG(dcr) = DEG(dct);
        !           158:                        reorderp(vl,mvl,COEF(dcr),&t); COEF(dcr) = t;
        !           159:                }
        !           160:                for ( ; NEXT(dc); dc = NEXT(dc) );
        !           161:                NEXT(dc) = dcs;
        !           162:        }
        !           163:        adjsgn(f,dc0); *dcp = dc0;
        !           164: }
        !           165:
        !           166: void mfctr_wrt_v(vl,f,v,dcp)
        !           167: VL vl;
        !           168: P f;
        !           169: V v;
        !           170: DCP *dcp;
        !           171: {
        !           172:        DCP dc,dc0,dct,dcs,dcr;
        !           173:        P p,pmin,ppmin,cmin,t;
        !           174:        VL nvl,mvl;
        !           175:        Q c;
        !           176:
        !           177:        ptozp(f,1,&c,&p);
        !           178:        NEWDC(dc0); dc = dc0; COEF(dc) = (P)c; DEG(dc) = ONE; NEXT(dc) = 0;
        !           179:        msqfr(vl,p,&dct);
        !           180:        for ( ; dct; dct = NEXT(dct) ) {
        !           181:                clctv(vl,f,&nvl);
        !           182:                reordvar(nvl,v,&mvl);
        !           183:                reorderp(mvl,vl,f,&pmin);
1.1       noro      184:                pcp(mvl,pmin,&ppmin,&cmin);
                    185:                if ( !NUM(cmin) ) {
                    186:                        mfctrmain(mvl,cmin,&dcs);
                    187:                        for ( dcr = dcs; dcr; dcr = NEXT(dcr) ) {
                    188:                                DEG(dcr) = DEG(dct);
                    189:                                reorderp(vl,mvl,COEF(dcr),&t); COEF(dcr) = t;
                    190:                        }
                    191:                        for ( ; NEXT(dc); dc = NEXT(dc) );
                    192:                        NEXT(dc) = dcs;
                    193:                }
                    194:                mfctrmain(mvl,ppmin,&dcs);
                    195:                for ( dcr = dcs; dcr; dcr = NEXT(dcr) ) {
                    196:                        DEG(dcr) = DEG(dct);
                    197:                        reorderp(vl,mvl,COEF(dcr),&t); COEF(dcr) = t;
                    198:                }
                    199:                for ( ; NEXT(dc); dc = NEXT(dc) );
                    200:                NEXT(dc) = dcs;
                    201:        }
                    202:        adjsgn(f,dc0); *dcp = dc0;
                    203: }
                    204:
1.2       noro      205: #if 0
1.1       noro      206: void adjsgn(p,dc)
                    207: P p;
                    208: DCP dc;
                    209: {
                    210:        int sgn;
                    211:        DCP dct;
                    212:        P c;
                    213:
                    214:        for ( dct = dc, sgn = headsgn(p); dct; dct = NEXT(dct) )
                    215:                if ( !EVENN(NM(dct->d)) )
                    216:                        sgn *= headsgn(COEF(dct));
                    217:        if ( sgn < 0 ) {
                    218:                chsgnp(COEF(dc),&c); COEF(dc) = c;
                    219:        }
                    220: }
1.2       noro      221: #else
                    222: void adjsgn(p,dc)
                    223: P p;
                    224: DCP dc;
                    225: {
                    226:        int sgn;
                    227:        DCP dct;
                    228:        P c;
                    229:
                    230:        if ( headsgn(COEF(dc)) != headsgn(p) ) {
                    231:                chsgnp(COEF(dc),&c); COEF(dc) = c;
                    232:        }
                    233:        for ( dct = NEXT(dc); dct; dct = NEXT(dct) )
                    234:                if ( headsgn(COEF(dct)) < 0 ) {
                    235:                        chsgnp(COEF(dct),&c); COEF(dct) = c;
                    236:                }
                    237: }
                    238: #endif
1.1       noro      239:
                    240: int headsgn(p)
                    241: P p;
                    242: {
                    243:        if ( !p )
                    244:                return 0;
                    245:        else {
                    246:                while ( !NUM(p) )
                    247:                        p = COEF(DC(p));
                    248:                return SGN((Q)p);
                    249:        }
                    250: }
                    251:
                    252: void fctrwithmvp(vl,f,v,dcp)
                    253: VL vl;
                    254: P f;
                    255: V v;
                    256: DCP *dcp;
                    257: {
                    258:        VL nvl;
                    259:        DCP dc;
                    260:
                    261:        if ( NUM(f) ) {
                    262:                NEWDC(dc); COEF(dc) = f; DEG(dc) = ONE;
                    263:                NEXT(dc) = 0; *dcp = dc;
                    264:                return;
                    265:        }
                    266:
                    267:        clctv(vl,f,&nvl);
                    268:        if ( !NEXT(nvl) )
                    269:                ufctr(f,1,dcp);
                    270:        else
                    271:                mfctrwithmv(nvl,f,v,dcp);
                    272: }
                    273:
                    274: void mfctrwithmv(vl,f,v,dcp)
                    275: VL vl;
                    276: P f;
                    277: V v;
                    278: DCP *dcp;
                    279: {
                    280:        DCP dc,dc0,dct,dcs,dcr;
                    281:        P p,pmin,ppmin,cmin,t;
                    282:        VL mvl;
                    283:        Q c;
                    284:
                    285:        ptozp(f,1,&c,&p);
                    286:        NEWDC(dc0); dc = dc0; COEF(dc) = (P)c; DEG(dc) = ONE; NEXT(dc) = 0;
                    287:        msqfr(vl,p,&dct);
                    288:        for ( ; dct; dct = NEXT(dct) ) {
                    289:                if ( !v )
                    290:                        mindegp(vl,COEF(dct),&mvl,&pmin);
                    291:                else {
                    292:                        reordvar(vl,v,&mvl); reorderp(mvl,vl,COEF(dct),&pmin);
                    293:                }
                    294:                pcp(mvl,pmin,&ppmin,&cmin);
                    295:                if ( !NUM(cmin) ) {
                    296:                        mfctrmain(mvl,cmin,&dcs);
                    297:                        for ( dcr = dcs; dcr; dcr = NEXT(dcr) ) {
                    298:                                DEG(dcr) = DEG(dct);
                    299:                                reorderp(vl,mvl,COEF(dcr),&t); COEF(dcr) = t;
                    300:                        }
                    301:                        for ( ; NEXT(dc); dc = NEXT(dc) );
                    302:                        NEXT(dc) = dcs;
                    303:                }
                    304:                mfctrmain(mvl,ppmin,&dcs);
                    305:                for ( dcr = dcs; dcr; dcr = NEXT(dcr) ) {
                    306:                        DEG(dcr) = DEG(dct);
                    307:                        reorderp(vl,mvl,COEF(dcr),&t); COEF(dcr) = t;
                    308:                }
                    309:                for ( ; NEXT(dc); dc = NEXT(dc) );
                    310:                NEXT(dc) = dcs;
                    311:        }
                    312:        *dcp = dc0;
                    313: }
                    314:
                    315: void ufctr(f,hint,dcp)
                    316: P f;
                    317: int hint;
                    318: DCP *dcp;
                    319: {
                    320:        P p,c;
                    321:        DCP dc,dct,dcs,dcr;
                    322:
                    323:        ptozp(f,SGN((Q)UCOEF(f)),(Q *)&c,&p);
                    324:        NEWDC(dc); COEF(dc) = c; DEG(dc) = ONE; NEXT(dc) = 0;
                    325:        usqp(p,&dct);
                    326:        for ( *dcp = dc; dct; dct = NEXT(dct) ) {
                    327:                ufctrmain(COEF(dct),hint,&dcs);
                    328:                for ( dcr = dcs; dcr; dcr = NEXT(dcr) )
                    329:                        DEG(dcr) = DEG(dct);
                    330:                for ( ; NEXT(dc); dc = NEXT(dc) );
                    331:                NEXT(dc) = dcs;
                    332:        }
                    333: }
                    334:
                    335: void mfctrmain(vl,p,dcp)
                    336: VL vl;
                    337: P p;
                    338: DCP *dcp;
                    339: {
1.5       noro      340:        int i,j,k,*win,np,x;
1.1       noro      341:        VL nvl,tvl;
                    342:        VN vn,vnt,vn1;
                    343:        P p0,f,g,f0,g0,s,t,lp,m;
                    344:        P *fp0,*fpt,*l,*tl;
                    345:        DCP dc,dc0,dcl;
                    346:        int count,nv;
1.5       noro      347:        int *nonzero;
1.1       noro      348:
                    349:        if ( !cmpq(DEG(DC(p)),ONE) ) {
                    350:                NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
                    351:                *dcp = dc; return;
                    352:        }
                    353:        lp = LC(p); fctrp(vl,lp,&dcl); clctv(vl,p,&nvl);
                    354:        for ( nv = 0, tvl = nvl; tvl; tvl = NEXT(tvl), nv++);
                    355:        W_CALLOC(nv,struct oVN,vn); W_CALLOC(nv,struct oVN,vnt);
                    356:        W_CALLOC(nv,struct oVN,vn1);
1.5       noro      357:        W_CALLOC(nv,int,nonzero);
                    358:
1.1       noro      359:        for ( i = 0, tvl = NEXT(nvl); tvl; tvl = NEXT(tvl), i++ )
                    360:                vn1[i].v = vn[i].v = tvl->v;
                    361:        vn1[i].v = vn[i].v = 0;
1.5       noro      362:
                    363:        /* determine a heuristic bound of deg(GCD(p,p')) */
                    364:        while ( 1 ) {
                    365:                for ( i = 0; vn1[i].v; i++ )
                    366:                        vn1[i].n = ((unsigned int)random())%256+1;
                    367:                substvp(nvl,LC(p),vn1,&p0);
                    368:                if ( p0 ) {
                    369:                        substvp(nvl,p,vn1,&p0);
                    370:                        if ( sqfrchk(p0) ) {
                    371:                                ufctr(p0,1,&dc0);
                    372:                                if ( NEXT(NEXT(dc0)) == 0 ) {
                    373:                                        NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
                    374:                                        *dcp = dc;
                    375:                                        return;
                    376:                                } else {
                    377:                                        for ( dc0 = NEXT(dc0), np = 0; dc0; dc0 = NEXT(dc0), np++ );
                    378:                                        break;
                    379:                                }
                    380:                        }
                    381:                }
                    382:        }
                    383:
1.6       noro      384:        /* determine the position of variables which is not allowed to
                    385:           be set to 0 */
1.5       noro      386:        for ( i = 0; vn1[i].v; i++ ) {
                    387:                x = vn1[i].n; vn1[i].n = 0;
                    388:                substvp(nvl,LC(p),vn1,&p0);
                    389:                if ( !p0 )
                    390:                        vn1[i].n = x;
                    391:                else {
                    392:                        substvp(nvl,p,vn1,&p0);
                    393:                        if ( !sqfrchk(p0) )
                    394:                                vn1[i].n = x;
                    395:                        else {
                    396:                                ufctr(p0,1,&dc0);
                    397:                                for ( dc0 = NEXT(dc0), j = 0; dc0; dc0 = NEXT(dc0), j++ );
                    398:                                if ( j > np )
                    399:                                        vn1[i].n = x;
                    400:                        }
                    401:                }
                    402:        }
                    403:        for ( i = 0; vn1[i].v; i++ )
                    404:                if (vn1[i].n )
                    405:                        nonzero[i] = 1;
                    406:
1.1       noro      407:        count = 0;
                    408:        while  ( 1 ) {
                    409:                while ( 1 ) {
                    410:                        count++;
                    411:                        for ( i = 0, j = 0; vn[i].v; i++ )
                    412:                                if ( vn[i].n )
                    413:                                        vnt[j++].v = (V)i;
                    414:                        vnt[j].n = 0; mulsgn(vn,vnt,j,vn1);
                    415:                        for ( i = 0; vn1[i].v; i++ )
                    416:                                if ( vn1[i].n ) {
                    417:                                        if ( vn1[i].n > 0 )
                    418:                                                vn1[i].n = sprime[vn1[i].n];
                    419:                                        else
                    420:                                                vn1[i].n = -sprime[-vn1[i].n];
                    421:                                }
                    422:                        if ( valideval(nvl,dcl,vn1) ) {
                    423:                                substvp(nvl,p,vn1,&p0);
                    424:                                if ( sqfrchk(p0) ) {
                    425:                                        ufctr(p0,1,&dc0);
                    426:                                        if ( NEXT(NEXT(dc0)) == 0 ) {
                    427:                                                NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
                    428:                                                *dcp = dc;
                    429:                                                return;
1.5       noro      430:                                        } else {
                    431:                                                for ( dc = NEXT(dc0), i = 0; dc; dc = NEXT(dc), i++ );
                    432:                                                if ( i <= np )
                    433:                                                        goto MAIN;
                    434:                                                if ( i < np )
                    435:                                                        np = i;
                    436:                                        }
                    437:                                }
1.1       noro      438:                        }
                    439:                        if ( nextbin(vnt,j) )
                    440:                                break;
                    441:                }
1.5       noro      442:                while ( 1 ) {
                    443:                        next(vn);
                    444:                        for ( i = 0; vn[i].v; i++ )
                    445:                                if ( nonzero[i] && !vn[i].n )
                    446:                                        break;
                    447:                        if ( !vn[i].v )
                    448:                                break;
                    449:                }
1.1       noro      450:        }
                    451: MAIN :
                    452: #if 0
                    453:        for ( i = 0; vn1[i].v; i++ )
                    454:                fprintf(stderr,"%d ",vn1[i].n);
                    455:        fprintf(stderr,"\n");
                    456: #endif
                    457:        for ( np = 0, dc = NEXT(dc0); dc; dc = NEXT(dc), np++ );
                    458:        fp0 = (P *)ALLOCA((np + 1)*sizeof(P));
                    459:        fpt = (P *)ALLOCA((np + 1)*sizeof(P));
                    460:        l = tl = (P *)ALLOCA((np + 1)*sizeof(P));
                    461:        for ( i = 1, dc = NEXT(dc0); dc; i++, dc = NEXT(dc) )
                    462:                fp0[i-1] = COEF(dc);
                    463: #if 0
                    464:        sort_by_deg(np,fp0,fpt);
                    465:        sort_by_deg_rev(np-1,fpt+1,fp0+1);
                    466: #endif
                    467: #if 0
                    468:        sort_by_deg_rev(np,fp0,fpt); fp0[0] = fpt[0];
                    469:        sort_by_deg(np-1,fpt+1,fp0+1); fp0[np] = 0;
                    470: #endif
                    471:        fp0[np] = 0;
                    472:        win = W_ALLOC(np + 1); f = p; divsp(vl,p0,COEF(dc0),&f0);
                    473:        for ( k = 1, win[0] = 1, --np; ; ) {
                    474:                P h0,lcg,lch;
                    475:                Q c;
                    476:
                    477:                g0 = fp0[win[0]];
                    478:                for ( i = 1; i < k; i++ ) {
                    479:                        mulp(vl,g0,fp0[win[i]],&m); g0 = m;
                    480:                }
                    481:                mulq((Q)LC(g0),(Q)COEF(dc0),&c); estimatelc(nvl,c,dcl,vn1,&lcg);
                    482:                divsp(nvl,f0,g0,&h0);
                    483:                mulq((Q)LC(h0),(Q)COEF(dc0),&c); estimatelc(nvl,c,dcl,vn1,&lch);
                    484:                mfctrhen2(nvl,vn1,f,f0,g0,h0,lcg,lch,&g);
                    485:                if ( g ) {
                    486:                        *tl++ = g; divsp(vl,f,g,&t);
                    487:                        f = t; divsp(vl,f0,g0,&t); ptozp(t,1,(Q *)&s,&f0);
                    488:                        for ( i = 0; i < k - 1; i++ )
                    489:                                for ( j = win[i] + 1; j < win[i + 1]; j++ )
                    490:                                        fp0[j - i - 1] = fp0[j];
                    491:                        for ( j = win[k - 1] + 1; j <= np; j++ )
                    492:                                        fp0[j - k] = fp0[j];
                    493:                        if ( ( np -= k ) < k ) break;
                    494:                        if ( np - win[0] + 1 < k )
                    495:                                if ( ++k <= np ) {
                    496:                                        for ( i = 0; i < k; i++ ) win[i] = i + 1;
                    497:                                        continue;
                    498:                                } else
                    499:                                        break;
                    500:                        else for ( i = 1; i < k; i++ ) win[i] = win[0] + i;
                    501:                } else {
                    502:                        if ( ncombi(1,np,k,win) == 0 )
                    503:                                if ( k == np ) break;
                    504:                                else for ( i = 0, ++k; i < k; i++ ) win[i] = i + 1;
                    505:                }
                    506:        }
                    507:        *tl++ = f; *tl = 0;
                    508:        for ( dc0 = 0; *l; l++ ) {
                    509:                NEXTDC(dc0,dc); DEG(dc) = ONE; COEF(dc) = *l;
                    510:        }
                    511:        NEXT(dc) = 0; *dcp = dc0;
                    512: }
                    513:
                    514: void ufctrmain(p,hint,dcp)
                    515: P p;
                    516: int hint;
                    517: DCP *dcp;
                    518: {
                    519:        ML list;
                    520:        DCP dc;
                    521:
                    522:        if ( NUM(p) || (UDEG(p) == 1) ) {
                    523:                NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
                    524:                *dcp = dc;
                    525:        } else if ( iscycm(p) )
                    526:                cycm(VR(p),UDEG(p),dcp);
                    527:        else if ( iscycp(p) )
                    528:                cycp(VR(p),UDEG(p),dcp);
                    529:        else {
                    530:                hensel(5,5,p,&list);
                    531:                if ( list->n == 1 ) {
                    532:                        NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
                    533:                        *dcp = dc;
                    534:                } else
                    535:                        dtest(p,list,hint,dcp);
                    536:        }
                    537: }
                    538:
                    539: struct oMF {
                    540:        int m;
                    541:        P f;
                    542: };
                    543:
                    544: void calcphi();
                    545:
                    546: void cycm(v,n,dcp)
                    547: V v;
                    548: register int n;
                    549: DCP *dcp;
                    550: {
                    551:        register int i,j;
                    552:        struct oMF *mfp;
                    553:        DCP dc,dc0;
                    554:
                    555:        if ( n == 1 ) {
                    556:                NEWDC(dc); mkssum(v,1,1,-1,&COEF(dc)); DEG(dc) = ONE;
                    557:        } else {
                    558:                mfp = (struct oMF *) ALLOCA((n+1)*sizeof(struct oMF));
                    559:                bzero((char *)mfp,(int)(sizeof(struct oMF)*(n+1)));
                    560:                for ( i = 1, j = 0; i <= n; i++ )
                    561:                        if ( !(n%i) ) mfp[j++].m = i;
                    562:                mkssum(v,1,1,-1,&mfp[0].f);
                    563:                for ( i = 1; i < j; i++ )
                    564:                        calcphi(v,i,mfp);
                    565:                for ( dc0 = 0, i = 0; i < j; i++ ) {
                    566:                        NEXTDC(dc0,dc); COEF(dc) = mfp[i].f; DEG(dc) = ONE;
                    567:                }
                    568:        }
                    569:        NEXT(dc) = 0; *dcp = dc0;
                    570: }
                    571:
                    572: void cycp(v,n,dcp)
                    573: V v;
                    574: register int n;
                    575: DCP *dcp;
                    576: {
                    577:        register int i,j;
                    578:        int n0;
                    579:        struct oMF *mfp;
                    580:        DCP dc,dc0;
                    581:
                    582:        if ( n == 1 ) {
                    583:                NEWDC(dc); mkssum(v,1,1,1,&COEF(dc)); DEG(dc) = ONE;
                    584:        } else {
                    585:                n0 = n; n *= 2;
                    586:                mfp = (struct oMF *) ALLOCA((n+1)*sizeof(struct oMF));
                    587:                bzero((char *)mfp,(int)(sizeof(struct oMF)*(n+1)));
                    588:                for ( i = 1, j = 0; i <= n; i++ )
                    589:                        if ( !(n%i) ) mfp[j++].m = i;
                    590:                mkssum(v,1,1,-1,&mfp[0].f);
                    591:                for ( i = 1; i < j; i++ )
                    592:                        calcphi(v,i,mfp);
                    593:                for ( dc0 = 0, i = 0; i < j; i++ )
                    594:                        if ( n0 % mfp[i].m ) {
                    595:                                NEXTDC(dc0,dc); COEF(dc) = mfp[i].f; DEG(dc) = ONE;
                    596:                        }
                    597:        }
                    598:        NEXT(dc) = 0; *dcp = dc0;
                    599: }
                    600:
                    601: void calcphi(v,n,mfp)
                    602: V v;
                    603: int n;
                    604: register struct oMF *mfp;
                    605: {
                    606:        register int i,m;
                    607:        P t,s,tmp;
                    608:
                    609:        for ( t = (P)ONE, i = 0, m = mfp[n].m; i < n; i++ )
                    610:                if ( !(m%mfp[i].m) ) {
                    611:                        mulp(CO,t,mfp[i].f,&s); t = s;
                    612:                }
                    613:        mkssum(v,m,1,-1,&s); udivpz(s,t,&mfp[n].f,&tmp);
                    614:        if ( tmp )
                    615:                error("calcphi: cannot happen");
                    616: }
                    617:
                    618: void mkssum(v,e,s,sgn,r)
                    619: V v;
                    620: int e,s,sgn;
                    621: P *r;
                    622: {
                    623:        register int i,sgnt;
                    624:        DCP dc,dc0;
                    625:        Q q;
                    626:
                    627:        for ( dc0 = 0, i = s, sgnt = 1; i >= 0; i--, sgnt *= sgn ) {
                    628:                if ( !dc0 ) {
                    629:                        NEWDC(dc0); dc = dc0;
                    630:                } else {
                    631:                        NEWDC(NEXT(dc)); dc = NEXT(dc);
                    632:                }
                    633:                STOQ(i*e,DEG(dc)); STOQ(sgnt,q),COEF(dc) = (P)q;
                    634:        }
                    635:        NEXT(dc) = 0; MKP(v,dc0,*r);
                    636: }
                    637:
                    638: int iscycp(f)
                    639: P f;
                    640: {
                    641:        DCP dc;
                    642:        dc = DC(f);
                    643:
                    644:        if ( !UNIQ((Q)COEF(dc)) )
                    645:                return ( 0 );
                    646:        dc = NEXT(dc);
                    647:        if ( NEXT(dc) || DEG(dc) || !UNIQ((Q)COEF(dc)) )
                    648:                return ( 0 );
                    649:        return ( 1 );
                    650: }
                    651:
                    652: int iscycm(f)
                    653: P f;
                    654: {
                    655:        DCP dc;
                    656:
                    657:        dc = DC(f);
                    658:        if ( !UNIQ((Q)COEF(dc)) )
                    659:                return ( 0 );
                    660:        dc = NEXT(dc);
                    661:        if ( NEXT(dc) || DEG(dc) || !MUNIQ((Q)COEF(dc)) )
                    662:                return ( 0 );
                    663:        return ( 1 );
                    664: }
                    665:
                    666: void sortfs(dcp)
                    667: DCP *dcp;
                    668: {
                    669:        int i,k,n,k0,d;
                    670:        DCP dc,dct,t;
                    671:        DCP *a;
                    672:
                    673:        dc = *dcp;
                    674:        for ( n = 0, dct = dc; dct; dct = NEXT(dct), n++ );
                    675:        a = (DCP *)ALLOCA((n+1)*(sizeof(DCP)));
                    676:        for ( i = 0, dct = dc; dct; dct = NEXT(dct), i++ )
                    677:                a[i] = dct;
                    678:        a[n] = 0;
                    679:
                    680:        for ( i = 0; i < n; i++ ) {
                    681:                for ( k0 = k = i, d = UDEG(COEF(a[i])); k < n; k++ )
                    682:                        if ( (int)UDEG(COEF(a[k])) < d ) {
                    683:                                k0 = k;
                    684:                                d = UDEG(COEF(a[k]));
                    685:                        }
                    686:                if ( i != k0 ) {
                    687:                        t = a[i]; a[i] = a[k0]; a[k0] = t;
                    688:                }
                    689:        }
                    690:        for ( *dcp = dct = a[0], i = 1; i < n; i++ )
                    691:                dct = NEXT(dct) = a[i];
                    692:        NEXT(dct) = 0;
                    693: }
                    694:
                    695: void sortfsrev(dcp)
                    696: DCP *dcp;
                    697: {
                    698:        int i,k,n,k0,d;
                    699:        DCP dc,dct,t;
                    700:        DCP *a;
                    701:
                    702:        dc = *dcp;
                    703:        for ( n = 0, dct = dc; dct; dct = NEXT(dct), n++ );
                    704:        a = (DCP *)ALLOCA((n+1)*(sizeof(DCP)));
                    705:        for ( i = 0, dct = dc; dct; dct = NEXT(dct), i++ )
                    706:                a[i] = dct;
                    707:        a[n] = 0;
                    708:
                    709:        for ( i = 0; i < n; i++ ) {
                    710:                for ( k0 = k = i, d = UDEG(COEF(a[i])); k < n; k++ )
                    711:                        if ( (int)UDEG(COEF(a[k])) > d ) {
                    712:                                k0 = k;
                    713:                                d = UDEG(COEF(a[k]));
                    714:                        }
                    715:                if ( i != k0 ) {
                    716:                        t = a[i]; a[i] = a[k0]; a[k0] = t;
                    717:                }
                    718:        }
                    719:        for ( *dcp = dct = a[0], i = 1; i < n; i++ )
                    720:                dct = NEXT(dct) = a[i];
                    721:        NEXT(dct) = 0;
                    722: }
                    723:
                    724: void nthrootchk(f,dc,fp,dcp)
                    725: P f;
                    726: struct oDUM *dc;
                    727: ML fp;
                    728: DCP *dcp;
                    729: {
                    730:        register int i,k;
                    731:        int e,n,dr,tmp,t;
                    732:        int *tmpp,**tmppp;
                    733:        int **pp,**wpp;
                    734:        LUM fpa,tpa,f0l;
                    735:        UM wt,wq,ws,dvr,f0,fe;
                    736:        N lc;
                    737:        int lcm;
                    738:        int m,b;
                    739:
                    740:        m = fp->mod; b = fp->bound; fe = *((UM *)fp->c);
                    741:        e = dc->n; f0 = dc->f; nthrootn(NM((Q)COEF(DC(f))),e,&lc);
                    742:        if ( !lc ) {
                    743:                *dcp = 0;
                    744:                return;
                    745:        }
                    746:        lcm = rem(lc,m); W_LUMALLOC(DEG(f0),b,f0l);
                    747:        for ( i = DEG(f0), tmppp = COEF(f0l), tmpp = COEF(f0);
                    748:                i >= 0; i-- )
                    749:                *(tmppp[i]) = dmb(m,tmpp[i],lcm,&tmp);
                    750:        dtestroot(m,1,f,f0l,dc,dcp);
                    751:        if ( *dcp )
                    752:                return;
                    753:        n = UDEG(f); W_LUMALLOC(n,b,fpa); W_LUMALLOC(n,b,tpa);
                    754:        ptolum(m,b,f,fpa);
                    755:        dvr = W_UMALLOC(n); wq = W_UMALLOC(n);
                    756:        wt = W_UMALLOC(n); ws = W_UMALLOC(n);
                    757:        cpyum(fe,dvr); divum(m,dvr,f0,wq);
                    758:        t = dmb(m,pwrm(m,lcm,e-1),e,&tmp); DEG(dvr) = DEG(wq);
                    759:        for ( k = 0; k <= DEG(wq); k++ )
                    760:                COEF(dvr)[k] = dmb(m,COEF(wq)[k],t,&tmp);
                    761:        for ( i = 1; i < b; i++ ) {
                    762:                pwrlum(m,i+1,f0l,e,tpa);
                    763:                for ( k = 0, pp = COEF(fpa), wpp = COEF(tpa);
                    764:                        k <= n; k++ )
                    765:                        COEF(wt)[k] = (pp[k][i]-wpp[k][i]+m)%m;
                    766:                degum(wt,n); dr = divum(m,wt,dvr,ws);
                    767:                if ( dr >= 0 ) {
                    768:                        *dcp = 0;
                    769:                        return;
                    770:                }
                    771:                for ( k = 0, pp = COEF(f0l); k <= DEG(ws); k++ )
                    772:                        pp[k][i] = COEF(ws)[k];
                    773:                dtestroot(m,i+1,f,f0l,dc,dcp);
                    774:                if ( *dcp )
                    775:                        return;
                    776:        }
                    777: }
                    778:
                    779: void sqfrp(vl,f,dcp)
                    780: VL vl;
                    781: P f;
                    782: DCP *dcp;
                    783: {
                    784:        P c,p;
                    785:        DCP dc,dc0;
                    786:
                    787:        if ( !f || NUM(f) ) {
                    788:                NEWDC(dc0); *dcp = dc0; DEG(dc0) = ONE;
                    789:                COEF(dc0) = f; NEXT(dc0) = 0;
                    790:        } else if ( !qpcheck((Obj)f) )
                    791:                error("sqfrp : invalid argument");
                    792:        else {
                    793:                NEWDC(dc0); *dcp = dc0; DEG(dc0) = ONE;
                    794:                ptozp(f,1,(Q *)&c,&p); msqfr(vl,p,&dc);
                    795:                COEF(dc0) = c; NEXT(dc0) = dc;
                    796:                adjsgn(f,dc0);
                    797:        }
                    798: }
                    799:
                    800: /*
                    801:  * f : must be a poly with int coef, ignore int content
                    802:  */
                    803: void msqfr(vl,f,dcp)
                    804: VL vl;
                    805: P f;
                    806: DCP *dcp;
                    807: {
                    808:        DCP dc,dct,dcs;
                    809:        P c,p,t,s,pc;
                    810:        VL mvl;
                    811:
                    812:        ptozp(f,1,(Q *)&c,&t); monomialfctr(vl,t,&p,&dc);
                    813:        if ( NUM(p) ) {
                    814:                *dcp = dc;
                    815:                return;
                    816:        }
                    817:        mindegp(vl,p,&mvl,&s);
                    818: #if 0
                    819:        minlcdegp(vl,p,&mvl,&s);
                    820:        min_common_vars_in_coefp(vl,p,&mvl,&s);
                    821: #endif
                    822:        pcp(mvl,s,&p,&pc);
                    823:        if ( !NUM(pc) ) {
                    824:                msqfr(mvl,pc,&dcs);
                    825:                if ( !dc )
                    826:                        dc = dcs;
                    827:                else {
                    828:                        for ( dct = dc; NEXT(dct); dct = NEXT(dct) );
                    829:                        NEXT(dct) = dcs;
                    830:                }
                    831:        }
                    832:        msqfrmain(mvl,p,&dcs);
                    833:        for ( dct = dcs; dct; dct = NEXT(dct) ) {
                    834:                reorderp(vl,mvl,COEF(dct),&t); COEF(dct) = t;
                    835:        }
                    836:        if ( !dc )
                    837:                *dcp = dcs;
                    838:        else {
                    839:                for ( dct = dc; NEXT(dct); dct = NEXT(dct) );
                    840:                NEXT(dct) = dcs; *dcp = dc;
                    841:        }
                    842: }
                    843:
                    844: void usqp(f,dcp)
                    845: P f;
                    846: DCP *dcp;
                    847: {
                    848:        int index,nindex;
                    849:        P g,c,h;
                    850:        DCP dc;
                    851:
                    852:        ptozp(f,1,(Q *)&c,&h);
                    853:        if ( SGN((Q)LC(h)) < 0 )
                    854:                chsgnp(h,&g);
                    855:        else
                    856:                g = h;
                    857:        for ( index = 0, dc = 0; !dc; index = nindex )
                    858:                hsq(index,5,g,&nindex,&dc);
                    859:        *dcp = dc;
                    860: }
                    861:
                    862: void msqfrmain(vl,p,dcp)
                    863: VL vl;
                    864: P p;
                    865: DCP *dcp;
                    866: {
                    867:        int i,j;
                    868:        VL nvl,tvl;
                    869:        VN vn,vnt,vn1;
                    870:        P gg,tmp,p0,g;
                    871:        DCP dc,dc0,dcr,dcr0;
                    872:        int nv,d,d1;
                    873:        int found;
                    874:        VN svn1;
                    875:        P sp0;
                    876:        DCP sdc0;
                    877:
                    878:        if ( deg(VR(p),p) == 1 ) {
                    879:                NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
                    880:                *dcp = dc;
                    881:                return;
                    882:        }
                    883:        clctv(vl,p,&nvl);
                    884:        for ( nv = 0, tvl = nvl; tvl; tvl = NEXT(tvl), nv++);
                    885:        if ( nv == 1 ) {
                    886:                usqp(p,dcp);
                    887:                return;
                    888:        }
                    889: #if 0
                    890:        if ( heusqfrchk(nvl,p) ) {
                    891:                NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
                    892:                *dcp = dc;
                    893:                return;
                    894:        }
                    895: #endif
                    896:        W_CALLOC(nv,struct oVN,vn);
                    897:        W_CALLOC(nv,struct oVN,vnt);
                    898:        W_CALLOC(nv,struct oVN,vn1);
                    899:        W_CALLOC(nv,struct oVN,svn1);
                    900:        for ( i = 0, tvl = NEXT(nvl); tvl; tvl = NEXT(tvl), i++ )
                    901:                vn1[i].v = vn[i].v = tvl->v;
                    902:        vn1[i].v = vn[i].v = 0;
1.5       noro      903:
                    904:        /* determine a heuristic bound of deg(GCD(p,p')) */
                    905:        while ( 1 ) {
                    906:                for ( i = 0; vn1[i].v; i++ )
                    907:                        vn1[i].n = ((unsigned int)random())%256+1;
                    908:                substvp(nvl,LC(p),vn1,&tmp);
                    909:                if ( tmp ) {
                    910:                        substvp(nvl,p,vn1,&p0);
                    911:                        usqp(p0,&dc0);
                    912:                        for ( d1 = 0, dc = dc0; dc; dc = NEXT(dc) )
                    913:                                if ( DEG(dc) )
                    914:                                        d1 += (QTOS(DEG(dc))-1)*UDEG(COEF(dc));
                    915:                        if ( d1 == 0 ) {
                    916:                                /* p is squarefree */
                    917:                                NEWDC(dc); DEG(dc) = ONE; COEF(dc) = p; NEXT(dc) = 0;
                    918:                                *dcp = dc;
                    919:                                return;
                    920:                        } else {
1.7       noro      921:                                d = d1+1; /* XXX : try searching better evaluation */
                    922:                                found = 0;
1.5       noro      923:                                break;
                    924:                        }
                    925:                }
                    926:        }
1.1       noro      927:
1.6       noro      928:        for  ( dcr0 = 0, g = p; ; ) {
1.1       noro      929:                while ( 1 ) {
                    930:                        for ( i = 0, j = 0; vn[i].v; i++ )
                    931:                                if ( vn[i].n ) vnt[j++].v = (V)i;
                    932:                        vnt[j].n = 0;
                    933:
                    934:                        mulsgn(vn,vnt,j,vn1);
                    935:                        substvp(nvl,LC(g),vn1,&tmp);
                    936:                        if ( tmp ) {
                    937:                                substvp(nvl,g,vn1,&p0);
                    938:                                usqp(p0,&dc0);
                    939:                                for ( d1 = 0, dc = dc0; dc; dc = NEXT(dc) )
                    940:                                        if ( DEG(dc) )
                    941:                                                d1 += (QTOS(DEG(dc))-1)*UDEG(COEF(dc));
                    942:
                    943:                                if ( d1 == 0 ) {
                    944:                                        NEWDC(dc); DEG(dc) = ONE; COEF(dc) = g; NEXT(dc) = 0;
                    945:                                        if ( !dcr0 )
                    946:                                                dcr0 = dc;
                    947:                                        else
                    948:                                                NEXT(dcr) = dc;
                    949:                                        *dcp = dcr0;
                    950:                                        return;
                    951:                                }
                    952:
                    953:                                if ( d < d1 )
                    954:                                        goto END;
                    955:                                if ( d > d1 ) {
                    956:                                        d = d1;
                    957:                                        found = 1;
                    958:                                        bcopy((char *)vn1,(char *)svn1,(int)(sizeof(struct oVN)*nv));
                    959:                                        sp0 = p0; sdc0 = dc0;
                    960:                                        goto END;
                    961:                                }
                    962:                                /* d1 == d */
                    963:                                if ( found ) {
                    964:                                        found = 0;
                    965: #if 0
                    966:                                if ( d > d1 ) {
                    967:                                        d = d1;
                    968:                                                        /*} */
                    969: #endif
                    970:                                        msqfrmainmain(nvl,g,svn1,sp0,sdc0,&dc,&gg); g = gg;
                    971:                                        if ( dc ) {
                    972:                                                if ( !dcr0 )
                    973:                                                        dcr0 = dc;
                    974:                                                else
                    975:                                                        NEXT(dcr) = dc;
                    976:                                                for ( dcr = dc; NEXT(dcr); dcr = NEXT(dcr) );
                    977:                                                if ( NUM(g) ) {
                    978:                                                        NEXT(dcr) = 0; *dcp = dcr0;
                    979:                                                        return;
                    980:                                                }
                    981:                                                d = deg(VR(g),g);
                    982:                                        }
                    983:                                }
                    984:                        }
                    985: END:
                    986:                        if ( nextbin(vnt,j) )
                    987:                                break;
                    988:                }
                    989:                next(vn);
                    990:        }
                    991: }
                    992:
                    993: void msqfrmainmain(vl,p,vn,p0,dc0,dcp,pp)
                    994: VL vl;
                    995: P p;
                    996: VN vn;
                    997: P p0;
                    998: DCP dc0;
                    999: DCP *dcp;
                   1000: P *pp;
                   1001: {
                   1002:        int i,j,k,np;
                   1003:        DCP *a;
                   1004:        DCP dc,dcr,dcr0,dct;
                   1005:        P g,t,s,u,t0,f,f0,d,d0,g0,h0,x,xx;
                   1006:        Q q;
                   1007:        V v;
                   1008:
                   1009:        for ( np = 0, dc = dc0; dc; dc = NEXT(dc), np++ );
                   1010:        a = (DCP *)ALLOCA((np + 1)*sizeof(DCP));
                   1011:        for ( i = 0, dc = dc0; dc; i++, dc = NEXT(dc) )
                   1012:                a[np-i-1] = dc;
                   1013:
                   1014:        for ( i = 0, dcr0 = 0, f = p, f0 = p0, v = VR(p);
                   1015:                i < np; i++ ) {
                   1016:                if ( (i == (np-1))&&UNIQ(DEG(a[i])) ) {
                   1017:                        NEXTDC(dcr0,dcr);
                   1018:                        DEG(dcr) = DEG(a[i]);
                   1019:                        COEF(dcr) = f;
                   1020:                        f = (P)ONE;
                   1021:                } else if ( (i == (np-1))&&UNIQ(DEG(DC(COEF(a[i])))) ) {
                   1022:                        diffp(vl,f,v,&s); pcp(vl,s,&t,&u);
                   1023:                        if ( divtpz(vl,f,t,&s) ) {
                   1024:                                NEXTDC(dcr0,dcr);
                   1025:                                DEG(dcr) = DEG(a[i]);
                   1026:                                COEF(dcr) = s;
                   1027:                                f = (P)ONE;
                   1028:                        } else
                   1029:                                break;
                   1030:                } else {
                   1031:                        for ( t = f, t0 = f0,
                   1032:                                j = 0, k = QTOS(DEG(a[i]))-1; j < k; j++ ) {
                   1033:                                diffp(vl,t,v,&s); t = s;
                   1034:                                diffp(vl,t0,v,&s); t0 = s;
                   1035:                        }
                   1036:                        factorial(k,&q);
                   1037:                        divsp(vl,t,(P)q,&s);
                   1038:                        for ( dct = DC(s); NEXT(dct); dct = NEXT(dct) );
                   1039:                        if ( DEG(dct) ) {
                   1040:                                MKV(VR(s),x); pwrp(vl,x,DEG(dct),&xx);
                   1041:                                divsp(vl,s,xx,&d);
                   1042:                        } else {
                   1043:                                xx = (P)ONE; d = s;
                   1044:                        }
                   1045:                        divsp(vl,t0,xx,&t);
                   1046:                        divsp(vl,t,(P)q,&s);
                   1047:                        ptozp(s,1,(Q *)&t,&d0);
                   1048:
                   1049:                        for ( dct = DC(COEF(a[i])); NEXT(dct); dct = NEXT(dct) );
                   1050:                        if ( DEG(dct) )
                   1051:                                divsp(vl,COEF(a[i]),xx,&g0);
                   1052:                        else {
                   1053:                                xx = (P)ONE; g0 = COEF(a[i]);
                   1054:                        }
                   1055:
                   1056:                        pcp(vl,d,&t,&u); d = t;
                   1057:                        ptozp(g0,1,(Q *)&u,&t); g0 = t;
                   1058:
                   1059:                {
                   1060:                        DCP dca,dcb;
                   1061:
                   1062:                        fctrp(vl,LC(d),&dca);
                   1063:                        for ( dcb = dca, u = (P)ONE; dcb; dcb = NEXT(dcb) ) {
                   1064:                                if ( NUM(COEF(dcb)) ) {
                   1065:                                        mulp(vl,u,COEF(dcb),&t); u = t;
                   1066:                                } else {
                   1067:                                        Q qq;
                   1068:                                        P tt;
                   1069:
                   1070:                                        pwrp(vl,COEF(dcb),DEG(a[i]),&s);
                   1071:                                        for ( t = LC(f), j = 0; divtpz(vl,t,s,&tt); j++, t = tt );
                   1072:                                        STOQ(j,qq);
                   1073:                                        if ( cmpq(qq,DEG(dcb)) > 0 )
                   1074:                                                qq = DEG(dcb);
                   1075:                                        pwrp(vl,COEF(dcb),qq,&t); mulp(vl,u,t,&s); u = s;
                   1076:                                }
                   1077:                        }
                   1078:                        divsp(vl,d0,g0,&h0);
                   1079:                }
                   1080:                        mfctrhen2(vl,vn,d,d0,g0,h0,u,LC(d),&s);
                   1081:                        if ( s ) {
                   1082:                                mulp(vl,s,xx,&g);
                   1083:                                pwrp(vl,g,DEG(a[i]),&t);
                   1084:                                if ( divtpz(vl,f,t,&s) ) {
                   1085:                                        NEXTDC(dcr0,dcr);
                   1086:                                        DEG(dcr) = DEG(a[i]); COEF(dcr) = g;
                   1087:                                        f = s; substvp(vl,f,vn,&f0);
                   1088:                                } else
                   1089:                                        break;
                   1090:                        } else
                   1091:                                break;
                   1092:                }
                   1093:        }
                   1094:        *pp = f;
                   1095:        if ( dcr0 )
                   1096:                NEXT(dcr) = 0;
                   1097:        *dcp = dcr0;
                   1098: }
                   1099:
                   1100: void mfctrhen2(vl,vn,f,f0,g0,h0,lcg,lch,gp)
                   1101: VL vl;
                   1102: VN vn;
                   1103: P f;
                   1104: P f0,g0,h0,lcg,lch;
                   1105: P *gp;
                   1106: {
                   1107:        V v;
                   1108:        P f1,lc,lc0,lcg0,lch0;
                   1109:        P m,ff0,gg0,hh0,gk,hk,ggg,gggr,hhh,ak,bk,tmp;
                   1110:        Q bb,qk,s;
                   1111:        Q cbd;
                   1112:        int dbd;
                   1113:        int d;
                   1114:
                   1115:        if ( NUM(g0) ) {
                   1116:                *gp = (P)ONE;
                   1117:                return;
                   1118:        }
                   1119:
                   1120:        v = VR(f); d = deg(v,f);
                   1121:        if ( d == deg(v,g0) ) {
                   1122:                pcp(vl,f,gp,&tmp);
                   1123:                return;
                   1124:        }
                   1125:
                   1126:        mulp(vl,lcg,lch,&lc);
                   1127:        if ( !divtpz(vl,lc,LC(f),(P *)&s) ) {
                   1128:                *gp = 0;
                   1129:                return;
                   1130:        }
                   1131:        mulp(vl,(P)s,f,&f1);
                   1132:        dbd = dbound(VR(f1),f1) + 1; cbound(vl,f1,&cbd);
                   1133:
                   1134:        substvp(vl,lc,vn,&lc0);
                   1135:        divq((Q)lc0,(Q)LC(f0),(Q *)&m); mulp(vl,f0,m,&ff0);
                   1136:        substvp(vl,lcg,vn,&lcg0);
                   1137:        divq((Q)lcg0,(Q)LC(g0),(Q *)&m); mulp(vl,g0,m,&gg0);
                   1138:        substvp(vl,lch,vn,&lch0);
                   1139:        divq((Q)lch0,(Q)LC(h0),(Q *)&m); mulp(vl,h0,m,&hh0);
                   1140:        addq(cbd,cbd,&bb);
                   1141:        henzq1(gg0,hh0,bb,&bk,&ak,&qk); gk = gg0; hk = hh0;
                   1142:        henmv(vl,vn,f1,gk,hk,ak,bk,
                   1143:                lcg,lch,lcg0,lch0,qk,dbd,&ggg,&hhh);
                   1144:
                   1145:        if ( divtpz(vl,f1,ggg,&gggr) )
                   1146:                pcp(vl,ggg,gp,&tmp);
                   1147:        else
                   1148:                *gp = 0;
                   1149: }
                   1150:
                   1151: int sqfrchk(p)
                   1152: P p;
                   1153: {
                   1154:        Q c;
                   1155:        P f;
                   1156:        DCP dc;
                   1157:
                   1158:        ptozp(p,SGN((Q)UCOEF(p)),&c,&f); usqp(f,&dc);
                   1159:        if ( NEXT(dc) || !UNIQ(DEG(dc)) )
                   1160:                return ( 0 );
                   1161:        else
                   1162:                return ( 1 );
                   1163: }
                   1164:
                   1165: int cycchk(p)
                   1166: P p;
                   1167: {
                   1168:        Q c;
                   1169:        P f;
                   1170:
                   1171:        ptozp(p,SGN((Q)UCOEF(p)),&c,&f);
                   1172:        if ( iscycp(f) || iscycm(f) )
                   1173:                return 0;
                   1174:        else
                   1175:                return 1;
                   1176: }
                   1177:
                   1178: int zerovpchk(vl,p,vn)
                   1179: VL vl;
                   1180: P p;
                   1181: VN vn;
                   1182: {
                   1183:        P t;
                   1184:
                   1185:        substvp(vl,p,vn,&t);
                   1186:        if ( t )
                   1187:                return ( 0 );
                   1188:        else
                   1189:                return ( 1 );
                   1190: }
                   1191:
                   1192: int valideval(vl,dc,vn)
                   1193: VL vl;
                   1194: DCP dc;
                   1195: VN vn;
                   1196: {
                   1197:        DCP dct;
                   1198:        Q *a;
                   1199:        int i,j,n;
                   1200:        N q,r;
                   1201:
                   1202:        for ( dct = NEXT(dc), n = 0; dct; dct = NEXT(dct), n++ );
                   1203:        W_CALLOC(n,Q,a);
                   1204:        for ( dct = NEXT(dc), i = 0; dct; dct = NEXT(dct), i++ ) {
                   1205:                substvp(vl,COEF(dct),vn,(P *)&a[i]);
                   1206:                if ( !a[i] )
                   1207:                        return ( 0 );
                   1208:
                   1209:                for ( j = 0; j < i; j++ ) {
                   1210:                        divn(NM(a[j]),NM(a[i]),&q,&r);
                   1211:                        if ( !r )
                   1212:                                return ( 0 );
                   1213:                        divn(NM(a[i]),NM(a[j]),&q,&r);
                   1214:                        if ( !r )
                   1215:                                return ( 0 );
                   1216:                }
                   1217:        }
                   1218:        return ( 1 );
                   1219: }
                   1220:
                   1221: void estimatelc(vl,c,dc,vn,lcp)
                   1222: VL vl;
                   1223: Q c;
                   1224: DCP dc;
                   1225: VN vn;
                   1226: P *lcp;
                   1227: {
                   1228:        int i;
                   1229:        DCP dct;
                   1230:        P r,s,t;
                   1231:        Q c0,c1,c2;
                   1232:
                   1233:        for ( dct = dc, r = (P)ONE; dct; dct = NEXT(dct) ) {
                   1234:                if ( NUM(COEF(dct)) ) {
                   1235:                        mulp(vl,r,COEF(dct),&s); r = s;
                   1236:                } else {
                   1237:                        substvp(vl,COEF(dct),vn,(P *)&c0);
                   1238:                        for ( i = 0, c1 = c; i < (int)QTOS(DEG(dct)); i++ ) {
                   1239:                                divq(c1,c0,&c2);
                   1240:                                if ( !INT(c2) )
                   1241:                                        break;
                   1242:                                else
                   1243:                                        c1 = c2;
                   1244:                        }
                   1245:                        if ( i ) {
                   1246:                                STOQ(i,c1);
                   1247:                                pwrp(vl,COEF(dct),c1,&s); mulp(vl,r,s,&t); r = t;
                   1248:                        }
                   1249:                }
                   1250:        }
                   1251:        *lcp = r;
                   1252: }
                   1253:
                   1254: void monomialfctr(vl,p,pr,dcp)
                   1255: VL vl;
                   1256: P p;
                   1257: P *pr;
                   1258: DCP *dcp;
                   1259: {
                   1260:        VL nvl,avl;
                   1261:        Q d;
                   1262:        P f,t,s;
                   1263:        DCP dc0,dc;
                   1264:
                   1265:        clctv(vl,p,&nvl);
                   1266:        for ( dc0 = 0, avl = nvl, f = p; avl; avl = NEXT(avl) ) {
                   1267:                getmindeg(avl->v,f,&d);
                   1268:                if ( d ) {
                   1269:                        MKV(avl->v,t); NEXTDC(dc0,dc); DEG(dc) = d; COEF(dc) = t;
                   1270:                        pwrp(vl,t,d,&s); divsp(vl,f,s,&t); f = t;
                   1271:                }
                   1272:        }
                   1273:        if ( dc0 )
                   1274:                NEXT(dc) = 0;
                   1275:        *pr = f; *dcp = dc0;
                   1276: }
                   1277:
                   1278: void afctr(vl,p0,p,dcp)
                   1279: VL vl;
                   1280: P p,p0;
                   1281: DCP *dcp;
                   1282: {
                   1283:        DCP dc,dc0,dcr,dct,dcs;
                   1284:        P t;
                   1285:        VL nvl;
                   1286:
                   1287:        if ( VR(p) == VR(p0) ) {
                   1288:                NEWDC(dc);
                   1289:                DEG(dc) = ONE;
                   1290:                COEF(dc) = p;
                   1291:                NEXT(dc) = 0;
                   1292:                *dcp = dc;
                   1293:                return;
                   1294:        }
                   1295:
                   1296:        clctv(vl,p,&nvl);
                   1297:        if ( !NEXT(nvl) )
                   1298:                ufctr(p,1,&dc);
                   1299:        else {
                   1300:                sqa(vl,p0,p,&dc);
                   1301:                for ( dct = dc; dct; dct = NEXT(dct) ) {
                   1302:                        pmonic(vl,p0,COEF(dct),&t); COEF(dct) = t;
                   1303:                }
                   1304:        }
                   1305:        if ( NUM(COEF(dc)) )
                   1306:                dcr = NEXT(dc);
                   1307:        else
                   1308:                dcr = dc;
                   1309:        for ( dc0 = 0; dcr; dcr = NEXT(dcr) ) {
                   1310:                afctrmain(vl,p0,COEF(dcr),1,&dcs);
                   1311:
                   1312:                for ( dct = dcs; dct; dct = NEXT(dct) )
                   1313:                        DEG(dct) = DEG(dcr);
                   1314:                if ( !dc0 )
                   1315:                        dc0 = dcs;
                   1316:                else {
                   1317:                        for ( dct = dc0; NEXT(dct); dct = NEXT(dct) );
                   1318:                        NEXT(dct) = dcs;
                   1319:                }
                   1320:        }
                   1321:        *dcp = dc0;
                   1322: }
                   1323:
                   1324: void afctrmain(vl,p0,p,init,dcp)
                   1325: VL vl;
                   1326: P p,p0;
                   1327: int init;
                   1328: DCP *dcp;
                   1329: {
                   1330:        P x,y,s,m,a,t,u,pt,pt1,res,g;
                   1331:        Q q;
                   1332:        DCP dc,dc0,dcsq0,dcr0,dcr,dct,dcs;
                   1333:        V v,v0;
                   1334:
                   1335:        if ( !cmpq(DEG(DC(p)),ONE) ) {
                   1336:                NEWDC(dc); DEG(dc) = ONE; NEXT(dc) = 0;
                   1337:                pmonic(vl,p0,p,&COEF(dc)); *dcp = dc;
                   1338:                return;
                   1339:        }
                   1340:
                   1341:        v = VR(p); MKV(v,x);
                   1342:        v0 = VR(p0); MKV(v0,y);
                   1343:        STOQ(init,q),s = (P)q;
                   1344:        mulp(vl,s,y,&m); subp(vl,x,m,&t); addp(vl,x,m,&a);
                   1345:        substp(vl,p,v,t,&pt);
                   1346:        remsdcp(vl,pt,p0,&pt1);
                   1347:
                   1348: /*
                   1349:        if ( ( deg(v0,p0) <= 3 ) || ( TCPQ(p0) <= 2 ) )
                   1350:                resultp(vl,v0,p0,pt1,&res);
                   1351:        else
                   1352:                srcrnorm(vl,v0,pt1,p0,&res);
                   1353: */
                   1354: #if 0
                   1355:        srcr(vl,v0,pt1,p0,&res);
                   1356: #endif
                   1357:        resultp(vl,v0,p0,pt1,&res);
                   1358:        usqp(res,&dcsq0);
                   1359:        for ( dc0 = 0, dct = dcsq0; dct; dct = NEXT(dct) ) {
                   1360:                if ( UNIQ(DEG(dct)) )
                   1361:                        ufctr(COEF(dct),deg(v0,p0),&dcs);
                   1362:                else
                   1363:                        ufctr(COEF(dct),1,&dcs);
                   1364:                for ( dcr = dcs; dcr; dcr = NEXT(dcr) )
                   1365:                        DEG(dcr) = DEG(dct);
                   1366:                if ( !dc0 ) {
                   1367:                        dc0 = NEXT(dcs);
                   1368:                        dc = dc0;
                   1369:                } else {
                   1370:                        for ( ; NEXT(dc); dc = NEXT(dc) );
                   1371:                        NEXT(dc) = NEXT(dcs);
                   1372:                }
                   1373:        }
                   1374:        sortfs(&dc0);
                   1375:
                   1376:        for ( g = p, dcr = dcr0 = 0, dc = dc0; dc; dc = NEXT(dc) ) {
                   1377:                if ( !UNIQ(DEG(dc)) ) {
                   1378:                        substp(vl,COEF(dc),v,a,&pt); remsdcp(vl,pt,p0,&s);
                   1379:                        gcda(vl,p0,s,g,&u);
                   1380:                        if ( !NUM(u) && (VR(u) == v)) {
                   1381:                                afctrmain(vl,p0,u,init+1,&dct);
                   1382:                                for ( dcs = dct, t = (P)ONE; dcs; dcs = NEXT(dcs) ) {
                   1383:                                        mulp(vl,t,COEF(dcs),&s); remsdcp(vl,s,p0,&t);
                   1384:                                }
                   1385:                                pdiva(vl,p0,g,t,&s); g = s;
                   1386:                                if ( !dcr0 )
                   1387:                                        dcr0 = dct;
                   1388:                                else
                   1389:                                        NEXT(dcr) = dct;
                   1390:                                for ( dcr = dct; NEXT(dcr); dcr = NEXT(dcr) );
                   1391:                        }
                   1392:                } else {
                   1393:                        substp(vl,COEF(dc),v,a,&pt); remsdcp(vl,pt,p0,&s);
                   1394:                        gcda(vl,p0,s,g,&u);
                   1395:                        if ( !NUM(u) && (VR(u) == v)) {
                   1396:                                NEXTDC(dcr0,dcr);
                   1397:                                DEG(dcr) = ONE;
                   1398:                                COEF(dcr) = u;
                   1399:                                pdiva(vl,p0,g,u,&t); g = t;
                   1400:                        }
                   1401:                }
                   1402:        }
                   1403:        if ( dcr0 )
                   1404:                NEXT(dcr) = 0;
                   1405:        *dcp = dcr0;
                   1406: }

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