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