Annotation of OpenXM_contrib2/asir2000/engine/dalg.c, Revision 1.3
1.1 noro 1: /*
1.3 ! noro 2: * $OpenXM: OpenXM_contrib2/asir2000/engine/dalg.c,v 1.2 2004/12/02 08:39:54 noro Exp $
1.1 noro 3: */
4:
5: #include "ca.h"
6: #include "base.h"
7:
8: static NumberField current_numberfield;
9: extern struct order_spec *dp_current_spec;
1.2 noro 10: void simpdalg(DAlg da,DAlg *r);
1.3 ! noro 11: void invdalg(DAlg a,DAlg *c);
! 12: void rmcontdalg(DAlg a, DAlg *c);
1.1 noro 13:
14: void setfield_dalg(NODE alist)
15: {
16: NumberField nf;
17: VL vl,vl1,vl2;
18: int n,i,dim;
19: Alg *gen;
20: P *defpoly;
21: P p;
22: Q c,iq,two;
23: DP *ps,*mb;
1.3 ! noro 24: DP one;
1.1 noro 25: NODE t,b,b1,b2,hlist,mblist;
26: struct order_spec *current_spec;
27:
28: nf = (NumberField)MALLOC(sizeof(struct oNumberField));
29: current_numberfield = nf;
30: vl = 0;
31: for ( t = alist; t; t = NEXT(t) ) {
32: clctalg(BDY((Alg)BDY(t)),&vl1);
33: mergev(ALG,vl,vl1,&vl2); vl = vl2;
34: }
35: for ( n = 0, vl1 = vl; vl1; vl1 = NEXT(vl1), n++ );
36: nf->n = n;
37: nf->vl = vl;
38: nf->defpoly = defpoly = (P *)MALLOC(n*sizeof(P));
39: nf->ps = ps = (DP *)MALLOC(n*sizeof(DP));
40: current_spec = dp_current_spec;
41: STOQ(2,two);
42: create_order_spec(0,(Obj)two,&nf->spec);
43: initd(nf->spec);
44: for ( b = hlist = 0, i = 0, vl1 = vl; i < n; vl1 = NEXT(vl1), i++ ) {
45: ptozp(vl1->v->attr,1,&c,&defpoly[i]);
46: ptod(ALG,vl,defpoly[i],&ps[i]);
47: STOQ(i,iq); MKNODE(b1,(pointer)iq,b); b = b1;
1.3 ! noro 48: MKNODE(b2,(pointer)ps[i],hlist); hlist = b2;
1.1 noro 49: }
1.3 ! noro 50: ptod(ALG,vl,(P)ONE,&one);
! 51: MKDAlg(one,ONE,nf->one);
! 52: nf->ind = b;
! 53: dp_mbase(hlist,&mblist);
1.1 noro 54: initd(current_spec);
55: nf->dim = dim = length(mblist);
56: nf->mb = mb = (DP *)MALLOC(dim*sizeof(DP));
57: for ( i = 0, t = mblist; t; t = NEXT(t), i++ )
1.3 ! noro 58: mb[i] = (DP)BDY(t);
1.1 noro 59: }
60:
61: void algtodalg(Alg a,DAlg *r)
62: {
63: P ap,p,p1;
1.3 ! noro 64: Q c,c1,d1,dn,nm;
1.1 noro 65: DP dp;
66: DAlg da;
67: NumberField nf;
68: struct order_spec *current_spec;
1.3 ! noro 69: VL vl,tvl,svl;
! 70: V v;
1.1 noro 71:
72: if ( !(nf=current_numberfield) )
73: error("algtodalg : current_numberfield is not set");
1.3 ! noro 74: if ( !a ) {
! 75: *r = 0;
! 76: return;
! 77: }
! 78: switch (NID((Num)a) ) {
! 79: case N_Q:
! 80: c = (Q)a;
! 81: if ( INT(c) ) {
! 82: muldc(CO,nf->one->nm,(P)c,&dp);
! 83: MKDAlg(dp,ONE,*r);
! 84: } else {
! 85: NTOQ(NM(c),SGN(c),c1);
! 86: NTOQ(DN(c),1,d1);
! 87: muldc(CO,nf->one->nm,(P)c1,&dp);
! 88: MKDAlg(dp,c1,*r);
! 89: }
! 90: break;
! 91: case N_A:
! 92: ap = (P)BDY(a);
! 93: ptozp(ap,1,&c,&p);
! 94: if ( INT(c) ) {
! 95: p = ap;
! 96: dn = ONE;
! 97: } else {
! 98: NTOQ(NM(c),SGN(c),nm);
! 99: NTOQ(DN(c),1,dn);
! 100: mulpq(p,(P)nm,&p1); p = p1;
! 101: }
! 102: current_spec = dp_current_spec; initd(nf->spec);
! 103: get_vars(p,&vl);
! 104: for ( tvl = vl; tvl; tvl = NEXT(tvl) ) {
! 105: v = tvl->v;
! 106: for ( svl = nf->vl; svl; svl = NEXT(svl) )
! 107: if ( v == svl->v )
! 108: break;
! 109: if ( !svl )
! 110: error("algtodalg : incompatible numberfield");
! 111: }
! 112: ptod(ALG,nf->vl,p,&dp);
! 113: MKDAlg(dp,dn,da);
! 114: simpdalg(da,r);
! 115: break;
! 116: default:
! 117: error("algtodalg : invalid argument");
! 118: break;
1.1 noro 119: }
120: }
121:
1.2 noro 122: void dalgtoalg(DAlg da,Alg *r)
1.1 noro 123: {
1.2 noro 124: NumberField nf;
125: P p,p1;
126: Q inv;
127:
128: if ( !(nf=current_numberfield) )
1.3 ! noro 129: error("dalgtoalg : current_numberfield is not set");
1.2 noro 130: dtop(ALG,nf->vl,da->nm,&p);
131: invq(da->dn,&inv);
132: mulpq(p,(P)inv,&p1);
133: MKAlg(p1,*r);
1.1 noro 134: }
135:
136: void simpdalg(DAlg da,DAlg *r)
137: {
1.2 noro 138: NumberField nf;
139: DP nm;
1.3 ! noro 140: DAlg d;
1.2 noro 141: Q dn,dn1;
142:
143: if ( !(nf=current_numberfield) )
1.3 ! noro 144: error("simpdalg : current_numberfield is not set");
! 145: if ( !da ) {
! 146: *r = 0;
! 147: return;
! 148: }
1.2 noro 149: dp_true_nf(nf->ind,da->nm,nf->ps,1,&nm,&dn);
150: mulq(da->dn,dn,&dn1);
1.3 ! noro 151: MKDAlg(nm,dn1,d);
! 152: rmcontdalg(d,r);
1.1 noro 153: }
154:
155: void adddalg(DAlg a,DAlg b,DAlg *c)
156: {
1.3 ! noro 157: NumberField nf;
! 158: Q dna,dnb,a1,b1,dn,g;
! 159: N an,bn,gn;
! 160: DP ta,tb,nm;
! 161: struct order_spec *current_spec;
! 162:
! 163: if ( !(nf=current_numberfield) )
! 164: error("adddalg : current_numberfield is not set");
! 165: if ( !a )
! 166: *c = b;
! 167: else if ( !b )
! 168: *c = a;
! 169: else {
! 170: dna = a->dn;
! 171: dnb = b->dn;
! 172: gcdn(NM(dna),NM(dnb),&gn);
! 173: divsn(NM(dna),gn,&an); divsn(NM(dnb),gn,&bn);
! 174: NTOQ(an,SGN(dna),a1); NTOQ(bn,SGN(dnb),b1);
! 175: /* nma/dna+nmb/dnb = (nma*b1+nmb*a1)/(dna*b1) */
! 176: muldc(CO,a->nm,(P)b1,&ta); muldc(CO,b->nm,(P)a1,&tb);
! 177: current_spec = dp_current_spec; initd(nf->spec);
! 178: addd(CO,ta,tb,&nm);
! 179: initd(current_spec);
! 180: if ( !nm )
! 181: *c = 0;
! 182: else {
! 183: mulq(dna,b1,&dn);
! 184: MKDAlg(nm,dn,*c);
! 185: }
! 186: }
1.1 noro 187: }
188:
189: void subdalg(DAlg a,DAlg b,DAlg *c)
190: {
1.3 ! noro 191: NumberField nf;
! 192: Q dna,dnb,a1,b1,dn,g;
! 193: N an,bn,gn;
! 194: DP ta,tb,nm;
! 195: struct order_spec *current_spec;
! 196:
! 197: if ( !(nf=current_numberfield) )
! 198: error("subdalg : current_numberfield is not set");
! 199: if ( !a )
! 200: *c = b;
! 201: else if ( !b )
! 202: *c = a;
! 203: else {
! 204: dna = a->dn;
! 205: dnb = b->dn;
! 206: gcdn(NM(dna),NM(dnb),&gn);
! 207: divsn(NM(dna),gn,&an); divsn(NM(dnb),gn,&bn);
! 208: NTOQ(an,SGN(dna),a1); NTOQ(bn,SGN(dnb),b1);
! 209: /* nma/dna-nmb/dnb = (nma*b1-nmb*a1)/(dna*b1) */
! 210: muldc(CO,a->nm,(P)b1,&ta); muldc(CO,b->nm,(P)a1,&tb);
! 211: current_spec = dp_current_spec; initd(nf->spec);
! 212: subd(CO,ta,tb,&nm);
! 213: initd(current_spec);
! 214: if ( !nm )
! 215: *c = 0;
! 216: else {
! 217: mulq(dna,b1,&dn);
! 218: MKDAlg(nm,dn,*c);
! 219: }
! 220: }
1.1 noro 221: }
222:
1.2 noro 223: void muldalg(DAlg a,DAlg b,DAlg *c)
224: {
1.3 ! noro 225: NumberField nf;
! 226: DP nm;
! 227: Q dn;
! 228: DAlg t;
! 229: struct order_spec *current_spec;
! 230:
! 231: if ( !(nf=current_numberfield) )
! 232: error("muldalg : current_numberfield is not set");
! 233: if ( !a || !b )
! 234: *c = 0;
! 235: else {
! 236: current_spec = dp_current_spec; initd(nf->spec);
! 237: muld(CO,a->nm,b->nm,&nm);
! 238: initd(current_spec);
! 239: mulq(a->dn,b->dn,&dn);
! 240: MKDAlg(nm,dn,t);
! 241: simpdalg(t,c);
! 242: }
1.2 noro 243: }
244:
245:
1.1 noro 246: void divdalg(DAlg a,DAlg b,DAlg *c)
247: {
1.3 ! noro 248: DAlg inv;
! 249:
1.1 noro 250: if ( !current_numberfield )
1.3 ! noro 251: error("divdalg : current_numberfield is not set");
! 252: if ( !b )
! 253: error("divdalg : division by 0");
! 254: if ( !a )
! 255: c = 0;
! 256: else {
! 257: invdalg(b,&inv);
! 258: muldalg(a,inv,c);
! 259: }
! 260: }
! 261:
! 262: void rmcontdalg(DAlg a, DAlg *r)
! 263: {
! 264: DP u,u1;
! 265: Q cont,c,d;
! 266: N gn,cn,dn;
! 267:
! 268: if ( !a )
! 269: *r = a;
! 270: else {
! 271: dp_ptozp(a->nm,&u);
! 272: divq((Q)BDY(a->nm)->c,(Q)BDY(u)->c,&cont);
! 273: gcdn(NM(cont),NM(a->dn),&gn);
! 274: divsn(NM(cont),gn,&cn); NTOQ(cn,SGN(cont),c);
! 275: divsn(NM(a->dn),gn,&dn); NTOQ(dn,SGN(a->dn),d);
! 276: muldc(CO,u,(P)c,&u1);
! 277: MKDAlg(u1,d,*r);
! 278: }
1.1 noro 279: }
280:
281: void invdalg(DAlg a,DAlg *c)
282: {
1.3 ! noro 283: NumberField nf;
! 284: int dim,n,i,j;
! 285: DP *mb;
! 286: DP m,d,u;
! 287: N ln,gn,qn;
! 288: DAlg *simp;
! 289: DAlg t,a0,r;
! 290: Q dn,dnsol,mul;
! 291: MAT mobj,sol;
! 292: Q **mat,**solmat;
! 293: MP mp0,mp;
! 294: int *rinfo,*cinfo;
! 295: struct order_spec *current_spec;
! 296:
! 297: if ( !(nf=current_numberfield) )
! 298: error("invdalg : current_numberfield is not set");
! 299: if ( !a )
! 300: error("invdalg : division by 0");
! 301: dim = nf->dim;
! 302: mb = nf->mb;
! 303: n = nf->n;
! 304: ln = ONEN;
! 305: MKDAlg(a->nm,ONE,a0);
! 306: simp = (DAlg *)ALLOCA(dim*sizeof(DAlg));
! 307: current_spec = dp_current_spec; initd(nf->spec);
! 308: for ( i = dim-1; i >= 0; i-- ) {
! 309: m = mb[i];
! 310: for ( j = i+1; j < dim; j++ )
! 311: if ( dp_redble(m,mb[j]) )
! 312: break;
! 313: if ( j < dim ) {
! 314: dp_subd(m,mb[j],&d);
! 315: muld(CO,d,simp[j]->nm,&u);
! 316: MKDAlg(u,simp[j]->dn,t);
! 317: simpdalg(t,&simp[i]);
! 318: } else {
! 319: MKDAlg(m,ONE,t);
! 320: muldalg(t,a0,&simp[i]);
! 321: }
! 322: gcdn(NM(simp[i]->dn),ln,&gn); divsn(ln,gn,&qn);
! 323: muln(NM(simp[i]->dn),qn,&ln);
! 324: }
! 325: initd(current_spec);
! 326: NTOQ(ln,1,dn);
! 327: MKMAT(mobj,dim,dim+1);
! 328: mat = (Q **)BDY(mobj);
! 329: mulq(dn,a->dn,&mat[dim-1][dim]);
! 330: for ( j = 0; j < dim; j++ ) {
! 331: divq(dn,simp[j]->dn,&mul);
! 332: for ( i = 0, mp = BDY(simp[j]->nm); mp && i < dim; i++ )
! 333: if ( dl_equal(n,BDY(mb[i])->dl,mp->dl) ) {
! 334: mulq(mul,(Q)mp->c,&mat[i][j]);
! 335: mp = NEXT(mp);
! 336: }
! 337: }
! 338: generic_gauss_elim_hensel(mobj,&sol,&dnsol,&rinfo,&cinfo);
! 339: solmat = (Q **)BDY(sol);
! 340: for ( i = 0, mp0 = 0; i < dim; i++ )
! 341: if ( solmat[i][0] ) {
! 342: NEXTMP(mp0,mp);
! 343: mp->c = (P)solmat[i][0];
! 344: mp->dl = BDY(mb[i])->dl;
! 345: }
! 346: NEXT(mp) = 0; MKDP(n,mp0,u);
! 347: MKDAlg(u,dnsol,r);
! 348: rmcontdalg(r,c);
1.1 noro 349: }
350:
351: void chsgndalg(DAlg a,DAlg *c)
352: {
1.3 ! noro 353: DP nm;
! 354:
! 355: if ( !a ) *c = 0;
! 356: else {
! 357: chsgnd(a->nm,&nm);
! 358: MKDAlg(nm,a->dn,*c);
! 359: }
1.1 noro 360: }
361:
1.3 ! noro 362: void pwrdalg(DAlg a,Q e,DAlg *c)
1.1 noro 363: {
1.3 ! noro 364: NumberField nf;
! 365: DAlg t,z,y;
! 366: N en,qn;
! 367: int r;
! 368:
! 369: if ( !(nf=current_numberfield) )
! 370: error("pwrdalg : current_numberfield is not set");
! 371: if ( !e )
! 372: *c = nf->one;
! 373: else if ( UNIQ(e) )
! 374: *c = a;
! 375: else {
! 376: if ( SGN(e) < 0 ) {
! 377: invdalg(a,&t); a = t;
! 378: }
! 379: en = NM(e);
! 380: y = nf->one;
! 381: z = a;
! 382: while ( 1 ) {
! 383: r = divin(en,2,&qn); en = qn;
! 384: if ( r ) {
! 385: muldalg(z,y,&t); y = t;
! 386: if ( !en ) {
! 387: *c = y;
! 388: return;
! 389: }
! 390: }
! 391: muldalg(z,z,&t); z = t;
! 392: }
! 393: }
1.1 noro 394: }
395:
1.3 ! noro 396: int cmpdalg(DAlg a,DAlg b)
1.1 noro 397: {
1.3 ! noro 398: DAlg c;
! 399:
! 400: subdalg(a,b,&c);
! 401: if ( !c ) return 0;
! 402: else
! 403: return SGN((Q)BDY(c->nm)->c);
1.1 noro 404: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>