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

Annotation of OpenXM_contrib2/asir2018/engine/EZ.c, Revision 1.2

1.1       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
                     26:  * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
                     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.2     ! noro       48:  * $OpenXM: OpenXM_contrib2/asir2018/engine/EZ.c,v 1.1 2018/09/19 05:45:06 noro Exp $
1.1       noro       49: */
                     50: #include "ca.h"
                     51:
                     52: void ezgcdp(VL vl,P p1,P p2,P *pr)
                     53: {
                     54:   P f1,f2;
                     55:   Q c;
                     56:
                     57:   if ( !p1 )
                     58:     if ( !p2 )
                     59:       *pr = 0;
                     60:     else
                     61:       *pr = p2;
                     62:   else if ( !p2 )
                     63:     *pr = p1;
                     64:   else {
                     65:     if ( !qpcheck((Obj)p1) || !qpcheck((Obj)p2) )
                     66:       error("ezgcdp : invalid argument");
                     67:     ptozp(p1,1,&c,&f1);
                     68:     ptozp(p2,1,&c,&f2);
                     69:     ezgcdpz(vl,f1,f2,pr);
                     70:   }
                     71: }
                     72:
                     73: /*
                     74:  * p1, p2 : integer coefficient
                     75:  * returns gcd(pp(p1),pp(p2)) * gcd(cont(p1),cont(p2))
                     76:  */
                     77:
                     78: void ezgcdpz(VL vl,P p1,P p2,P *pr)
                     79: {
                     80:   P f1,f2,t,s,g,gcd;
                     81:   P fc1,fc2,cont;
                     82:   VL tvl,svl;
                     83:   V v1,v2;
                     84:   DCP dc,dc1,dc2;
                     85:   Z c1,c2,c;
                     86:   P g1,g2;
                     87:   P mgcd;
                     88:   extern int nez;
                     89:   P pm[2];
                     90:
                     91:   if ( nez ) {
                     92:     pm[0] = p1; pm[1] = p2; nezgcdnpz(vl,pm,2,pr); return;
                     93:   }
                     94:   monomialfctr(vl,p1,&f1,&dc1); p1 = f1;
                     95:   monomialfctr(vl,p2,&f2,&dc2); p2 = f2;
                     96:   for ( mgcd = (P)ONE; dc1; dc1 = NEXT(dc1) )
                     97:     for ( v1 = VR(dc1->c), dc = dc2; dc; dc = NEXT(dc) )
                     98:       if ( v1 == VR(dc->c) ) {
                     99:         pwrp(vl,dc->c,cmpz(dc1->d,dc->d)>=0?dc->d:dc1->d,&t);
                    100:         mulp(vl,mgcd,t,&s); mgcd = s; break;
                    101:       }
                    102:
                    103:   if ( NUM(p1) ) {
                    104:     if ( NUM(p2) ) {
                    105:       gcdz((Z)p1,(Z)p2,&c);
                    106:     } else {
                    107:       ptozp(p2,1,(Q *)&c2,&t);
                    108:       gcdz((Z)p1,c2,&c);
                    109:     }
                    110:     mulp(vl,(P)c,mgcd,pr);
                    111:     return;
                    112:   } else if ( NUM(p2) ) {
                    113:     ptozp(p1,1,(Q *)&c1,&t);
                    114:     gcdz(c1,(Z)p2,&c);
                    115:     mulp(vl,(P)c,mgcd,pr);
                    116:     return;
                    117:   }
                    118:
                    119:   ptozp(p1,1,(Q *)&c1,&g1); ptozp(p2,1,(Q *)&c2,&g2);
                    120:   gcdz(c1,c2,&c);
                    121:
                    122:   if ( ( v1 = VR(f1) ) != ( v2 = VR(f2) ) ) {
                    123:     while ( v1 != VR(vl) && v2 != VR(vl) )
                    124:       vl = NEXT(vl);
                    125:     if ( v1 == VR(vl) ) {
                    126:       pcp(vl,f1,&g,&fc1);
                    127:       ezgcdpz(vl,fc1,f2,&t);
                    128:     } else {
                    129:       pcp(vl,f2,&g,&fc2);
                    130:       ezgcdpz(vl,fc2,f1,&t);
                    131:     }
                    132:     mulp(vl,t,(P)c,&s); mulp(vl,s,mgcd,pr);
                    133:     return;
                    134:   }
                    135:
                    136:   pcp(vl,f1,&g1,&fc1); pcp(vl,f2,&g2,&fc2);
                    137:   ezgcdpz(vl,fc1,fc2,&cont);
                    138:   clctv(vl,g1,&tvl); clctv(vl,g2,&svl);
                    139:   if ( !NEXT(tvl) && !NEXT(svl) ) {
                    140:     uezgcdpz(vl,g1,g2,&t);
                    141:     mulp(vl,t,cont,&s); mulp(vl,s,(P)c,&t); mulp(vl,t,mgcd,pr);
                    142:     return;
                    143:   }
                    144:
                    145:   if ( homdeg(g1) > homdeg(g2) ) {
                    146:     t = g1; g1 = g2; g2 = t;
                    147:   }
                    148:   sqfrp(vl,g1,&dc);
                    149:   for ( g = g2, gcd = (P)ONE; dc && !NUM(g); dc = NEXT(dc) ) {
                    150:     if ( NUM(COEF(dc)) )
                    151:       continue;
                    152:     ezgcdpp(vl,dc,g,&t);
                    153:     if ( NUM(t) )
                    154:       continue;
                    155:     mulp(vl,gcd,t,&s); gcd = s;
                    156:     divsp(vl,g,t,&s); g = s;
                    157:   }
                    158:   mulp(vl,gcd,cont,&t); mulp(vl,t,(P)c,&s); mulp(vl,s,mgcd,pr);
                    159: }
                    160:
                    161: void uezgcdpz(VL vl,P p1,P p2,P *pr)
                    162: {
                    163:   P g1,g2,gcd,t,s,g;
                    164:   DCP dc;
                    165:   Z c1,c2,cq;
                    166:   P f1,f2;
                    167:
                    168:   if ( NUM(p1) ) {
                    169:     if ( NUM(p2) ) {
                    170:       gcdz((Z)p1,(Z)p2,&cq); *pr = (P)cq;
                    171:       return;
                    172:     } else {
                    173:       ptozp(p2,1,(Q *)&c2,&t);
                    174:       gcdz((Z)p1,c2,&cq); *pr = (P)cq;
                    175:       return;
                    176:     }
                    177:   } else if ( NUM(p2) ) {
                    178:     ptozp(p1,1,(Q *)&c1,&t);
                    179:     gcdz(c1,(Z)p2,&cq); *pr = (P)cq;
                    180:     return;
                    181:   }
                    182:
                    183:   ptozp(p1,1,(Q *)&c1,&f1); ptozp(p2,1,(Q *)&c2,&f2);
                    184:   gcdz(c1,c2,&cq);
                    185:   if ( UDEG(f1) > UDEG(f2) ) {
                    186:     g1 = f2; g2 = f1;
                    187:   } else {
                    188:     g1 = f1; g2 = f2;
                    189:   }
                    190:   usqp(g1,&dc);
                    191:   for ( g = g2, gcd = (P)ONE; dc && !NUM(g); dc = NEXT(dc) ) {
                    192:     if ( NUM(COEF(dc)) )
                    193:       continue;
                    194:     uezgcdpp(dc,g,&t);
                    195:     if ( NUM(t) )
                    196:       continue;
                    197:     mulp(CO,gcd,t,&s); gcd = s;
                    198:     divsp(CO,g,t,&s); g = s;
                    199:   }
                    200:   mulp(vl,gcd,(P)cq,pr);
                    201: }
                    202:
                    203: /*
                    204:   dc : dc pair c^d
                    205:   r = gcd(c^d,f)
                    206: */
                    207:
                    208: void ezgcdpp(VL vl,DCP dc,P f,P *r)
                    209: {
                    210:   int k;
                    211:   P g,h,t,s,gcd;
                    212:
                    213:   if ( NUM(f) ) {
                    214:     *r = (P)ONE;
                    215:     return;
                    216:   }
1.2     ! noro      217:   k = ZTOS(DEG(dc)) - 1;
1.1       noro      218: /*  ezgcd1p(vl,COEF(dc),f,&gcd); */
                    219:   ezgcdnp(vl,COEF(dc),&f,1,&gcd);
                    220:   g = gcd; divsp(vl,f,gcd,&h);
                    221:   for ( ; k > 0; k-- ) {
                    222: /*    ezgcd1p(vl,g,h,&t); */
                    223:     ezgcdnp(vl,g,&h,1,&t);
                    224:     if ( NUM(t) )
                    225:       break;
                    226:     mulp(vl,gcd,t,&s); gcd = s;
                    227:     divsp(vl,h,t,&s); h = s;
                    228:   }
                    229:   *r = gcd;
                    230: }
                    231:
                    232: void ezgcd1p(VL vl,P p0,P p1,P *gcdp)
                    233: {
                    234:   VL nvl,tvl,vl0,vl1,vl2;
                    235:   P f0,f1,t;
                    236:
                    237:   clctv(vl,p0,&vl0); clctv(vl,p1,&vl1); mergev(vl,vl0,vl1,&vl2);
                    238:   minchdegp(vl,p0,&tvl,&t); reordvar(vl2,tvl->v,&nvl);
                    239:   reorderp(nvl,vl,p0,&f0); reorderp(nvl,vl,p1,&f1);
                    240:   ezgcdnp(nvl,f0,&f1,1,&t);
                    241:   reorderp(vl,nvl,t,gcdp);
                    242: }
                    243:
                    244: void uezgcdpp(DCP dc,P f,P *r)
                    245: {
                    246:   int k;
                    247:   P g,h,t,s,gcd;
                    248:
                    249:   if ( NUM(f) ) {
                    250:     *r = (P)ONE;
                    251:     return;
                    252:   }
                    253:
1.2     ! noro      254:   k = ZTOS(DEG(dc)) - 1;
1.1       noro      255:   uezgcd1p(COEF(dc),f,&gcd);
                    256:   g = gcd; divsp(CO,f,gcd,&h);
                    257:   for ( ; k > 0; k-- ) {
                    258:     uezgcd1p(g,h,&t);
                    259:     if ( NUM(t) )
                    260:       break;
                    261:     mulp(CO,gcd,t,&s); gcd = s;
                    262:     divsp(CO,h,t,&s); h = s;
                    263:   }
                    264:   *r = gcd;
                    265: }
                    266:
                    267: /*
                    268:  * pr = gcd(p0,ps[0],...,ps[m-1])
                    269:  *
                    270:  * p0 is already square-free and primitive.
                    271:  * ps[i] is at least primitive.
                    272:  *
                    273:  */
                    274:
                    275: void ezgcdnp(VL vl,P p0,P *ps,int m,P *pr)
                    276: {
                    277:   /* variables */
                    278:   P p00,g,h,g0,h0,a0,b0;
                    279:   P lp0,lgp0,lp00,lg,lg0,t;
                    280:   Q cbd;
                    281:   Z tq;
                    282:   P *tps;
                    283:   VL nvl1,nvl2,nvl,tvl;
                    284:   V v;
                    285:   int i,j,k,d0,dg,dg0,dmin;
                    286:   VN vn0,vn1,vnt;
                    287:   int nv,flag;
                    288:
                    289:   /* set-up */
                    290:   if ( NUM(p0) ) {
                    291:     *pr = (P) ONE;
                    292:     return;
                    293:   }
                    294:   for ( v = VR(p0), i = 0; i < m; i++ )
                    295:     if ( NUM(ps[i]) || (v != VR(ps[i])) ) {
                    296:       *pr = (P)ONE;
                    297:       return;
                    298:     }
                    299:   tps = (P *) ALLOCA(m*sizeof(P));
                    300:   for ( i = 0; i < m; i++ )
                    301:     tps[i] = ps[i];
                    302:   sortplist(tps,m);
                    303:   /* deg(tps[0]) <= deg(tps[1]) <= ... */
                    304:
                    305:   if ( !cmpz(DEG(DC(p0)),ONE) ) {
                    306:     if ( divcheck(vl,tps,m,(P)ONE,p0) )
                    307:       *pr = p0;
                    308:     else
                    309:       *pr = (P)ONE;
                    310:     return;
                    311:   }
                    312:
                    313:   lp0 = LC(p0); lg = lp0; dmin = d0 = deg(v,p0);
                    314:   clctv(vl,p0,&nvl);
                    315:   for ( i = 0; i < m; i++ ) {
                    316:     clctv(vl,tps[i],&nvl1); mergev(vl,nvl,nvl1,&nvl2);
                    317:     nvl = nvl2;
                    318:     ezgcdpz(nvl,lg,LC(tps[i]),&t); lg = t;
                    319:   }
                    320:
                    321:   mulp(nvl,p0,lg,&lgp0);
                    322:   k = dbound(v,lgp0) + 1;
                    323:   cbound(nvl,lgp0,(Q *)&cbd);
                    324:   for ( nv = 0, tvl = nvl; tvl; tvl = NEXT(tvl), nv++ );
                    325:   W_CALLOC(nv,struct oVN,vn0); W_CALLOC(nv,struct oVN,vnt);
                    326:   W_CALLOC(nv,struct oVN,vn1);
                    327:   for ( i = 0, tvl = NEXT(nvl); tvl; tvl = NEXT(tvl), i++ )
                    328:     vn1[i].v = vn0[i].v = tvl->v;
                    329:
                    330:   /* main loop */
                    331:   for ( dg = deg(v,tps[0]) + 1; ; next(vn0) )
                    332:     do {
                    333:       for ( i = 0, j = 0; vn0[i].v; i++ )
                    334:         if ( vn0[i].n ) vnt[j++].v = (V)((unsigned long)i);
                    335:       vnt[j].n = 0;
                    336:
                    337:       /* find b s.t. LC(p0)(b), LC(tps[i])(b) != 0 */
                    338:       mulsgn(vn0,vnt,j,vn1);
                    339:       substvp(nvl,p0,vn1,&p00);
                    340:       flag = (!zerovpchk(nvl,lp0,vn1) && sqfrchk(p00));
                    341:       for ( i = 0; flag && (i < m); i++ )
                    342:         flag &= (!zerovpchk(nvl,LC(tps[i]),vn1));
                    343:       if ( !flag )
                    344:         continue;
                    345:
                    346:       /* substitute y -> b */
                    347:       substvp(nvl,lg,vn1,&lg0);
                    348:       lp00 = LC(p00);
                    349:       /* extended-gcd in 1-variable */
                    350:       uexgcdnp(nvl,p00,tps,m,vn1,(Q)cbd,&g0,&h0,&a0,&b0,&tq);
                    351:       if ( NUM(g0) ) {
                    352:         *pr = (P)ONE;
                    353:         return;
                    354:       } else if ( dg > ( dg0 = deg(v,g0) ) ) {
                    355:         dg = dg0;
                    356:         if ( dg == d0 ) {
                    357:           if ( divcheck(nvl,tps,m,lp0,p0) ) {
                    358:             *pr = p0;
                    359:              return;
                    360:           }
                    361:         } else if ( dg == deg(v,tps[0]) ) {
                    362:           if ( divtpz(nvl,p0,tps[0],&t) &&
                    363:             divcheck(nvl,tps+1,m-1,LC(tps[0]),tps[0]) ) {
                    364:             *pr = tps[0];
                    365:              return;
                    366:           } else
                    367:             break;
                    368:         } else {
                    369:           henmv(nvl,vn1,lgp0,g0,h0,a0,b0,
                    370:             lg,lp0,lg0,lp00,tq,k,&g,&h);
                    371:           if ( divtpz(nvl,lgp0,g,&t) &&
                    372:             divcheck(nvl,tps,m,lg,g) ) {
                    373:             pcp(nvl,g,pr,&t);
                    374:             return;
                    375:           }
                    376:         }
                    377:       }
                    378:     } while ( !nextbin(vnt,j) );
                    379: }
                    380:
                    381: /*
                    382:   f : sqfr
                    383: */
                    384:
                    385: void uezgcd1p(P f,P g,P *r)
                    386: {
                    387:   UM wf,wf1,wf2,wg,wg1,wgcd,wcof;
                    388:   int d1,d2,dg,m,index,n;
                    389:   ML list;
                    390:   DCP dc;
                    391:   P t;
                    392:   Q c;
                    393:
                    394:   if ( NUM(f) || NUM(g) ) {
                    395:     *r = (P)ONE;
                    396:     return;
                    397:   }
                    398:   ptozp(f,1,&c,&t); f = t; ptozp(g,1,&c,&t); g = t;
                    399:   d1 = UDEG(f); d2 = UDEG(g);
                    400:   n = MAX(d1,d2)+1;
                    401:   wf = W_UMALLOC(n); wf1 = W_UMALLOC(n);
                    402:   wf2 = W_UMALLOC(n); wg = W_UMALLOC(n);
                    403:   wg1 = W_UMALLOC(n); wgcd = W_UMALLOC(n);
                    404:   wcof = W_UMALLOC(n);
                    405:
                    406:   for ( index = INDEX, dg = MIN(d1,d2)+1; ; ) {
                    407:     m = sprime[index++];
                    408:     if ( !remqi((Q)UCOEF(f),m) || !remqi((Q)UCOEF(g),m))
                    409:       continue;
                    410:     ptoum(m,f,wf); cpyum(wf,wf1);
                    411:     diffum(m,wf1,wf2); gcdum(m,wf1,wf2,wgcd);
                    412:     if ( DEG(wgcd) > 0 )
                    413:       continue;
                    414:     ptoum(m,g,wg); cpyum(wg,wg1); cpyum(wf,wf1);
                    415:     gcdum(m,wf1,wg1,wgcd);
                    416:     if ( dg <= DEG(wgcd) )
                    417:       continue;
                    418:     else
                    419:       dg = DEG(wgcd);
                    420:     if ( dg == 0 ) {
                    421:       *r = (P)ONE;
                    422:       return;
                    423:     } else if ( dg == d1 ) {
                    424:       if ( divtpz(CO,g,f,&t) ) {
                    425:         *r = f;
                    426:         return;
                    427:       }
                    428:     } else if ( dg == d2 ) {
                    429:       if ( divtpz(CO,f,g,&t) ) {
                    430:         *r = g;
                    431:         return;
                    432:       }
                    433:     } else {
                    434:       divum(m,wf,wgcd,wcof);
                    435:       ezgcdhensel(f,m,wcof,wgcd,&list);
                    436:       dtest(f,list,1,&dc);
                    437:       if ( NEXT(dc) ) {
                    438:         if ( divtpz(CO,g,COEF(dc),&t) ) {
                    439:           *r = COEF(dc);
                    440:           return;
                    441:         }
                    442:       }
                    443:     }
                    444:   }
                    445: }
                    446:
                    447: void uexgcdnp(VL vl,P p1,P *ps,int n,VN vn,Q cbd,P *g,P *h,P *a,P *b,Z *q)
                    448: {
                    449:   UM wg,wh,wg1,wh1,wgcd,wt;
                    450:   P t,s,gcd,cof,gk,hk,ak,bk;
                    451:   Q c,bb;
                    452:   Z tq,tq1,qk;
                    453:   int mod,k,i,index,d;
                    454:
                    455:   ptozp(p1,1,&c,&gcd);
                    456:   for ( i = 0; i < n; i++ ) {
                    457:     substvp(vl,ps[i],vn,&t);
                    458:     uezgcd1p(gcd,t,&s);
                    459:     if ( NUM(s) ) {
                    460:       *g = (P)ONE; *h = p1; *a = 0; *b = (P)ONE;
                    461:       return;
                    462:     } else
                    463:       gcd = s;
                    464:   }
                    465:
                    466:   if ( !dcomp(p1,gcd) ) {
                    467:     *g = p1; *h = (P)ONE; *a = 0; *b = (P)ONE;
                    468:     return;
                    469:   }
                    470:
                    471:   divsp(CO,p1,gcd,&cof);
                    472:   d = UDEG(p1)+1;
                    473:   wg = W_UMALLOC(d); wh = W_UMALLOC(d);
                    474:   wg1 = W_UMALLOC(d); wh1 = W_UMALLOC(d);
                    475:   wgcd = W_UMALLOC(d); wt = W_UMALLOC(d);
                    476:   for ( index = INDEX; ; ) {
                    477:     mod = sprime[index++];
                    478:     if ( !remqi((Q)LC(p1),mod) )
                    479:       continue;
                    480:     ptoum(mod,gcd,wg); ptoum(mod,cof,wh);
                    481:     cpyum(wg,wg1); cpyum(wh,wh1);
                    482:     gcdum(mod,wg,wh,wt); cpyum(wt,wgcd);
                    483:     if ( DEG(wgcd) > 0 )
                    484:       continue;
1.2     ! noro      485:     STOZ(mod,tq); addq(cbd,cbd,&bb);
1.1       noro      486:     for ( k = 1; cmpq((Q)tq,bb) < 0; k++ ) {
                    487:       mulz(tq,tq,&tq1); tq = tq1;
                    488:     }
                    489:     henzq(p1,gcd,wg1,cof,wh1,mod,k,&gk,&hk,&bk,&ak,&qk);
                    490:     break;
                    491:   }
                    492:   *g = gk; *h = hk; *a = ak; *b = bk; *q = tq;
                    493: }
                    494:
                    495: void ezgcdhensel(P f,int mod,UM cof,UM gcd,ML *listp)
                    496: {
                    497:   register int i,j;
                    498:   int q,n,bound;
                    499:   int *p;
                    500:   int **pp;
                    501:   ML blist,clist,bqlist,cqlist,rlist;
                    502:   UM *b;
                    503:   LUM fl,tl;
                    504:   LUM *l;
                    505:   LUM LUMALLOC();
                    506:
                    507:   blist = W_MLALLOC(2);
                    508:   blist->n = 2; blist->mod = mod;
                    509:   blist->c[0] = (pointer)cof; blist->c[1] = (pointer)gcd;
                    510:   gcdgen(f,blist,&clist);
                    511:   henprep(f,blist,clist,&bqlist,&cqlist);
                    512:   n = bqlist->n; q = bqlist->mod;
                    513:   bqlist->bound = cqlist->bound = bound = mignotte(q,f);
                    514:
                    515:   if ( bound == 1 ) {
                    516:     *listp = rlist = MLALLOC(n);
                    517:     rlist->n = n;
                    518:     rlist->mod = q;
                    519:     rlist->bound = bound;
                    520:
                    521:     for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c;
                    522:       i < n; i++ ) {
                    523:       tl = LUMALLOC(DEG(b[i]),1);
                    524:       l[i] = tl;
                    525:       p = COEF(b[i]);
                    526:
                    527:       for ( j = 0, pp = COEF(tl);
                    528:           j <= DEG(tl); j++ )
                    529:           pp[j][0] = p[j];
                    530:     }
                    531:   } else {
                    532:     W_LUMALLOC((int)UDEG(f),bound,fl);
                    533:     ptolum(q,bound,f,fl);
                    534:     henmain(fl,bqlist,cqlist,listp);
                    535:   }
                    536: }
                    537:
                    538: void ezgcdnpz(VL vl,P *ps,int m,P *pr)
                    539: {
                    540:   P t,s,gcd;
                    541:   P cont;
                    542:   VL tvl,svl,nvl;
                    543:   int i;
                    544:   DCP dc;
                    545:   Z cq;
                    546:   P *pl,*ppl,*pcl;
                    547:   Z *cl;
                    548:   V v;
                    549:
                    550:   pl = (P *)ALLOCA((m+1)*sizeof(P));
                    551:   cl = (Z *)ALLOCA((m+1)*sizeof(Q));
                    552:   for ( i = 0; i < m; i++ )
                    553:     ptozp(ps[i],1,(Q *)&cl[i],&pl[i]);
                    554:   for ( i = 1, cq = cl[0]; i < m; i++ ) {
                    555:     gcdz(cl[i],cq,&cq);
                    556:   }
                    557:   for ( i = 0; i < m; i++ )
                    558:     if ( NUM(pl[i]) ) {
                    559:       *pr = (P)cq;
                    560:       return;
                    561:     }
                    562:
                    563:   for ( i = 0, nvl = 0; i < m; i++ ) {
                    564:     clctv(vl,ps[i],&tvl); mergev(vl,nvl,tvl,&svl); nvl = svl;
                    565:   }
                    566:
                    567:   ppl = (P *)ALLOCA((m+1)*sizeof(P));
                    568:   pcl = (P *)ALLOCA((m+1)*sizeof(P));
                    569:   for ( i = 0, v = nvl->v; i < m; i++ )
                    570:     if ( v == VR(pl[i]) )
                    571:       pcp(nvl,pl[i],&ppl[i],&pcl[i]);
                    572:     else {
                    573:       ppl[i] = (P)ONE; pcl[i] = pl[i];
                    574:     }
                    575:   ezgcdnpz(nvl,pcl,m,&cont);
                    576:
                    577:   for ( i = 0; i < m; i++ )
                    578:     if ( NUM(ppl[i]) ) {
                    579:       mulp(nvl,cont,(P)cq,pr);
                    580:       return;
                    581:     }
                    582:   sortplist(ppl,m);
                    583:   sqfrp(nvl,ppl[0],&dc);
                    584:   for ( dc = NEXT(dc), gcd = (P)ONE; dc; dc = NEXT(dc) ) {
                    585:     if ( NUM(COEF(dc)) )
                    586:       continue;
                    587:     ezgcdnpp(vl,dc,ppl+1,m-1,&t);
                    588:     if ( NUM(t) )
                    589:       continue;
                    590:     mulp(vl,gcd,t,&s); gcd = s;
                    591:   }
                    592:   mulp(vl,gcd,cont,&t); mulp(vl,t,(P)cq,pr);
                    593: }
                    594:
                    595: void ezgcdnpp(VL vl,DCP dc,P *pl,int m,P *r)
                    596: {
                    597:   int i,k;
                    598:   P g,t,s,gcd;
                    599:   P *pm;
                    600:
                    601:   ezgcdnp(vl,COEF(dc),pl,m,&gcd);
                    602:   if ( NUM(gcd) ) {
                    603:     *r = (P)ONE;
                    604:     return;
                    605:   }
                    606:   pm = (P *) ALLOCA((m+1)*sizeof(P));
                    607:   for ( i = 0; i < m; i++ ) {
                    608:     divsp(vl,pl[i],gcd,&pm[i]);
                    609:     if ( NUM(pm[i]) ) {
                    610:       *r = gcd;
                    611:       return;
                    612:     }
                    613:   }
1.2     ! noro      614:   for ( g = gcd, k = ZTOS(DEG(dc)) - 1; k > 0; k-- ) {
1.1       noro      615:     ezgcdnp(vl,g,pm,m,&t);
                    616:     if ( NUM(t) )
                    617:       break;
                    618:     mulp(vl,gcd,t,&s); gcd = s;
                    619:     for ( i = 0; i < m; i++ ) {
                    620:       divsp(vl,pm[i],t,&s);
                    621:       if ( NUM(s) ) {
                    622:         *r = gcd;
                    623:         return;
                    624:       }
                    625:       pm[i] = s;
                    626:     }
                    627:   }
                    628:   *r = gcd;
                    629: }
                    630:
                    631: void pcp(VL vl,P p,P *pp,P *c)
                    632: {
                    633:   P f,g,n;
                    634:   DCP dc;
                    635:   P *pl;
                    636:   int i,m;
                    637:   extern int nez;
                    638:
                    639:   if ( NUM(p) ) {
                    640:     *c = p;
                    641:     *pp = (P)ONE;
                    642:   } else {
                    643:     for ( m = 0, dc = DC(p); dc; dc = NEXT(dc), m++ );
                    644:     if ( m == 1 ) {
                    645:       *c = COEF(DC(p));
                    646:       divsp(vl,p,*c,pp);
                    647:       return;
                    648:     }
                    649:     ptozp(p,1,(Q *)&n,&f);
                    650:     pl = (P *)ALLOCA((m+1)*sizeof(P));
                    651:     for ( i = 0, dc = DC(f); i < m; dc = NEXT(dc), i++ )
                    652:       pl[i] = COEF(dc);
                    653:     if ( nez )
                    654:       nezgcdnpz(vl,pl,m,&g);
                    655:     else
                    656:       ezgcdnpz(vl,pl,m,&g);
                    657:     mulp(vl,g,n,c); divsp(vl,f,g,pp);
                    658:   }
                    659: }
                    660:
                    661: int divcheck(VL vl,P *ps,int m,P l,P p)
                    662: {
                    663:   int i;
                    664:   P r,t;
                    665:
                    666:   for ( i = 0; i < m; i++ ) {
                    667:     mulp(vl,ps[i],l,&t);
                    668:     if ( !divtpz(vl,t,p,&r) )
                    669:       return ( 0 );
                    670:   }
                    671:   return ( 1 );
                    672: }
                    673:
                    674: void sortplist(P *plist,int n)
                    675: {
                    676:   int i,j;
                    677:   P t;
                    678:
                    679:   for ( i = 0; i < n; i++ )
                    680:     for ( j = i + 1; j < n; j++ )
                    681:       if ( cmpz(DEG(DC(plist[i])),DEG(DC(plist[j]))) > 0 ) {
                    682:         t = plist[i]; plist[i] = plist[j]; plist[j] = t;
                    683:       }
                    684: }
                    685:
                    686: int dcomp(P p1,P p2)
                    687: {
                    688:   return ( cmpz(DEG(DC(p1)),DEG(DC(p2))) );
                    689: }

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