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

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

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