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

Annotation of OpenXM_contrib2/asir2000/engine/dalg.c, Revision 1.18

1.1       noro        1: /*
1.18    ! noro        2:  * $OpenXM: OpenXM_contrib2/asir2000/engine/dalg.c,v 1.17 2017/08/31 02:36:21 noro Exp $
1.1       noro        3: */
                      4:
                      5: #include "ca.h"
                      6: #include "base.h"
                      7:
                      8: static NumberField current_numberfield;
                      9: extern struct order_spec *dp_current_spec;
1.2       noro       10: void simpdalg(DAlg da,DAlg *r);
1.8       noro       11: int invdalg(DAlg a,DAlg *c);
1.3       noro       12: void rmcontdalg(DAlg a, DAlg *c);
1.6       noro       13: void algtodalg(Alg a,DAlg *r);
                     14: void dalgtoalg(DAlg da,Alg *r);
1.1       noro       15:
1.5       noro       16: NumberField get_numberfield()
                     17: {
1.18    ! noro       18:   return current_numberfield;
1.5       noro       19: }
                     20:
1.1       noro       21: void setfield_dalg(NODE alist)
                     22: {
1.18    ! noro       23:   NumberField nf;
        !            24:   VL vl,vl1,vl2;
        !            25:   int n,i,dim;
        !            26:   Alg *gen;
        !            27:   P *defpoly;
        !            28:   P p;
        !            29:   Q c,iq,two;
        !            30:   DP *ps,*mb;
        !            31:   DP one;
        !            32:   NODE t,b,b1,b2,hlist,mblist;
        !            33:   struct order_spec *current_spec;
        !            34:
        !            35:   nf = (NumberField)MALLOC(sizeof(struct oNumberField));
        !            36:   current_numberfield = nf;
        !            37:   vl = 0;
        !            38:   for ( t = alist; t; t = NEXT(t) ) {
        !            39:     clctalg((P)BDY((Alg)BDY(t)),&vl1);
        !            40:     mergev(ALG,vl,vl1,&vl2); vl = vl2;
        !            41:   }
        !            42:   for ( n = 0, vl1 = vl; vl1; vl1 = NEXT(vl1), n++ );
        !            43:   nf->n = n;
        !            44:   nf->vl = vl;
        !            45:   nf->defpoly = defpoly = (P *)MALLOC(n*sizeof(P));
        !            46:   nf->ps = ps = (DP *)MALLOC(n*sizeof(DP));
        !            47:   current_spec = dp_current_spec;
        !            48:   STOQ(2,two);
        !            49:   create_order_spec(0,(Obj)two,&nf->spec);
        !            50:   initd(nf->spec);
        !            51:   for ( b = hlist = 0, i = 0, vl1 = vl; i < n; vl1 = NEXT(vl1), i++ ) {
        !            52:     ptozp(vl1->v->attr,1,&c,&defpoly[i]);
        !            53:     ptod(ALG,vl,defpoly[i],&ps[i]);
        !            54:     STOQ(i,iq); MKNODE(b1,(pointer)iq,b); b = b1;
        !            55:     MKNODE(b2,(pointer)ps[i],hlist); hlist = b2;
        !            56:   }
        !            57:   ptod(ALG,vl,(P)ONE,&one);
        !            58:   MKDAlg(one,ONE,nf->one);
        !            59:   nf->ind = b;
        !            60:   dp_mbase(hlist,&mblist);
        !            61:   initd(current_spec);
        !            62:   nf->dim = dim = length(mblist);
        !            63:   nf->mb = mb = (DP *)MALLOC(dim*sizeof(DP));
        !            64:   for ( i = 0, t = mblist; t; t = NEXT(t), i++ )
        !            65:     mb[dim-i-1] = (DP)BDY(t);
1.1       noro       66: }
                     67:
1.10      noro       68: void setfield_gb(NODE gb,VL vl,struct order_spec *spec)
                     69: {
1.18    ! noro       70:   NumberField nf;
        !            71:   VL vl1,vl2;
        !            72:   int n,i,dim;
        !            73:   Alg *gen;
        !            74:   P *defpoly;
        !            75:   P p;
        !            76:   Q c,iq,two;
        !            77:   DP *ps,*mb;
        !            78:   DP one;
        !            79:   NODE t,b,b1,b2,hlist,mblist;
        !            80:   struct order_spec *current_spec;
        !            81:
        !            82:   nf = (NumberField)MALLOC(sizeof(struct oNumberField));
        !            83:   current_numberfield = nf;
        !            84:   for ( vl1 = vl, n = 0; vl1; vl1 = NEXT(vl1), n++ );
        !            85:   nf->n = n;
        !            86:   nf->psn = length(gb);
        !            87:   nf->vl = vl;
        !            88:   nf->defpoly = defpoly = (P *)MALLOC(nf->psn*sizeof(P));
        !            89:   nf->ps = ps = (DP *)MALLOC(nf->psn*sizeof(DP));
        !            90:   current_spec = dp_current_spec;
        !            91:   nf->spec = spec;
        !            92:   initd(nf->spec);
        !            93:   for ( b = hlist = 0, i = 0, t = gb; i < nf->psn; t = NEXT(t), i++ ) {
        !            94:     ptozp((P)BDY(t),1,&c,&defpoly[i]);
        !            95:     ptod(CO,vl,defpoly[i],&ps[i]);
        !            96:     STOQ(i,iq); MKNODE(b1,(pointer)iq,b); b = b1;
        !            97:     MKNODE(b2,(pointer)ps[i],hlist); hlist = b2;
        !            98:   }
        !            99:   ptod(ALG,vl,(P)ONE,&one);
        !           100:   MKDAlg(one,ONE,nf->one);
        !           101:   nf->ind = b;
        !           102:   dp_mbase(hlist,&mblist);
        !           103:   initd(current_spec);
        !           104:   nf->dim = dim = length(mblist);
        !           105:   nf->mb = mb = (DP *)MALLOC(dim*sizeof(DP));
        !           106:   for ( i = 0, t = mblist; t; t = NEXT(t), i++ )
        !           107:     mb[dim-i-1] = (DP)BDY(t);
1.10      noro      108: }
                    109:
1.4       noro      110: void qtodalg(Q q,DAlg *r)
                    111: {
1.18    ! noro      112:   NumberField nf;
        !           113:   Q t;
        !           114:   DP nm;
        !           115:
        !           116:   if ( !(nf=current_numberfield) )
        !           117:     error("qtodalg : current_numberfield is not set");
        !           118:   if ( !q )
        !           119:     *r = 0;
        !           120:   else if ( NID(q) == N_DA )
        !           121:     *r = (DAlg)q;
        !           122:   else if ( NID(q) == N_Q ) {
        !           123:     if ( INT(q) ) {
        !           124:       muldc(CO,nf->one->nm,(Obj)q,&nm);
        !           125:       MKDAlg(nm,ONE,*r);
        !           126:     } else {
        !           127:       NTOQ(NM(q),SGN(q),t);
        !           128:       muldc(CO,nf->one->nm,(Obj)t,&nm);
        !           129:       NTOQ(DN(q),1,t);
        !           130:       MKDAlg(nm,t,*r);
        !           131:     }
        !           132:   } else
        !           133:     error("qtodalg : invalid argument");
1.6       noro      134: }
                    135:
                    136: void obj_algtodalg(Obj obj,Obj *r)
                    137: {
1.18    ! noro      138:   DAlg d;
        !           139:   DCP dc,dcr0,dcr;
        !           140:   P c,p;
        !           141:   Obj t;
        !           142:   Obj nm,dn;
        !           143:   NODE b,s,s0;
        !           144:   R rat;
        !           145:   VECT v;
        !           146:   MAT mat;
        !           147:   LIST list;
        !           148:   pointer *a;
        !           149:   pointer **m;
        !           150:   int len,row,col,i,j,l;
        !           151:
        !           152:   if ( !obj ) {
        !           153:     *r = 0;
        !           154:     return;
        !           155:   }
        !           156:   switch ( OID(obj) ) {
        !           157:     case O_N:
        !           158:       algtodalg((Alg)obj,&d); *r = (Obj)d;
        !           159:       break;
        !           160:     case O_P:
        !           161:       for ( dcr0 = 0, dc = DC((P)obj); dc; dc = NEXT(dc) ) {
        !           162:         obj_algtodalg((Obj)COEF(dc),&t);
        !           163:         if ( t ) {
        !           164:           NEXTDC(dcr0,dcr);
        !           165:           COEF(dcr) = (P)t;
        !           166:           DEG(dcr) = DEG(dc);
        !           167:         }
        !           168:       }
        !           169:       if ( dcr0 ) {
        !           170:         MKP(VR((P)obj),dcr0,p);
        !           171:         *r = (Obj)p;
        !           172:       } else
        !           173:         *r = 0;
        !           174:       break;
        !           175:     case O_R:
        !           176:       obj_algtodalg((Obj)NM((R)obj),&nm);
        !           177:       obj_algtodalg((Obj)DN((R)obj),&dn);
        !           178:       if ( !dn )
        !           179:         error("obj_algtodalg : division by 0");
        !           180:       if ( !nm )
        !           181:         *r = 0;
        !           182:       else {
        !           183:         MKRAT((P)nm,(P)dn,0,rat); *r = (Obj)rat;
        !           184:       }
        !           185:       break;
        !           186:     case O_LIST:
        !           187:       s0 = 0;
        !           188:       for ( b = BDY((LIST)obj); b; b = NEXT(b) ) {
        !           189:         NEXTNODE(s0,s);
        !           190:         obj_algtodalg((Obj)BDY(b),&t);
        !           191:         BDY(s) = (pointer)t;
        !           192:       }
        !           193:       NEXT(s) = 0;
        !           194:       MKLIST(list,s0);
        !           195:       *r = (Obj)list;
        !           196:       break;
        !           197:     case O_VECT:
        !           198:       l = ((VECT)obj)->len;
        !           199:       a = BDY((VECT)obj);
        !           200:       MKVECT(v,l);
        !           201:       for ( i = 0; i < l; i++ ) {
        !           202:         obj_algtodalg((Obj)a[i],&t);
        !           203:         BDY(v)[i] = (pointer)t;
        !           204:       }
        !           205:       *r = (Obj)v;
        !           206:       break;
        !           207:     case O_MAT:
        !           208:       row = ((MAT)obj)->row; col = ((MAT)obj)->col;
        !           209:       m = BDY((MAT)obj);
        !           210:       MKMAT(mat,row,col);
        !           211:       for ( i = 0; i < row; i++ )
        !           212:         for ( j = 0; j < col; j++ ) {
        !           213:           obj_algtodalg((Obj)m[i][j],&t);
        !           214:           BDY(mat)[i][j] = (pointer)t;
        !           215:         }
        !           216:       *r = (Obj)mat;
        !           217:       break;
        !           218:     default:
        !           219:       *r = obj;
        !           220:       break;
        !           221:   }
1.6       noro      222: }
                    223:
                    224: void obj_dalgtoalg(Obj obj,Obj *r)
                    225: {
1.18    ! noro      226:   Alg d;
        !           227:   DCP dc,dcr0,dcr;
        !           228:   P c,p;
        !           229:   Obj t;
        !           230:   Obj nm,dn;
        !           231:   NODE b,s,s0;
        !           232:   R rat;
        !           233:   VECT v;
        !           234:   MAT mat;
        !           235:   LIST list;
        !           236:   pointer *a;
        !           237:   pointer **m;
        !           238:   int len,row,col,i,j,l;
        !           239:
        !           240:   if ( !obj ) {
        !           241:     *r = 0;
        !           242:     return;
        !           243:   }
        !           244:   switch ( OID(obj) ) {
        !           245:     case O_N:
        !           246:       dalgtoalg((DAlg)obj,&d); *r = (Obj)d;
        !           247:       break;
        !           248:     case O_P:
        !           249:       for ( dcr0 = 0, dc = DC((P)obj); dc; dc = NEXT(dc) ) {
        !           250:         obj_dalgtoalg((Obj)COEF(dc),&t);
        !           251:         if ( t ) {
        !           252:           NEXTDC(dcr0,dcr);
        !           253:           COEF(dcr) = (P)t;
        !           254:           DEG(dcr) = DEG(dc);
        !           255:         }
        !           256:       }
        !           257:       if ( dcr0 ) {
        !           258:         MKP(VR((P)obj),dcr0,p);
        !           259:         *r = (Obj)p;
        !           260:       } else
        !           261:         *r = 0;
        !           262:       break;
        !           263:     case O_R:
        !           264:       obj_dalgtoalg((Obj)NM((R)obj),&nm);
        !           265:       obj_dalgtoalg((Obj)DN((R)obj),&dn);
        !           266:       if ( !dn )
        !           267:         error("obj_dalgtoalg : division by 0");
        !           268:       if ( !nm )
        !           269:         *r = 0;
        !           270:       else {
        !           271:         MKRAT((P)nm,(P)dn,0,rat); *r = (Obj)rat;
        !           272:       }
        !           273:       break;
        !           274:     case O_LIST:
        !           275:       s0 = 0;
        !           276:       for ( b = BDY((LIST)obj); b; b = NEXT(b) ) {
        !           277:         NEXTNODE(s0,s);
        !           278:         obj_dalgtoalg((Obj)BDY(b),&t);
        !           279:         BDY(s) = (pointer)t;
        !           280:       }
        !           281:       NEXT(s) = 0;
        !           282:       MKLIST(list,s0);
        !           283:       *r = (Obj)list;
        !           284:       break;
        !           285:     case O_VECT:
        !           286:       l = ((VECT)obj)->len;
        !           287:       a = BDY((VECT)obj);
        !           288:       MKVECT(v,l);
        !           289:       for ( i = 0; i < l; i++ ) {
        !           290:         obj_dalgtoalg((Obj)a[i],&t);
        !           291:         BDY(v)[i] = (pointer)t;
        !           292:       }
        !           293:       *r = (Obj)v;
        !           294:       break;
        !           295:     case O_MAT:
        !           296:       row = ((MAT)obj)->row; col = ((MAT)obj)->col;
        !           297:       m = BDY((MAT)obj);
        !           298:       MKMAT(mat,row,col);
        !           299:       for ( i = 0; i < row; i++ )
        !           300:         for ( j = 0; j < col; j++ ) {
        !           301:           obj_dalgtoalg((Obj)m[i][j],&t);
        !           302:           BDY(mat)[i][j] = (pointer)t;
        !           303:         }
        !           304:       *r = (Obj)mat;
        !           305:       break;
        !           306:     default:
        !           307:       *r = obj;
        !           308:       break;
        !           309:   }
1.4       noro      310: }
                    311:
1.1       noro      312: void algtodalg(Alg a,DAlg *r)
                    313: {
1.18    ! noro      314:   P ap,p,p1;
        !           315:   Q c,c1,d1,dn,nm;
        !           316:   DP dp;
        !           317:   DAlg da;
        !           318:   NumberField nf;
        !           319:   struct order_spec *current_spec;
        !           320:   VL vl,tvl,svl;
        !           321:   V v;
        !           322:
        !           323:   if ( !(nf=current_numberfield) )
        !           324:     error("algtodalg : current_numberfield is not set");
        !           325:   if ( !a ) {
        !           326:     *r = 0;
        !           327:     return;
        !           328:   }
        !           329:   switch (NID((Num)a) ) {
        !           330:     case N_Q:
        !           331:       c = (Q)a;
        !           332:       if ( INT(c) ) {
        !           333:         muldc(CO,nf->one->nm,(Obj)c,&dp);
        !           334:         MKDAlg(dp,ONE,*r);
        !           335:       } else {
        !           336:         NTOQ(NM(c),SGN(c),c1);
        !           337:         NTOQ(DN(c),1,d1);
        !           338:         muldc(CO,nf->one->nm,(Obj)c1,&dp);
        !           339:         MKDAlg(dp,d1,*r);
        !           340:       }
        !           341:       break;
        !           342:     case N_A:
        !           343:       ap = (P)BDY(a);
        !           344:       ptozp(ap,1,&c,&p);
        !           345:       if ( INT(c) ) {
        !           346:         p = ap;
        !           347:         dn = ONE;
        !           348:       } else {
        !           349:         NTOQ(NM(c),SGN(c),nm);
        !           350:         NTOQ(DN(c),1,dn);
        !           351:         mulpq(p,(P)nm,&p1); p = p1;
        !           352:       }
        !           353:       current_spec = dp_current_spec; initd(nf->spec);
        !           354:       get_vars((Obj)p,&vl);
        !           355:       for ( tvl = vl; tvl; tvl = NEXT(tvl) ) {
        !           356:         v = tvl->v;
        !           357:         for ( svl = nf->vl; svl; svl = NEXT(svl) )
        !           358:           if ( v == svl->v )
        !           359:             break;
        !           360:         if ( !svl )
        !           361:           error("algtodalg : incompatible numberfield");
        !           362:       }
        !           363:       ptod(ALG,nf->vl,p,&dp);
        !           364:       MKDAlg(dp,dn,da);
        !           365:       simpdalg(da,r);
        !           366:       break;
        !           367:     default:
        !           368:       error("algtodalg : invalid argument");
        !           369:       break;
        !           370:   }
1.1       noro      371: }
                    372:
1.2       noro      373: void dalgtoalg(DAlg da,Alg *r)
1.1       noro      374: {
1.18    ! noro      375:   NumberField nf;
        !           376:   P p,p1;
        !           377:   Q inv;
        !           378:
        !           379:   if ( !(nf=current_numberfield) )
        !           380:     error("dalgtoalg : current_numberfield is not set");
        !           381:   if ( !da ) *r = 0;
        !           382:   else {
        !           383:     dtop(ALG,nf->vl,da->nm,(Obj *)&p);
        !           384:     invq(da->dn,&inv);
        !           385:     mulpq(p,(P)inv,&p1);
        !           386:     MKAlg(p1,*r);
        !           387:   }
1.1       noro      388: }
                    389:
                    390: void simpdalg(DAlg da,DAlg *r)
                    391: {
1.18    ! noro      392:   NumberField nf;
        !           393:   DP nm;
        !           394:   DAlg d;
        !           395:   Q dn,dn1;
        !           396:   struct order_spec *current_spec;
        !           397:
        !           398:   if ( !(nf=current_numberfield) )
        !           399:     error("simpdalg : current_numberfield is not set");
        !           400:   if ( !da ) {
        !           401:     *r = 0;
        !           402:     return;
        !           403:   }
        !           404:   current_spec = dp_current_spec; initd(nf->spec);
        !           405:   dp_true_nf(nf->ind,da->nm,nf->ps,1,&nm,(P *)&dn);
        !           406:   if ( !nm ) *r = 0;
        !           407:   else {
        !           408:     initd(current_spec);
        !           409:     mulq(da->dn,dn,&dn1);
        !           410:     MKDAlg(nm,dn1,d);
        !           411:     rmcontdalg(d,r);
        !           412:   }
1.1       noro      413: }
                    414:
                    415: void adddalg(DAlg a,DAlg b,DAlg *c)
                    416: {
1.18    ! noro      417:   NumberField nf;
        !           418:   Q dna,dnb,a1,b1,dn,g;
        !           419:   N an,bn,gn;
        !           420:   DAlg t;
        !           421:   DP ta,tb,nm;
        !           422:   struct order_spec *current_spec;
        !           423:
        !           424:   if ( !(nf=current_numberfield) )
        !           425:     error("adddalg : current_numberfield is not set");
        !           426:   if ( !a )
        !           427:     *c = b;
        !           428:   else if ( !b )
        !           429:     *c = a;
        !           430:   else {
        !           431:     qtodalg((Q)a,&t); a = t; qtodalg((Q)b,&t); b = t;
        !           432:     dna = a->dn;
        !           433:     dnb = b->dn;
        !           434:     gcdn(NM(dna),NM(dnb),&gn);
        !           435:     divsn(NM(dna),gn,&an); divsn(NM(dnb),gn,&bn);
        !           436:     NTOQ(an,SGN(dna),a1); NTOQ(bn,SGN(dnb),b1);
        !           437:     /* nma/dna+nmb/dnb = (nma*b1+nmb*a1)/(dna*b1) */
        !           438:     muldc(CO,a->nm,(Obj)b1,&ta); muldc(CO,b->nm,(Obj)a1,&tb);
        !           439:     current_spec = dp_current_spec; initd(nf->spec);
        !           440:     addd(CO,ta,tb,&nm);
        !           441:     initd(current_spec);
        !           442:     if ( !nm )
        !           443:       *c = 0;
        !           444:     else {
        !           445:       mulq(dna,b1,&dn);
        !           446:       MKDAlg(nm,dn,*c);
        !           447:     }
        !           448:   }
1.1       noro      449: }
                    450:
                    451: void subdalg(DAlg a,DAlg b,DAlg *c)
                    452: {
1.18    ! noro      453:   NumberField nf;
        !           454:   Q dna,dnb,a1,b1,dn,g;
        !           455:   N an,bn,gn;
        !           456:   DP ta,tb,nm;
        !           457:   DAlg t;
        !           458:   struct order_spec *current_spec;
        !           459:
        !           460:   if ( !(nf=current_numberfield) )
        !           461:     error("subdalg : current_numberfield is not set");
        !           462:   if ( !a )
        !           463:     *c = b;
        !           464:   else if ( !b )
        !           465:     *c = a;
        !           466:   else {
        !           467:     qtodalg((Q)a,&t); a = t; qtodalg((Q)b,&t); b = t;
        !           468:     dna = a->dn;
        !           469:     dnb = b->dn;
        !           470:     gcdn(NM(dna),NM(dnb),&gn);
        !           471:     divsn(NM(dna),gn,&an); divsn(NM(dnb),gn,&bn);
        !           472:     NTOQ(an,SGN(dna),a1); NTOQ(bn,SGN(dnb),b1);
        !           473:     /* nma/dna-nmb/dnb = (nma*b1-nmb*a1)/(dna*b1) */
        !           474:     muldc(CO,a->nm,(Obj)b1,&ta); muldc(CO,b->nm,(Obj)a1,&tb);
        !           475:     current_spec = dp_current_spec; initd(nf->spec);
        !           476:     subd(CO,ta,tb,&nm);
        !           477:     initd(current_spec);
        !           478:     if ( !nm )
        !           479:       *c = 0;
        !           480:     else {
        !           481:       mulq(dna,b1,&dn);
        !           482:       MKDAlg(nm,dn,*c);
        !           483:     }
        !           484:   }
1.1       noro      485: }
                    486:
1.2       noro      487: void muldalg(DAlg a,DAlg b,DAlg *c)
                    488: {
1.18    ! noro      489:   NumberField nf;
        !           490:   DP nm;
        !           491:   Q dn;
        !           492:   DAlg t;
        !           493:   struct order_spec *current_spec;
        !           494:
        !           495:   if ( !(nf=current_numberfield) )
        !           496:     error("muldalg : current_numberfield is not set");
        !           497:   if ( !a || !b )
        !           498:     *c = 0;
        !           499:   else {
        !           500:     qtodalg((Q)a,&t); a = t; qtodalg((Q)b,&t); b = t;
        !           501:     current_spec = dp_current_spec; initd(nf->spec);
        !           502:     muld(CO,a->nm,b->nm,&nm);
        !           503:     initd(current_spec);
        !           504:     mulq(a->dn,b->dn,&dn);
        !           505:     MKDAlg(nm,dn,t);
        !           506:     simpdalg(t,c);
        !           507:   }
1.2       noro      508: }
                    509:
                    510:
1.1       noro      511: void divdalg(DAlg a,DAlg b,DAlg *c)
                    512: {
1.18    ! noro      513:   DAlg inv,t;
        !           514:   int ret;
1.3       noro      515:
1.18    ! noro      516:   if ( !current_numberfield )
        !           517:     error("divdalg : current_numberfield is not set");
        !           518:   if ( !b )
        !           519:     error("divdalg : division by 0");
        !           520:   if ( !a )
        !           521:     c = 0;
        !           522:   else {
        !           523:     qtodalg((Q)a,&t); a = t; qtodalg((Q)b,&t); b = t;
        !           524:     ret = invdalg(b,&inv);
        !           525:     if ( !ret ) {
        !           526:       error("divdalg : the denominator is not invertible");
        !           527:     }
        !           528:     muldalg(a,inv,c);
        !           529:   }
1.3       noro      530: }
                    531:
                    532: void rmcontdalg(DAlg a, DAlg *r)
                    533: {
1.18    ! noro      534:   DP u,u1;
        !           535:   Q cont,c,d;
        !           536:   N gn,cn,dn;
        !           537:
        !           538:   if ( !a )
        !           539:     *r = a;
        !           540:   else {
        !           541:     dp_ptozp(a->nm,&u);
        !           542:     divq((Q)BDY(a->nm)->c,(Q)BDY(u)->c,&cont);
        !           543:     gcdn(NM(cont),NM(a->dn),&gn);
        !           544:     divsn(NM(cont),gn,&cn); NTOQ(cn,SGN(cont),c);
        !           545:     divsn(NM(a->dn),gn,&dn); NTOQ(dn,SGN(a->dn),d);
        !           546:     muldc(CO,u,(Obj)c,&u1);
        !           547:     MKDAlg(u1,d,*r);
        !           548:   }
1.1       noro      549: }
                    550:
1.8       noro      551: int invdalg(DAlg a,DAlg *c)
1.1       noro      552: {
1.18    ! noro      553:   NumberField nf;
        !           554:   int dim,n,i,j,k,l;
        !           555:   DP *mb;
        !           556:   DP m,d,u;
        !           557:   N ln,gn,qn;
        !           558:   DAlg *simp;
        !           559:   DAlg t,a0,r;
        !           560:   Q dn,dnsol,mul,nmc,dn1;
        !           561:   MAT mobj,sol;
        !           562:   Q **mat,**solmat;
        !           563:   MP mp0,mp;
        !           564:   int *rinfo,*cinfo;
        !           565:   int rank,nparam;
        !           566:   NODE nd0,nd,ndt;
        !           567:   struct order_spec *current_spec;
        !           568:   struct oEGT eg0,eg1;
        !           569:   extern struct oEGT eg_le;
        !           570:
        !           571:   if ( !(nf=current_numberfield) )
        !           572:     error("invdalg : current_numberfield is not set");
        !           573:   if ( !a )
        !           574:     error("invdalg : division by 0");
        !           575:   else if ( NID(a) == N_Q ) {
        !           576:     invq((Q)a,&dn); *c = (DAlg)dn;
        !           577:     return 1;
        !           578:   }
        !           579:   dim = nf->dim;
        !           580:   mb = nf->mb;
        !           581:   n = nf->n;
        !           582:   ln = ONEN;
        !           583:   dp_ptozp(a->nm,&u); divq((Q)BDY(a->nm)->c,(Q)BDY(u)->c,&nmc);
        !           584:   MKDAlg(u,ONE,a0);
        !           585:   simp = (DAlg *)ALLOCA(dim*sizeof(DAlg));
        !           586:   current_spec = dp_current_spec; initd(nf->spec);
        !           587:   for ( i = 0; i < dim; i++ ) {
        !           588:     m = mb[i];
        !           589:     for ( j = i-1; j >= 0; j-- )
        !           590:       if ( dp_redble(m,mb[j]) )
        !           591:         break;
        !           592:     if ( j >= 0 ) {
        !           593:       dp_subd(m,mb[j],&d);
        !           594:       muld(CO,d,simp[j]->nm,&u);
        !           595:       MKDAlg(u,simp[j]->dn,t);
        !           596:       simpdalg(t,&simp[i]);
        !           597:     } else {
        !           598:       MKDAlg(m,ONE,t);
        !           599:       muldalg(t,a0,&simp[i]);
        !           600:     }
        !           601:     gcdn(NM(simp[i]->dn),ln,&gn); divsn(ln,gn,&qn);
        !           602:     muln(NM(simp[i]->dn),qn,&ln);
        !           603:   }
        !           604:   initd(current_spec);
        !           605:   NTOQ(ln,1,dn);
        !           606:   MKMAT(mobj,dim,dim+1);
        !           607:   mat = (Q **)BDY(mobj);
        !           608:   mulq(dn,a->dn,&mat[0][dim]);
        !           609:   for ( j = 0; j < dim; j++ ) {
        !           610:     divq(dn,simp[j]->dn,&mul);
        !           611:     for ( i = dim-1, mp = BDY(simp[j]->nm); mp && i >= 0; i-- )
        !           612:       if ( dl_equal(n,BDY(mb[i])->dl,mp->dl) ) {
        !           613:         mulq(mul,(Q)mp->c,&mat[i][j]);
        !           614:         mp = NEXT(mp);
        !           615:       }
        !           616:   }
        !           617:   get_eg(&eg0);
        !           618:   rank = generic_gauss_elim_hensel(mobj,&sol,&dnsol,&rinfo,&cinfo);
        !           619:   get_eg(&eg1); add_eg(&eg_le,&eg0,&eg1);
        !           620:   if ( cinfo[0] == dim ) {
        !           621:     /* the input is invertible */
        !           622:     solmat = (Q **)BDY(sol);
        !           623:     for ( i = dim-1, mp0 = 0; i >= 0; i-- )
        !           624:       if ( solmat[i][0] ) {
        !           625:         NEXTMP(mp0,mp);
        !           626:         mp->c = (Obj)solmat[i][0];
        !           627:         mp->dl = BDY(mb[i])->dl;
        !           628:       }
        !           629:     NEXT(mp) = 0; MKDP(n,mp0,u);
        !           630:     mulq(dnsol,nmc,&dn1);
        !           631:     MKDAlg(u,dn1,r);
        !           632:     rmcontdalg(r,c);
        !           633:     return 1;
        !           634:   } else
        !           635:     return 0;
1.8       noro      636: }
                    637:
                    638: NODE inv_or_split_dalg(DAlg a,DAlg *c)
                    639: {
1.18    ! noro      640:   NumberField nf;
        !           641:   int dim,n,i,j,k,l;
        !           642:   DP *mb;
        !           643:   DP m,d,u;
        !           644:   N ln,gn,qn;
        !           645:   DAlg *simp;
        !           646:   DAlg t,a0,r;
        !           647:   Q dn,dnsol,mul,nmc,dn1;
        !           648:   MAT mobj,sol;
        !           649:   Q **mat,**solmat;
        !           650:   MP mp0,mp;
        !           651:   int *rinfo,*cinfo;
        !           652:   int rank,nparam;
        !           653:   NODE nd0,nd,ndt;
        !           654:   struct order_spec *current_spec;
        !           655:   struct oEGT eg0,eg1;
        !           656:   extern struct oEGT eg_le;
        !           657:   extern int DP_Print;
        !           658:
        !           659:   if ( !(nf=current_numberfield) )
        !           660:     error("invdalg : current_numberfield is not set");
        !           661:   if ( !a )
        !           662:     error("invdalg : division by 0");
        !           663:   else if ( NID(a) == N_Q ) {
        !           664:     invq((Q)a,&dn); *c = (DAlg)dn;
        !           665:     return 0;
        !           666:   }
        !           667:   dim = nf->dim;
        !           668:   mb = nf->mb;
        !           669:   n = nf->n;
        !           670:   ln = ONEN;
        !           671:   dp_ptozp(a->nm,&u); divq((Q)BDY(a->nm)->c,(Q)BDY(u)->c,&nmc);
        !           672:   MKDAlg(u,ONE,a0);
        !           673:   simp = (DAlg *)MALLOC(dim*sizeof(DAlg));
        !           674:   current_spec = dp_current_spec; initd(nf->spec);
        !           675:   for ( i = 0; i < dim; i++ ) {
        !           676:     if ( DP_Print ) { fprintf(asir_out,"."); fflush(asir_out); }
        !           677:     m = mb[i];
        !           678:     for ( j = i-1; j >= 0; j-- )
        !           679:       if ( dp_redble(m,mb[j]) )
        !           680:         break;
        !           681:     if ( j >= 0 ) {
        !           682:       dp_subd(m,mb[j],&d);
        !           683:       if ( simp[j] ) {
        !           684:         muld(CO,d,simp[j]->nm,&u);
        !           685:         MKDAlg(u,simp[j]->dn,t);
        !           686:         simpdalg(t,&simp[i]);
        !           687:       } else
        !           688:         simp[i] = 0;
        !           689:     } else {
        !           690:       MKDAlg(m,ONE,t);
        !           691:       muldalg(t,a0,&simp[i]);
        !           692:     }
        !           693:     if ( simp[i] ) {
        !           694:       gcdn(NM(simp[i]->dn),ln,&gn); divsn(ln,gn,&qn);
        !           695:       muln(NM(simp[i]->dn),qn,&ln);
        !           696:     }
        !           697:   }
        !           698:   initd(current_spec);
        !           699:   NTOQ(ln,1,dn);
        !           700:   MKMAT(mobj,dim,dim+1);
        !           701:   mat = (Q **)BDY(mobj);
        !           702:   mulq(dn,a->dn,&mat[0][dim]);
        !           703:   for ( j = 0; j < dim; j++ ) {
        !           704:     if ( simp[j] ) {
        !           705:       divq(dn,simp[j]->dn,&mul);
        !           706:       for ( i = dim-1, mp = BDY(simp[j]->nm); mp && i >= 0; i-- )
        !           707:         if ( dl_equal(n,BDY(mb[i])->dl,mp->dl) ) {
        !           708:           mulq(mul,(Q)mp->c,&mat[i][j]);
        !           709:           mp = NEXT(mp);
        !           710:         }
        !           711:     }
        !           712:   }
        !           713:   get_eg(&eg0);
        !           714:   rank = generic_gauss_elim_hensel_dalg(mobj,mb,&sol,&dnsol,&rinfo,&cinfo);
        !           715:   get_eg(&eg1); add_eg(&eg_le,&eg0,&eg1);
        !           716:   if ( cinfo[0] == dim ) {
        !           717:     /* the input is invertible */
        !           718:     solmat = (Q **)BDY(sol);
        !           719:     for ( i = dim-1, mp0 = 0; i >= 0; i-- )
        !           720:       if ( solmat[i][0] ) {
        !           721:         NEXTMP(mp0,mp);
        !           722:         mp->c = (Obj)solmat[i][0];
        !           723:         mp->dl = BDY(mb[i])->dl;
        !           724:       }
        !           725:     NEXT(mp) = 0; MKDP(n,mp0,u);
        !           726:     mulq(dnsol,nmc,&dn1);
        !           727:     MKDAlg(u,dn1,r);
        !           728:     rmcontdalg(r,c);
        !           729:     return 0;
        !           730:   } else {
        !           731:     /* the input is not invertible */
        !           732:     nparam = sol->col;
        !           733:     solmat = (Q **)BDY(sol);
        !           734:     nd0 = 0;
        !           735:     for ( k = 0; k < nparam; k++ ) {
        !           736:       /* construct a new basis element */
        !           737:       m = mb[cinfo[k]];
        !           738:       mp0 = 0;
        !           739:       NEXTMP(mp0,mp);
        !           740:       chsgnq(dnsol,&dn1); mp->c = (Obj)dn1;
        !           741:       mp->dl = BDY(m)->dl;
        !           742:       /* skip the last parameter */
        !           743:       for ( l = rank-2; l >= 0; l-- ) {
        !           744:         if ( solmat[l][k] ) {
        !           745:           NEXTMP(mp0,mp);
        !           746:           mp->c = (Obj)solmat[l][k];
        !           747:           mp->dl = BDY(mb[rinfo[l]])->dl;
        !           748:         }
        !           749:       }
        !           750:       NEXT(mp) = 0; MKDP(n,mp0,u);
        !           751:       NEXTNODE(nd0,nd);
        !           752:       BDY(nd) = (pointer)u;
        !           753:       NEXT(nd) = 0;
        !           754:     }
        !           755:     NEXT(nd) = 0;
        !           756:     return nd0;
        !           757:   }
1.1       noro      758: }
                    759:
1.14      noro      760: NODE dp_inv_or_split(NODE gb,DP f,struct order_spec *spec, DP *inv)
                    761: {
1.18    ! noro      762:   int dim,n,i,j,k,l,nv;
        !           763:   DP *mb,*ps;
        !           764:   DP m,d,u,nm;
        !           765:   N ln,gn,qn;
        !           766:   DAlg *simp;
        !           767:   DAlg a0,r;
        !           768:   Q dn,dnsol,mul,nmc,dn1,iq;
        !           769:   MAT mobj,sol;
        !           770:   Q **mat,**solmat;
        !           771:   MP mp0,mp;
        !           772:   int *rinfo,*cinfo;
        !           773:   int rank,nparam;
        !           774:   NODE nd0,nd,ndt,ind,indt,t,mblist;
        !           775:   struct oEGT eg0,eg1;
        !           776:   extern struct oEGT eg_le;
        !           777:   extern int DP_Print;
        !           778:   initd(spec);
        !           779:   dp_ptozp(f,&u); f = u;
        !           780:
        !           781:   n = length(gb);
        !           782:   ps = (DP *)MALLOC(n*sizeof(DP));
        !           783:   for ( ind = 0, i = 0, t = gb; i < n; i++, t = NEXT(t) ) {
        !           784:     ps[i] = (DP)BDY(t);
        !           785:     NEXTNODE(ind,indt);
        !           786:     STOQ(i,iq); BDY(indt) = iq;
        !           787:   }
        !           788:   if ( ind ) NEXT(indt) = 0;
        !           789:   dp_true_nf(ind,f,ps,1,&nm,(P *)&dn);
        !           790:   if ( !nm ) error("dp_inv_or_split : input is 0");
        !           791:   f = nm;
        !           792:
        !           793:   dp_mbase(gb,&mblist);
        !           794:   dim = length(mblist);
        !           795:   mb = (DP *)MALLOC(dim*sizeof(DP));
        !           796:   for ( i = 0, t = mblist; i < dim; i++, t = NEXT(t) )
        !           797:     mb[dim-i-1] = (DP)BDY(t);
        !           798:   nv = mb[0]->nv;
        !           799:   ln = ONEN;
        !           800:   simp = (DAlg *)MALLOC(dim*sizeof(DAlg));
        !           801:   for ( i = 0; i < dim; i++ ) {
        !           802:     if ( DP_Print ) { fprintf(asir_out,"."); fflush(asir_out); }
        !           803:     m = mb[i];
        !           804:     for ( j = i-1; j >= 0; j-- )
        !           805:       if ( dp_redble(m,mb[j]) )
        !           806:         break;
        !           807:     if ( j >= 0 ) {
        !           808:       dp_subd(m,mb[j],&d);
        !           809:       if ( simp[j] ) {
        !           810:         muld(CO,d,simp[j]->nm,&u);
        !           811:         dp_true_nf(ind,u,ps,1,&nm,(P *)&dn);
        !           812:         mulq(simp[j]->dn,dn,&dn1);
        !           813:         MKDAlg(nm,dn1,simp[i]);
        !           814:       } else
        !           815:         simp[i] = 0;
        !           816:     } else {
        !           817:       dp_true_nf(ind,f,ps,1,&nm,(P *)&dn);
        !           818:       MKDAlg(nm,dn,simp[i]);
        !           819:     }
        !           820:     if ( simp[i] ) {
        !           821:       gcdn(NM(simp[i]->dn),ln,&gn); divsn(ln,gn,&qn);
        !           822:       muln(NM(simp[i]->dn),qn,&ln);
        !           823:     }
        !           824:   }
        !           825:   NTOQ(ln,1,dn);
        !           826:   MKMAT(mobj,dim,dim+1);
        !           827:   mat = (Q **)BDY(mobj);
        !           828:   mat[0][dim] = dn;
        !           829:   for ( j = 0; j < dim; j++ ) {
        !           830:     if ( simp[j] ) {
        !           831:       divq(dn,simp[j]->dn,&mul);
        !           832:       for ( i = dim-1, mp = BDY(simp[j]->nm); mp && i >= 0; i-- )
        !           833:         if ( dl_equal(nv,BDY(mb[i])->dl,mp->dl) ) {
        !           834:           mulq(mul,(Q)mp->c,&mat[i][j]);
        !           835:           mp = NEXT(mp);
        !           836:         }
        !           837:     }
        !           838:   }
        !           839:   get_eg(&eg0);
        !           840:   rank = generic_gauss_elim_hensel_dalg(mobj,mb,&sol,&dnsol,&rinfo,&cinfo);
        !           841:   get_eg(&eg1); add_eg(&eg_le,&eg0,&eg1);
        !           842:   if ( cinfo[0] == dim ) {
        !           843:     /* the input is invertible */
        !           844:     solmat = (Q **)BDY(sol);
        !           845:     for ( i = dim-1, mp0 = 0; i >= 0; i-- )
        !           846:       if ( solmat[i][0] ) {
        !           847:         NEXTMP(mp0,mp);
        !           848:         mp->c = (Obj)solmat[i][0];
        !           849:         mp->dl = BDY(mb[i])->dl;
        !           850:       }
        !           851:     NEXT(mp) = 0; MKDP(nv,mp0,*inv);
        !           852:     return 0;
        !           853:   } else {
        !           854:     /* the input is not invertible */
        !           855:     nparam = sol->col;
        !           856:     solmat = (Q **)BDY(sol);
        !           857:     nd0 = 0;
        !           858:     for ( k = 0; k < nparam; k++ ) {
        !           859:       /* construct a new basis element */
        !           860:       m = mb[cinfo[k]];
        !           861:       mp0 = 0;
        !           862:       NEXTMP(mp0,mp);
        !           863:       chsgnq(dnsol,&dn1); mp->c = (Obj)dn1;
        !           864:       mp->dl = BDY(m)->dl;
        !           865:       /* skip the last parameter */
        !           866:       for ( l = rank-2; l >= 0; l-- ) {
        !           867:         if ( solmat[l][k] ) {
        !           868:           NEXTMP(mp0,mp);
        !           869:           mp->c = (Obj)solmat[l][k];
        !           870:           mp->dl = BDY(mb[rinfo[l]])->dl;
        !           871:         }
        !           872:       }
        !           873:       NEXT(mp) = 0; MKDP(nv,mp0,u);
        !           874:       NEXTNODE(nd0,nd);
        !           875:       BDY(nd) = (pointer)u;
        !           876:       NEXT(nd) = 0;
        !           877:     }
        !           878:     NEXT(nd) = 0;
        !           879:     return nd0;
        !           880:   }
1.14      noro      881: }
                    882:
1.1       noro      883: void chsgndalg(DAlg a,DAlg *c)
                    884: {
1.18    ! noro      885:   DP nm;
        !           886:   Q t;
1.3       noro      887:
1.18    ! noro      888:   if ( !a ) *c = 0;
        !           889:   else if ( NID(a) == N_Q ) {
        !           890:     chsgnq((Q)a,&t); *c = (DAlg)t;
        !           891:   } else {
        !           892:     chsgnd(a->nm,&nm);
        !           893:     MKDAlg(nm,a->dn,*c);
        !           894:   }
1.1       noro      895: }
                    896:
1.3       noro      897: void pwrdalg(DAlg a,Q e,DAlg *c)
1.1       noro      898: {
1.18    ! noro      899:   NumberField nf;
        !           900:   DAlg t,z,y;
        !           901:   Q q;
        !           902:   N en,qn;
        !           903:   int r;
        !           904:   int ret;
        !           905:
        !           906:   if ( !(nf=current_numberfield) )
        !           907:     error("pwrdalg : current_numberfield is not set");
        !           908:   if ( !a )
        !           909:     *c = !e ? (DAlg)ONE : 0;
        !           910:   else if ( NID(a) == N_Q ) {
        !           911:     pwrq((Q)a,e,&q); *c = (DAlg)q;
        !           912:   } else if ( !e )
        !           913:     *c = nf->one;
        !           914:   else if ( UNIQ(e) )
        !           915:     *c = a;
        !           916:   else {
        !           917:     if ( SGN(e) < 0 ) {
        !           918:       ret = invdalg(a,&t);
        !           919:       if ( !ret )
        !           920:         error("pwrdalg : the denominator is not invertible");
        !           921:       a = t;
        !           922:     }
        !           923:     en = NM(e);
        !           924:     y = nf->one;
        !           925:     z = a;
        !           926:     while ( 1 ) {
        !           927:       r = divin(en,2,&qn); en = qn;
        !           928:       if ( r ) {
        !           929:         muldalg(z,y,&t); y = t;
        !           930:         if ( !en ) {
        !           931:           *c = y;
        !           932:           return;
        !           933:         }
        !           934:       }
        !           935:       muldalg(z,z,&t); z = t;
        !           936:     }
        !           937:   }
1.1       noro      938: }
                    939:
1.3       noro      940: int cmpdalg(DAlg a,DAlg b)
1.1       noro      941: {
1.18    ! noro      942:   DAlg c;
1.3       noro      943:
1.18    ! noro      944:   subdalg(a,b,&c);
        !           945:   if ( !c ) return 0;
        !           946:   else
        !           947:     return SGN((Q)BDY(c->nm)->c);
1.1       noro      948: }
1.9       noro      949:
                    950: /* convert da to a univariate poly; return the position of variable */
                    951:
                    952: int dalgtoup(DAlg da,P *up,Q *dn)
                    953: {
1.18    ! noro      954:   int nv,i,hi,current_d;
        !           955:   DCP dc0,dc;
        !           956:   MP h,mp0,mp,t;
        !           957:   DL hd,d;
        !           958:   DP c;
        !           959:   DAlg cc;
        !           960:   P v;
        !           961:
        !           962:   nv = da->nm->nv;
        !           963:   h = BDY(da->nm);
        !           964:   *dn = da->dn;
        !           965:   hd = h->dl;
        !           966:   for ( i = 0; i < nv; i++ )
        !           967:     if ( hd->d[i] ) break;
        !           968:   hi = i;
        !           969:   current_d = hd->d[i];
        !           970:   dc0 = 0;
        !           971:   mp0 = 0;
        !           972:   for ( t = h; t; t = NEXT(t) ) {
        !           973:     NEWDL(d,nv);
        !           974:     for ( i = 0; i <= hi; i++ ) d->d[i] = 0;
        !           975:     for ( ; i < nv; i++ ) d->d[i] = t->dl->d[i];
        !           976:     d->td = t->dl->td - t->dl->d[hi];
        !           977:     if ( t->dl->d[hi] != current_d ) {
        !           978:       NEXT(mp) = 0; MKDP(nv,mp0,c); MKDAlg(c,ONE,cc);
        !           979:       NEXTDC(dc0,dc); STOQ(current_d,DEG(dc)); COEF(dc) = (P)cc;
        !           980:       current_d = t->dl->d[hi];
        !           981:       mp0 = 0;
        !           982:     }
        !           983:     NEXTMP(mp0,mp);
        !           984:     mp->c = t->c; mp->dl = d;
        !           985:   }
        !           986:   NEXT(mp) = 0; MKDP(nv,mp0,c); MKDAlg(c,ONE,cc);
        !           987:   NEXTDC(dc0,dc); STOQ(current_d,DEG(dc)); COEF(dc) = (P)cc;
        !           988:   NEXT(dc) = 0;
        !           989:   makevar("x",&v);
        !           990:   MKP(VR(v),dc0,*up);
        !           991:   return hi;
1.9       noro      992: }
                    993:

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