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

Annotation of OpenXM_contrib2/asir2018/engine/dalg.c, Revision 1.1

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

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