Annotation of OpenXM_contrib2/asir2018/builtin/algnum.c, Revision 1.1
1.1 ! noro 1: /*
! 2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
! 3: * All rights reserved.
! 4: *
! 5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
! 6: * non-exclusive and royalty-free license to use, copy, modify and
! 7: * redistribute, solely for non-commercial and non-profit purposes, the
! 8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
! 9: * conditions of this Agreement. For the avoidance of doubt, you acquire
! 10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
! 11: * third party developer retains all rights, including but not limited to
! 12: * copyrights, in and to the SOFTWARE.
! 13: *
! 14: * (1) FLL does not grant you a license in any way for commercial
! 15: * purposes. You may use the SOFTWARE only for non-commercial and
! 16: * non-profit purposes only, such as academic, research and internal
! 17: * business use.
! 18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
! 19: * international copyright treaties. If you make copies of the SOFTWARE,
! 20: * with or without modification, as permitted hereunder, you shall affix
! 21: * to all such copies of the SOFTWARE the above copyright notice.
! 22: * (3) An explicit reference to this SOFTWARE and its copyright owner
! 23: * shall be made on your publication or presentation in any form of the
! 24: * results obtained by use of the SOFTWARE.
! 25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
! 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
! 27: * for such modification or the source code of the modified part of the
! 28: * SOFTWARE.
! 29: *
! 30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
! 31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
! 32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
! 33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
! 34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
! 35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
! 36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
! 37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
! 38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
! 39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
! 40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
! 41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
! 42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
! 43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
! 44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
! 45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
! 46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
! 47: *
! 48: * $OpenXM$
! 49: */
! 50: #include "ca.h"
! 51: #include "parse.h"
! 52:
! 53: void Pdefpoly(), Pnewalg(), Pmainalg(), Palgtorat(), Prattoalg(), Pgetalg();
! 54: void Palg(), Palgv(), Pgetalgtree();
! 55: void Pinvalg_le();
! 56: void Pset_field(),Palgtodalg(),Pdalgtoalg();
! 57: void Pinv_or_split_dalg();
! 58: void Pdalgtoup();
! 59: void Pget_field_defpoly();
! 60: void Pget_field_generator();
! 61:
! 62: void mkalg(P,Alg *);
! 63: int cmpalgp(P,P);
! 64: void algptop(P,P *);
! 65: void algtorat(Num,Obj *);
! 66: void rattoalg(Obj,Alg *);
! 67: void ptoalgp(P,P *);
! 68: void clctalg(P,VL *);
! 69: void get_algtree(Obj f,VL *r);
! 70: void Pinvalg_chrem();
! 71: void Pdalgtodp();
! 72: void Pdptodalg();
! 73:
! 74: struct ftab alg_tab[] = {
! 75: {"set_field",Pset_field,-3},
! 76: {"get_field_defpoly",Pget_field_defpoly,1},
! 77: {"get_field_generator",Pget_field_generator,1},
! 78: {"algtodalg",Palgtodalg,1},
! 79: {"dalgtoalg",Pdalgtoalg,1},
! 80: {"dalgtodp",Pdalgtodp,1},
! 81: {"dalgtoup",Pdalgtoup,1},
! 82: {"dptodalg",Pdptodalg,1},
! 83: {"inv_or_split_dalg",Pinv_or_split_dalg,1},
! 84: {"invalg_chrem",Pinvalg_chrem,2},
! 85: {"invalg_le",Pinvalg_le,1},
! 86: {"defpoly",Pdefpoly,1},
! 87: {"newalg",Pnewalg,1},
! 88: {"mainalg",Pmainalg,1},
! 89: {"algtorat",Palgtorat,1},
! 90: {"rattoalg",Prattoalg,1},
! 91: {"getalg",Pgetalg,1},
! 92: {"getalgtree",Pgetalgtree,1},
! 93: {"alg",Palg,1},
! 94: {"algv",Palgv,1},
! 95: {0,0,0},
! 96: };
! 97:
! 98: static int UCN,ACNT;
! 99:
! 100: void Pset_field(NODE arg,Q *rp)
! 101: {
! 102: int ac;
! 103: NODE a0,a1;
! 104: VL vl0,vl;
! 105: struct order_spec *spec;
! 106:
! 107: if ( (ac = argc(arg)) == 1 )
! 108: setfield_dalg(BDY((LIST)ARG0(arg)));
! 109: else if ( ac == 3 ) {
! 110: a0 = BDY((LIST)ARG0(arg));
! 111: a1 = BDY((LIST)ARG1(arg));
! 112: for ( vl0 = 0; a1; a1 = NEXT(a1) ) {
! 113: NEXTVL(vl0,vl);
! 114: vl->v = VR((P)BDY(a1));
! 115: }
! 116: if ( vl0 ) NEXT(vl) = 0;
! 117: create_order_spec(0,ARG2(arg),&spec);
! 118: setfield_gb(a0,vl0,spec);
! 119: }
! 120: *rp = 0;
! 121: }
! 122:
! 123: void Palgtodalg(NODE arg,DAlg *rp)
! 124: {
! 125: algtodalg((Alg)ARG0(arg),rp);
! 126: }
! 127:
! 128: void Pdalgtoalg(NODE arg,Alg *rp)
! 129: {
! 130: dalgtoalg((DAlg)ARG0(arg),rp);
! 131: }
! 132:
! 133: void Pdalgtodp(NODE arg,LIST *r)
! 134: {
! 135: NODE b;
! 136: DP nm;
! 137: Z dn;
! 138: DAlg da;
! 139:
! 140: da = (DAlg)ARG0(arg);
! 141: nm = da->nm;
! 142: dn = da->dn;
! 143: b = mknode(2,nm,dn);
! 144: MKLIST(*r,b);
! 145: }
! 146:
! 147: void Pdptodalg(NODE arg,DAlg *r)
! 148: {
! 149: DP d,nm,nm1;
! 150: MP m;
! 151: Q c;
! 152: Z a;
! 153: DAlg t;
! 154:
! 155: d = (DP)ARG0(arg);
! 156: if ( !d ) *r = 0;
! 157: else {
! 158: for ( m = BDY(d); m; m = NEXT(m) )
! 159: if ( !INT((Q)m->c) ) break;
! 160: if ( !m ) {
! 161: MKDAlg(d,ONE,t);
! 162: } else {
! 163: dp_ptozp(d,&nm);
! 164: divq((Q)BDY(d)->c,(Q)BDY(nm)->c,&c);
! 165: nmq(c,&a);
! 166: muldc(CO,nm,(Obj)a,&nm1);
! 167: dnq(c,&a);
! 168: MKDAlg(nm1,a,t);
! 169: }
! 170: simpdalg(t,r);
! 171: }
! 172: }
! 173:
! 174: void Pdalgtoup(NODE arg,LIST *r)
! 175: {
! 176: NODE b;
! 177: int pos;
! 178: P up;
! 179: DP nm;
! 180: Z dn;
! 181: Z q;
! 182:
! 183: pos = dalgtoup((DAlg)ARG0(arg),&up,&dn);
! 184: STOQ(pos,q);
! 185: b = mknode(3,up,dn,q);
! 186: MKLIST(*r,b);
! 187: }
! 188:
! 189: NODE inv_or_split_dalg(DAlg,DAlg *);
! 190: NumberField get_numberfield();
! 191:
! 192: void Pget_field_defpoly(NODE arg,DAlg *r)
! 193: {
! 194: NumberField nf;
! 195: DP d;
! 196:
! 197: nf = get_numberfield();
! 198: d = nf->ps[QTOS((Q)ARG0(arg))];
! 199: MKDAlg(d,ONE,*r);
! 200: }
! 201:
! 202: void Pget_field_generator(NODE arg,DAlg *r)
! 203: {
! 204: int index,n,i;
! 205: DL dl;
! 206: MP m;
! 207: DP d;
! 208:
! 209: index = QTOS((Q)ARG0(arg));
! 210: n = get_numberfield()->n;
! 211: NEWDL(dl,n);
! 212: for ( i = 0; i < n; i++ ) dl->d[i] = 0;
! 213: dl->d[index] = 1; dl->td = 1;
! 214: NEWMP(m); m->dl = dl; m->c = (Obj)ONE; NEXT(m) = 0;
! 215: MKDP(n,m,d);
! 216: MKDAlg(d,ONE,*r);
! 217: }
! 218:
! 219:
! 220: void Pinv_or_split_dalg(NODE arg,Obj *rp)
! 221: {
! 222: NODE gen,t,nd0,nd;
! 223: LIST list;
! 224: int l,i,j,n;
! 225: DP *ps,*ps1,*psw;
! 226: NumberField nf;
! 227: DAlg inv;
! 228: extern struct order_spec *dp_current_spec;
! 229: struct order_spec *current_spec;
! 230:
! 231: gen = inv_or_split_dalg((DAlg)ARG0(arg),&inv);
! 232: if ( !gen )
! 233: *rp = (Obj)inv;
! 234: else {
! 235: nf = get_numberfield();
! 236: current_spec = dp_current_spec; initd(nf->spec);
! 237: l = length(gen);
! 238: n = nf->n;
! 239: ps = nf->ps;
! 240: psw = (DP *)ALLOCA((n+l)*sizeof(DP));
! 241: for ( i = j = 0; i < n; i++ ) {
! 242: for ( t = gen; t; t = NEXT(t) )
! 243: if ( dp_redble(ps[i],(DP)BDY(t)) ) break;
! 244: if ( !t )
! 245: psw[j++] = ps[i];
! 246: }
! 247: nd0 = 0;
! 248: /* gen[0] < gen[1] < ... */
! 249: /* psw[0] > psw[1] > ... */
! 250: for ( i = j-1, t = gen; i >= 0 && t; ) {
! 251: NEXTNODE(nd0,nd);
! 252: if ( compd(CO,psw[i],(DP)BDY(t)) > 0 ) {
! 253: BDY(nd) = BDY(t); t = NEXT(t);
! 254: } else
! 255: BDY(nd) = (pointer)psw[i--];
! 256: }
! 257: for ( ; i >= 0; i-- ) {
! 258: NEXTNODE(nd0,nd); BDY(nd) = (pointer)psw[i];
! 259: }
! 260: for ( ; t; t = NEXT(t) ) {
! 261: NEXTNODE(nd0,nd); BDY(nd) = BDY(t);
! 262: }
! 263: NEXT(nd) = 0;
! 264: MKLIST(list,nd0);
! 265: initd(current_spec);
! 266: *rp = (Obj)list;
! 267: }
! 268: }
! 269:
! 270: void Pnewalg(arg,rp)
! 271: NODE arg;
! 272: Alg *rp;
! 273: {
! 274: P p;
! 275: VL vl;
! 276: P c;
! 277:
! 278: p = (P)ARG0(arg);
! 279: if ( !p || OID(p) != O_P )
! 280: error("newalg : invalid argument");
! 281: clctv(CO,p,&vl);
! 282: if ( NEXT(vl) )
! 283: error("newalg : invalid argument");
! 284: c = COEF(DC(p));
! 285: if ( !NUM(c) || !RATN(c) )
! 286: error("newalg : invalid argument");
! 287: mkalg(p,rp);
! 288: }
! 289:
! 290: void mkalg(p,r)
! 291: P p;
! 292: Alg *r;
! 293: {
! 294: VL vl,mvl,nvl;
! 295: V a,tv;
! 296: char buf[BUFSIZ];
! 297: char *name;
! 298: P x,t,s;
! 299: Num c;
! 300: DCP dc,dcr,dcr0;
! 301:
! 302: for ( vl = ALG; vl; vl = NEXT(vl) )
! 303: if ( !cmpalgp(p,(P)vl->v->attr) ) {
! 304: a = vl->v; break;
! 305: }
! 306: if ( !vl ) {
! 307: NEWVL(vl); NEXT(vl) = ALG; ALG = vl;
! 308: NEWV(a); vl->v = a;
! 309: sprintf(buf,"#%d",ACNT++);
! 310: name = (char *)MALLOC(strlen(buf)+1);
! 311: strcpy(name,buf); NAME(a) = name;
! 312:
! 313: for ( dc = DC(p), dcr0 = 0; dc; dc = NEXT(dc) ) {
! 314: NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); c = (Num)COEF(dc);
! 315: if ( NID(c) != N_A )
! 316: COEF(dcr) = (P)c;
! 317: else
! 318: COEF(dcr) = (P)BDY(((Alg)c));
! 319: }
! 320: NEXT(dcr) = 0; MKP(a,dcr0,t); a->attr = (pointer)t;
! 321:
! 322: sprintf(buf,"t%s",name); makevar(buf,&s);
! 323:
! 324: if ( NEXT(ALG) ) {
! 325: tv = (V)NEXT(ALG)->v->priv;
! 326: for ( vl = CO; NEXT(NEXT(vl)); vl = NEXT(vl) );
! 327: nvl = NEXT(vl); NEXT(vl) = 0;
! 328: for ( vl = CO; NEXT(vl) && (NEXT(vl)->v != tv); vl = NEXT(vl) );
! 329: mvl = NEXT(vl); NEXT(vl) = nvl; NEXT(nvl) = mvl;
! 330: }
! 331:
! 332: a->priv = (pointer)VR(s); VR(s)->priv = (pointer)a;
! 333: }
! 334: MKV(a,x); MKAlg(x,*r);
! 335: }
! 336:
! 337: int cmpalgp(p,defp)
! 338: P p,defp;
! 339: {
! 340: DCP dc,dcd;
! 341: P t;
! 342:
! 343: for ( dc = DC(p), dcd = DC(defp); dc && dcd;
! 344: dc = NEXT(dc), dcd = NEXT(dcd) ) {
! 345: if ( cmpz(DEG(dc),DEG(dcd)) )
! 346: break;
! 347: t = NID((Num)COEF(dc)) == N_A ? (P)BDY((Alg)COEF(dc)) : COEF(dc);
! 348: if ( compp(ALG,t,COEF(dcd)) )
! 349: break;
! 350: }
! 351: if ( dc || dcd )
! 352: return 1;
! 353: else
! 354: return 0;
! 355: }
! 356:
! 357: void Pdefpoly(arg,rp)
! 358: NODE arg;
! 359: P *rp;
! 360: {
! 361: asir_assert(ARG0(arg),O_N,"defpoly");
! 362: algptop((P)VR((P)BDY((Alg)ARG0(arg)))->attr,rp);
! 363: }
! 364:
! 365: void Pmainalg(arg,r)
! 366: NODE arg;
! 367: Alg *r;
! 368: {
! 369: Num c;
! 370: V v;
! 371: P b;
! 372:
! 373: c = (Num)(ARG0(arg));
! 374: if ( NID(c) <= N_R )
! 375: *r = 0;
! 376: else {
! 377: v = VR((P)BDY((Alg)c)); MKV(v,b); MKAlg(b,*r);
! 378: }
! 379: }
! 380:
! 381: void Palgtorat(arg,rp)
! 382: NODE arg;
! 383: Obj *rp;
! 384: {
! 385: asir_assert(ARG0(arg),O_N,"algtorat");
! 386: algtorat((Num)ARG0(arg),rp);
! 387: }
! 388:
! 389: void Prattoalg(arg,rp)
! 390: NODE arg;
! 391: Alg *rp;
! 392: {
! 393: asir_assert(ARG0(arg),O_R,"rattoalg");
! 394: rattoalg((Obj)ARG0(arg),rp);
! 395: }
! 396:
! 397: void Pgetalg(arg,rp)
! 398: NODE arg;
! 399: LIST *rp;
! 400: {
! 401: Obj t;
! 402: P p;
! 403: VL vl;
! 404: Num a;
! 405: Alg b;
! 406: NODE n0,n;
! 407:
! 408: if ( !(a = (Num)ARG0(arg)) || NID(a) <= N_R )
! 409: vl = 0;
! 410: else {
! 411: t = BDY((Alg)a);
! 412: switch ( OID(t) ) {
! 413: case O_P: case O_R:
! 414: clctvr(ALG,t,&vl); break;
! 415: default:
! 416: vl = 0; break;
! 417: }
! 418: }
! 419: for ( n0 = 0; vl; vl = NEXT(vl) ) {
! 420: NEXTNODE(n0,n); MKV(vl->v,p); MKAlg(p,b); BDY(n) = (pointer)b;
! 421: }
! 422: if ( n0 )
! 423: NEXT(n) = 0;
! 424: MKLIST(*rp,n0);
! 425: }
! 426:
! 427: void Pgetalgtree(arg,rp)
! 428: NODE arg;
! 429: LIST *rp;
! 430: {
! 431: Obj t;
! 432: P p;
! 433: VL vl,vl1,vl2;
! 434: Num a;
! 435: Alg b;
! 436: NODE n0,n;
! 437:
! 438: #if 0
! 439: if ( !(a = (Num)ARG0(arg)) || NID(a) <= N_R )
! 440: vl = 0;
! 441: else {
! 442: t = BDY((Alg)a);
! 443: switch ( OID(t) ) {
! 444: case O_P:
! 445: clctalg((P)t,&vl); break;
! 446: case O_R:
! 447: clctalg(NM((R)t),&vl1);
! 448: clctalg(DN((R)t),&vl2);
! 449: mergev(ALG,vl1,vl2,&vl); break;
! 450: default:
! 451: vl = 0; break;
! 452: }
! 453: }
! 454: #else
! 455: get_algtree((Obj)ARG0(arg),&vl);
! 456: #endif
! 457: for ( n0 = 0; vl; vl = NEXT(vl) ) {
! 458: NEXTNODE(n0,n); MKV(vl->v,p); MKAlg(p,b); BDY(n) = (pointer)b;
! 459: }
! 460: if ( n0 )
! 461: NEXT(n) = 0;
! 462: MKLIST(*rp,n0);
! 463: }
! 464:
! 465: void clctalg(p,vl)
! 466: P p;
! 467: VL *vl;
! 468: {
! 469: int n,i;
! 470: VL tvl;
! 471: VN vn,vn1;
! 472: P d;
! 473: DCP dc;
! 474:
! 475: for ( n = 0, tvl = ALG; tvl; tvl = NEXT(tvl), n++ );
! 476: vn = (VN) ALLOCA((n+1)*sizeof(struct oVN));
! 477: for ( i = n-1, tvl = ALG; tvl; tvl = NEXT(tvl), i-- ) {
! 478: vn[i].v = tvl->v;
! 479: vn[i].n = 0;
! 480: }
! 481: markv(vn,n,p);
! 482: for ( i = n-1; i >= 0; i-- ) {
! 483: if ( !vn[i].n )
! 484: continue;
! 485: d = (P)vn[i].v->attr;
! 486: for ( dc = DC(d); dc; dc = NEXT(dc) )
! 487: markv(vn,i,COEF(dc));
! 488: }
! 489: vn1 = (VN) ALLOCA((n+1)*sizeof(struct oVN));
! 490: for ( i = 0; i < n; i++ ) {
! 491: vn1[i].v = vn[n-1-i].v; vn1[i].n = vn[n-1-i].n;
! 492: }
! 493: vntovl(vn1,n,vl);
! 494: }
! 495:
! 496: void Palg(arg,rp)
! 497: NODE arg;
! 498: Alg *rp;
! 499: {
! 500: Q a;
! 501: VL vl;
! 502: P x;
! 503: int n;
! 504:
! 505: a = (Q)ARG0(arg);
! 506: if ( a && (OID(a) != O_N || NID(a) != N_Q || !INT(a)) )
! 507: *rp = 0;
! 508: else {
! 509: n = ACNT-QTOS(a)-1;
! 510: for ( vl = ALG; vl && n; vl = NEXT(vl), n-- );
! 511: if ( vl ) {
! 512: MKV(vl->v,x); MKAlg(x,*rp);
! 513: } else
! 514: *rp = 0;
! 515: }
! 516: }
! 517:
! 518: void Palgv(arg,rp)
! 519: NODE arg;
! 520: Obj *rp;
! 521: {
! 522: Q a;
! 523: VL vl;
! 524: P x;
! 525: int n;
! 526: Alg b;
! 527:
! 528: a = (Q)ARG0(arg);
! 529: if ( a && (OID(a) != O_N || NID(a) != N_Q || !INT(a)) )
! 530: *rp = 0;
! 531: else {
! 532: n = ACNT-QTOS(a)-1;
! 533: for ( vl = ALG; vl && n; vl = NEXT(vl), n-- );
! 534: if ( vl ) {
! 535: MKV(vl->v,x); MKAlg(x,b); algtorat((Num)b,rp);
! 536: } else
! 537: *rp = 0;
! 538: }
! 539: }
! 540:
! 541: void algptop(p,r)
! 542: P p,*r;
! 543: {
! 544: DCP dc,dcr,dcr0;
! 545:
! 546: if ( NUM(p) )
! 547: *r = (P)p;
! 548: else {
! 549: for ( dc = DC(p), dcr0 = 0; dc; dc = NEXT(dc) ) {
! 550: NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc);
! 551: algptop(COEF(dc),&COEF(dcr));
! 552: }
! 553: NEXT(dcr) = 0; MKP((V)(VR(p)->priv),dcr0,*r);
! 554: }
! 555: }
! 556:
! 557: void algtorat(n,r)
! 558: Num n;
! 559: Obj *r;
! 560: {
! 561: Obj obj;
! 562: P nm,dn;
! 563:
! 564: if ( !n || NID(n) <= N_R )
! 565: *r = (Obj)n;
! 566: else {
! 567: obj = BDY((Alg)n);
! 568: if ( ID(obj) <= O_P )
! 569: algptop((P)obj,(P *)r);
! 570: else {
! 571: algptop(NM((R)obj),&nm); algptop(DN((R)obj),&dn);
! 572: divr(CO,(Obj)nm,(Obj)dn,r);
! 573: }
! 574: }
! 575: }
! 576:
! 577: void rattoalg(obj,n)
! 578: Obj obj;
! 579: Alg *n;
! 580: {
! 581: P nm,dn;
! 582: Obj t;
! 583:
! 584: if ( !obj || ID(obj) == O_N )
! 585: *n = (Alg)obj;
! 586: else if ( ID(obj) == O_P ) {
! 587: ptoalgp((P)obj,(P *)&t); MKAlg(t,*n);
! 588: } else {
! 589: ptoalgp(NM((R)obj),&nm); ptoalgp(DN((R)obj),&dn);
! 590: divr(ALG,(Obj)nm,(Obj)dn,&t); MKAlg(t,*n);
! 591: }
! 592: }
! 593:
! 594: void ptoalgp(p,r)
! 595: P p,*r;
! 596: {
! 597: DCP dc,dcr,dcr0;
! 598:
! 599: if ( NUM(p) )
! 600: *r = (P)p;
! 601: else {
! 602: for ( dc = DC(p), dcr0 = 0; dc; dc = NEXT(dc) ) {
! 603: NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc);
! 604: ptoalgp(COEF(dc),&COEF(dcr));
! 605: }
! 606: NEXT(dcr) = 0; MKP((V)(VR(p)->priv),dcr0,*r);
! 607: }
! 608: }
! 609:
! 610: void Pinvalg_chrem(NODE arg,LIST *r)
! 611: {
! 612: NODE n;
! 613:
! 614: inva_chrem((P)ARG0(arg),(P)ARG1(arg),&n);
! 615: MKLIST(*r,n);
! 616: }
! 617:
! 618: void invalg_le(Alg a,LIST *r);
! 619:
! 620: void Pinvalg_le(NODE arg,LIST *r)
! 621: {
! 622: invalg_le((Alg)ARG0(arg),r);
! 623: }
! 624:
! 625: typedef struct oMono_nf {
! 626: DP mono;
! 627: DP nf;
! 628: Z dn;
! 629: } *Mono_nf;
! 630:
! 631: void invalg_le(Alg a,LIST *r)
! 632: {
! 633: Alg inv;
! 634: MAT mobj,sol;
! 635: int *rinfo,*cinfo;
! 636: P p,dn,ap;
! 637: VL vl,tvl;
! 638: Q c1,c2,c3,cont,c,mul;
! 639: Z two,iq,dn0,dn1,dnsol;
! 640: int i,j,n,len,k;
! 641: MP mp,mp0;
! 642: DP dp,nm,nm1,m,d,u,u1;
! 643: NODE b,b1,hlist,mblist,t,s,rev0,rev,hist;
! 644: DP *ps;
! 645: struct order_spec *spec;
! 646: Mono_nf h,h1;
! 647: Z nq,nr,nl,ng;
! 648: Q **mat,**solmat;
! 649: Q *w;
! 650: int *wi;
! 651:
! 652: ap = (P)BDY(a);
! 653: asir_assert(ap,O_P,"invalg_le");
! 654:
! 655: /* collecting algebraic numbers */
! 656: clctalg(ap,&vl);
! 657:
! 658: /* setup */
! 659: ptozp(ap,1,&c,&p);
! 660: STOQ(2,two); create_order_spec(0,(Obj)two,&spec); initd(spec);
! 661: for ( n = 0, tvl = vl; tvl; tvl = NEXT(tvl), n++ );
! 662: ps = (DP *)ALLOCA(n*sizeof(DP));
! 663:
! 664: /* conversion to DP */
! 665: for ( i = 0, tvl = vl; i < n; i++, tvl = NEXT(tvl) ) {
! 666: ptod(ALG,vl,tvl->v->attr,&ps[i]);
! 667: }
! 668: ptod(ALG,vl,p,&dp);
! 669: /* index list */
! 670: for ( b = 0, i = 0; i < n; i++ ) {
! 671: STOQ(i,iq); MKNODE(b1,(pointer)iq,b); b = b1;
! 672: }
! 673: /* simplification */
! 674: dp_true_nf(b,dp,ps,1,&nm,(P *)&dn);
! 675:
! 676: /* construction of NF table */
! 677:
! 678: /* stdmono: <<0,...,0>> < ... < max */
! 679: for ( hlist = 0, i = 0; i < n; i++ ) {
! 680: MKNODE(b1,(pointer)ps[i],hlist); hlist = b1;
! 681: }
! 682: dp_mbase(hlist,&rev0);
! 683: for ( mblist = 0, rev = rev0; rev; rev = NEXT(rev) ) {
! 684: MKNODE(b1,BDY(rev),mblist); mblist = b1;
! 685: }
! 686: dn0 = ONE;
! 687: for ( hist = 0, t = mblist; t; t = NEXT(t) ) {
! 688: /* searching a predecessor */
! 689: for ( m = (DP)BDY(t), s = hist; s; s = NEXT(s) ) {
! 690: h = (Mono_nf)BDY(s);
! 691: if ( dp_redble(m,h->mono) )
! 692: break;
! 693: }
! 694: h1 = (Mono_nf)ALLOCA(sizeof(struct oMono_nf));
! 695: if ( s ) {
! 696: dp_subd(m,h->mono,&d);
! 697: muld(CO,d,h->nf,&u);
! 698: dp_true_nf(b,u,ps,1,&nm1,(P *)&dn1);
! 699: mulz(h->dn,dn1,&h1->dn);
! 700: } else {
! 701: muld(CO,m,nm,&u);
! 702: dp_true_nf(b,u,ps,1,&nm1,(P *)&dn1);
! 703: h1->dn = dn1;
! 704: }
! 705: h1->mono = m;
! 706: h1->nf = nm1;
! 707: MKNODE(b1,(pointer)h1,hist); hist = b1;
! 708:
! 709: /* dn0 = LCM(dn0,h1->dn) */
! 710: gcdz(dn0,h1->dn,&ng); divz(dn0,ng,&nq);
! 711: mulz(nq,h1->dn,&nl); absz(nl,&dn0);
! 712: }
! 713: /* create a matrix */
! 714: len = length(mblist);
! 715: MKMAT(mobj,len,len+1);
! 716: mat = (Q **)BDY(mobj);
! 717: mat[len-1][len] = (Q)dn0;
! 718: for ( j = 0, t = hist; j < len; j++, t = NEXT(t) ) {
! 719: h = (Mono_nf)BDY(t);
! 720: nm1 = h->nf;
! 721: divq((Q)dn0,(Q)h->dn,&mul);
! 722: for ( i = 0, rev = rev0, mp = BDY(nm1); mp && i < len; i++, rev = NEXT(rev) )
! 723: if ( dl_equal(n,BDY((DP)BDY(rev))->dl,mp->dl) ) {
! 724: mulq(mul,(Q)mp->c,&mat[i][j]);
! 725: mp = NEXT(mp);
! 726: }
! 727: }
! 728: generic_gauss_elim_hensel(mobj,&sol,&dnsol,&rinfo,&cinfo);
! 729: solmat = (Q **)BDY(sol);
! 730: for ( i = 0, t = rev0, mp0 = 0; i < len; i++, t = NEXT(t) )
! 731: if ( solmat[i][0] ) {
! 732: NEXTMP(mp0,mp);
! 733: mp->c = (Obj)solmat[i][0];
! 734: mp->dl = BDY((DP)BDY(t))->dl;
! 735: }
! 736: NEXT(mp) = 0; MKDP(n,mp0,u);
! 737: dp_ptozp(u,&u1);
! 738: divq((Q)BDY(u)->c,(Q)BDY(u1)->c,&cont);
! 739: dtop(ALG,vl,u1,(Obj *)&ap);
! 740: MKAlg(ap,inv);
! 741: mulq((Q)dnsol,(Q)dn,&c1);
! 742: mulq(c1,c,&c2);
! 743: divq(c2,cont,&c3);
! 744: b = mknode(2,inv,c3);
! 745: MKLIST(*r,b);
! 746: }
! 747:
! 748: void get_algtree(Obj f,VL *r)
! 749: {
! 750: VL vl1,vl2,vl3;
! 751: Obj t;
! 752: DCP dc;
! 753: NODE b;
! 754: pointer *a;
! 755: pointer **m;
! 756: int len,row,col,i,j,l;
! 757:
! 758: if ( !f ) *r = 0;
! 759: else
! 760: switch ( OID(f) ) {
! 761: case O_N:
! 762: if ( NID((Num)f) != N_A ) *r = 0;
! 763: else {
! 764: t = BDY((Alg)f);
! 765: switch ( OID(t) ) {
! 766: case O_P:
! 767: clctalg((P)t,r); break;
! 768: case O_R:
! 769: clctalg(NM((R)t),&vl1);
! 770: clctalg(DN((R)t),&vl2);
! 771: mergev(ALG,vl1,vl2,r); break;
! 772: default:
! 773: *r = 0; break;
! 774: }
! 775: }
! 776: break;
! 777: case O_P:
! 778: vl1 = 0;
! 779: for ( dc = DC((P)f); dc; dc = NEXT(dc) ) {
! 780: get_algtree((Obj)COEF(dc),&vl2);
! 781: mergev(ALG,vl1,vl2,&vl3);
! 782: vl1 = vl3;
! 783: }
! 784: *r = vl1;
! 785: break;
! 786: case O_R:
! 787: get_algtree((Obj)NM((R)f),&vl1);
! 788: get_algtree((Obj)DN((R)f),&vl2);
! 789: mergev(ALG,vl1,vl2,r);
! 790: break;
! 791: case O_LIST:
! 792: vl1 = 0;
! 793: for ( b = BDY((LIST)f); b; b = NEXT(b) ) {
! 794: get_algtree((Obj)BDY(b),&vl2);
! 795: mergev(ALG,vl1,vl2,&vl3);
! 796: vl1 = vl3;
! 797: }
! 798: *r = vl1;
! 799: break;
! 800: case O_VECT:
! 801: vl1 = 0;
! 802: l = ((VECT)f)->len;
! 803: a = BDY((VECT)f);
! 804: for ( i = 0; i < l; i++ ) {
! 805: get_algtree((Obj)a[i],&vl2);
! 806: mergev(ALG,vl1,vl2,&vl3);
! 807: vl1 = vl3;
! 808: }
! 809: *r = vl1;
! 810: break;
! 811: case O_MAT:
! 812: vl1 = 0;
! 813: row = ((MAT)f)->row; col = ((MAT)f)->col;
! 814: m = BDY((MAT)f);
! 815: for ( i = 0; i < row; i++ )
! 816: for ( j = 0; j < col; j++ ) {
! 817: get_algtree((Obj)m[i][j],&vl2);
! 818: mergev(ALG,vl1,vl2,&vl3);
! 819: vl1 = vl3;
! 820: }
! 821: *r = vl1;
! 822: break;
! 823: default:
! 824: *r = 0;
! 825: break;
! 826: }
! 827: }
! 828:
! 829: void algobjtorat(Obj f,Obj *r)
! 830: {
! 831: Obj t;
! 832: DCP dc,dcr,dcr0;
! 833: P p,nm,dn;
! 834: R rat;
! 835: NODE b,s,s0;
! 836: VECT v;
! 837: MAT mat;
! 838: LIST list;
! 839: pointer *a;
! 840: pointer **m;
! 841: int len,row,col,i,j,l;
! 842:
! 843: if ( !f ) *r = 0;
! 844: else
! 845: switch ( OID(f) ) {
! 846: case O_N:
! 847: algtorat((Num)f,r);
! 848: break;
! 849: case O_P:
! 850: dcr0 = 0;
! 851: for ( dc = DC((P)f); dc; dc = NEXT(dc) ) {
! 852: NEXTDC(dcr0,dcr);
! 853: algobjtorat((Obj)COEF(dc),&t);
! 854: COEF(dcr) = (P)t;
! 855: DEG(dcr) = DEG(dc);
! 856: }
! 857: NEXT(dcr) = 0; MKP(VR((P)f),dcr0,p); *r = (Obj)p;
! 858: break;
! 859: case O_R:
! 860: algobjtorat((Obj)NM((R)f),&t); nm = (P)t;
! 861: algobjtorat((Obj)DN((R)f),&t); dn = (P)t;
! 862: MKRAT(nm,dn,0,rat); *r = (Obj)rat;
! 863: break;
! 864: case O_LIST:
! 865: s0 = 0;
! 866: for ( b = BDY((LIST)f); b; b = NEXT(b) ) {
! 867: NEXTNODE(s0,s);
! 868: algobjtorat((Obj)BDY(b),&t);
! 869: BDY(s) = (pointer)t;
! 870: }
! 871: NEXT(s) = 0;
! 872: MKLIST(list,s0);
! 873: *r = (Obj)list;
! 874: break;
! 875: case O_VECT:
! 876: l = ((VECT)f)->len;
! 877: a = BDY((VECT)f);
! 878: MKVECT(v,l);
! 879: for ( i = 0; i < l; i++ ) {
! 880: algobjtorat((Obj)a[i],&t);
! 881: BDY(v)[i] = (pointer)t;
! 882: }
! 883: *r = (Obj)v;
! 884: break;
! 885: case O_MAT:
! 886: row = ((MAT)f)->row; col = ((MAT)f)->col;
! 887: m = BDY((MAT)f);
! 888: MKMAT(mat,row,col);
! 889: for ( i = 0; i < row; i++ )
! 890: for ( j = 0; j < col; j++ ) {
! 891: algobjtorat((Obj)m[i][j],&t);
! 892: BDY(mat)[i][j] = (pointer)t;
! 893: }
! 894: *r = (Obj)mat;
! 895: break;
! 896: default:
! 897: *r = f;
! 898: break;
! 899: }
! 900: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>