Annotation of OpenXM_contrib2/asir2000/engine/PU.c, Revision 1.16
1.3 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.4 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.3 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/engine/PU.c,v 1.15 2018/02/28 03:55:38 noro Exp $
1.3 noro 49: */
1.1 noro 50: #include "ca.h"
51:
1.8 noro 52: void reorderp(VL nvl,VL ovl,P p,P *pr)
1.1 noro 53: {
1.16 ! noro 54: DCP dc;
! 55: P x,m,s,t,c;
! 56:
! 57: if ( !p )
! 58: *pr = 0;
! 59: else if ( NUM(p) )
! 60: *pr = p;
! 61: else {
! 62: MKV(VR(p),x);
! 63: for ( s = 0, dc = DC(p); dc; dc = NEXT(dc) ) {
! 64: reorderp(nvl,ovl,COEF(dc),&c);
! 65: if ( DEG(dc) ) {
! 66: pwrp(nvl,x,DEG(dc),&t); mulp(nvl,c,t,&m);
! 67: addp(nvl,m,s,&t);
! 68: } else
! 69: addp(nvl,s,c,&t);
! 70: s = t;
! 71: }
! 72: *pr = s;
! 73: }
1.1 noro 74: }
1.16 ! noro 75:
1.8 noro 76: void substp(VL vl,P p,V v0,P p0,P *pr)
1.1 noro 77: {
1.16 ! noro 78: P x,t,m,c,s,a;
! 79: DCP dc;
! 80: Q d;
! 81:
! 82: if ( !p )
! 83: *pr = 0;
! 84: else if ( NUM(p) )
! 85: *pr = p;
! 86: else if ( VR(p) != v0 ) {
! 87: MKV(VR(p),x);
! 88: for ( c = 0, dc = DC(p); dc; dc = NEXT(dc) ) {
! 89: substp(vl,COEF(dc),v0,p0,&t);
! 90: if ( DEG(dc) ) {
! 91: pwrp(vl,x,DEG(dc),&s); mulp(vl,s,t,&m);
! 92: addp(vl,m,c,&a);
! 93: c = a;
! 94: } else {
! 95: addp(vl,t,c,&a);
! 96: c = a;
! 97: }
! 98: }
! 99: *pr = c;
! 100: } else {
! 101: dc = DC(p);
! 102: c = COEF(dc);
! 103: for ( d = DEG(dc), dc = NEXT(dc);
! 104: dc; d = DEG(dc), dc = NEXT(dc) ) {
! 105: subq(d,DEG(dc),(Q *)&t); pwrp(vl,p0,(Q)t,&s);
! 106: mulp(vl,s,c,&m);
! 107: addp(vl,m,COEF(dc),&c);
! 108: }
! 109: if ( d ) {
! 110: pwrp(vl,p0,d,&t); mulp(vl,t,c,&m);
! 111: c = m;
! 112: }
! 113: *pr = c;
! 114: }
1.1 noro 115: }
116:
1.13 noro 117: void substpp(VL vl,P p,V *vvect,P *svect,int nv,P *pr);
118:
119: void substpp(VL vl,P p,V *vvect,P *svect,int nv,P *pr)
120: {
1.16 ! noro 121: P x,t,m,c,s,a,p0,c1;
! 122: DCP dc;
! 123: Q d;
! 124: V v;
! 125: int i;
! 126:
! 127: if ( !p )
! 128: *pr = 0;
! 129: else if ( NUM(p) )
! 130: *pr = p;
! 131: else {
! 132: v = VR(p);
! 133: for ( i = 0; i < nv; i++ ) if ( vvect[i] == v ) break;
! 134: if ( svect[i] && OID(svect[i]) < 0 ) {
! 135: MKV(VR(p),x);
! 136: for ( c = 0, dc = DC(p); dc; dc = NEXT(dc) ) {
! 137: substpp(vl,COEF(dc),vvect,svect,nv,&t);
! 138: if ( DEG(dc) ) {
! 139: pwrp(vl,x,DEG(dc),&s); mulp(vl,s,t,&m);
! 140: addp(vl,m,c,&a);
! 141: c = a;
! 142: } else {
! 143: addp(vl,t,c,&a);
! 144: c = a;
! 145: }
! 146: }
! 147: *pr = c;
! 148: } else {
! 149: p0 = svect[i];
! 150: dc = DC(p);
! 151: substpp(vl,COEF(dc),vvect,svect,nv,&c);
! 152: for ( d = DEG(dc), dc = NEXT(dc);
! 153: dc; d = DEG(dc), dc = NEXT(dc) ) {
! 154: subq(d,DEG(dc),(Q *)&t); pwrp(vl,p0,(Q)t,&s);
! 155: mulp(vl,s,c,&m);
! 156: substpp(vl,COEF(dc),vvect,svect,nv,&c1);
! 157: addp(vl,m,c1,&c);
! 158: }
! 159: if ( d ) {
! 160: pwrp(vl,p0,d,&t); mulp(vl,t,c,&m);
! 161: c = m;
! 162: }
! 163: *pr = c;
! 164: }
! 165: }
1.13 noro 166: }
167:
1.8 noro 168: void detp(VL vl,P **rmat,int n,P *dp)
1.1 noro 169: {
1.16 ! noro 170: int i,j,k,l,sgn,nmin,kmin,lmin,ntmp;
! 171: P mjj,mij,t,s,u,d;
! 172: P **mat;
! 173: P *mi,*mj;
! 174:
! 175: mat = (P **)almat_pointer(n,n);
! 176: for ( i = 0; i < n; i++ )
! 177: for ( j = 0; j < n; j++ )
! 178: mat[i][j] = rmat[i][j];
! 179: for ( j = 0, d = (P)ONE, sgn = 1; j < n; j++ ) {
! 180: for ( i = j; (i < n) && !mat[i][j]; i++ );
! 181: if ( i == n ) {
! 182: *dp = 0; return;
! 183: }
! 184: nmin = nmonop(mat[i][j]);
! 185: kmin=i; lmin=j;
! 186: for ( k = j; k < n; k++ )
! 187: for ( l = j; l < n; l++ )
! 188: if ( mat[k][l] && ((ntmp=nmonop(mat[k][l])) < nmin) ) {
! 189: kmin = k; lmin = l; nmin = ntmp;
! 190: }
! 191: if ( kmin != j ) {
! 192: mj = mat[j]; mat[j] = mat[kmin]; mat[kmin] = mj; sgn = -sgn;
! 193: }
! 194: if ( lmin != j ) {
! 195: for ( k = j; k < n; k++ ) {
! 196: t = mat[k][j]; mat[k][j] = mat[k][lmin]; mat[k][lmin] = t;
! 197: }
! 198: sgn = -sgn;
! 199: }
! 200: for ( i = j + 1, mj = mat[j], mjj = mj[j]; i < n; i++ )
! 201: for ( k = j + 1, mi = mat[i], mij = mi[j]; k < n; k++ ) {
! 202: mulp(vl,mi[k],mjj,&t); mulp(vl,mj[k],mij,&s);
! 203: subp(vl,t,s,&u); divsp(vl,u,d,&mi[k]);
! 204: }
! 205: d = mjj;
! 206: }
! 207: if ( sgn < 0 )
! 208: chsgnp(d,dp);
! 209: else
! 210: *dp = d;
1.7 noro 211: }
212:
1.8 noro 213: void invmatp(VL vl,P **rmat,int n,P ***imatp,P *dnp)
1.7 noro 214: {
1.16 ! noro 215: int i,j,k,l,n2;
! 216: P mjj,mij,t,s,u,d;
! 217: P **mat,**imat;
! 218: P *mi,*mj,*w;
! 219:
! 220: n2 = n<<1;
! 221: mat = (P **)almat_pointer(n,n2);
! 222: for ( i = 0; i < n; i++ ) {
! 223: for ( j = 0; j < n; j++ )
! 224: mat[i][j] = rmat[i][j];
! 225: mat[i][i+n] = (P)ONE;
! 226: }
! 227: for ( j = 0, d = (P)ONE; j < n; j++ ) {
! 228: for ( i = j; (i < n) && !mat[i][j]; i++ );
! 229: if ( i == n ) {
! 230: error("invmatp : input is singular");
! 231: }
! 232: for ( k = i; k < n; k++ )
! 233: if ( mat[k][j] && (nmonop(mat[k][j]) < nmonop(mat[i][j]) ) )
! 234: i = k;
! 235: if ( j != i ) {
! 236: mj = mat[j]; mat[j] = mat[i]; mat[i] = mj;
! 237: }
! 238: for ( i = j + 1, mj = mat[j], mjj = mj[j]; i < n; i++ )
! 239: for ( k = j + 1, mi = mat[i], mij = mi[j]; k < n2; k++ ) {
! 240: mulp(vl,mi[k],mjj,&t); mulp(vl,mj[k],mij,&s);
! 241: subp(vl,t,s,&u); divsp(vl,u,d,&mi[k]);
! 242: }
! 243: d = mjj;
! 244: }
! 245: /* backward substitution */
! 246: w = (P *)ALLOCA(n2*sizeof(P));
! 247: for ( i = n-2; i >= 0; i-- ) {
! 248: bzero(w,n2*sizeof(P));
! 249: for ( k = i+1; k < n; k++ )
! 250: for ( l = k, u = mat[i][l]; l < n2; l++ ) {
! 251: mulp(vl,mat[k][l],u,&t); addp(vl,w[l],t,&s); w[l] = s;
! 252: }
! 253: for ( j = i, u = mat[i][j]; j < n2; j++ ) {
! 254: mulp(vl,mat[i][j],d,&t); subp(vl,t,w[j],&s);
! 255: divsp(vl,s,u,&mat[i][j]);
! 256: }
! 257: }
! 258: imat = (P **)almat_pointer(n,n);
! 259: for ( i = 0; i < n; i++ )
! 260: for ( j = 0; j < n; j++ )
! 261: imat[i][j] = mat[i][j+n];
! 262: *imatp = imat;
! 263: *dnp = d;
1.1 noro 264: }
265:
1.8 noro 266: void reordvar(VL vl,V v,VL *nvlp)
1.1 noro 267: {
1.16 ! noro 268: VL nvl,nvl0;
1.1 noro 269:
1.16 ! noro 270: for ( NEWVL(nvl0), nvl0->v = v, nvl = nvl0;
! 271: vl; vl = NEXT(vl) )
! 272: if ( vl->v == v )
! 273: continue;
! 274: else {
! 275: NEWVL(NEXT(nvl));
! 276: nvl = NEXT(nvl);
! 277: nvl->v = vl->v;
! 278: }
! 279: NEXT(nvl) = 0;
! 280: *nvlp = nvl0;
1.1 noro 281: }
282:
1.8 noro 283: void gcdprsp(VL vl,P p1,P p2,P *pr)
1.1 noro 284: {
1.16 ! noro 285: P g1,g2,gc1,gc2,gp1,gp2,g,gc,gp,gcr;
! 286: V v1,v2;
1.1 noro 287:
1.16 ! noro 288: if ( !p1 )
! 289: ptozp0(p2,pr);
! 290: else if ( !p2 )
! 291: ptozp0(p1,pr);
! 292: else if ( NUM(p1) || NUM(p2) )
! 293: *pr = (P)ONE;
! 294: else {
! 295: ptozp0(p1,&g1); ptozp0(p2,&g2);
! 296: if ( ( v1 = VR(g1) ) == ( v2 = VR(g2) ) ) {
! 297: gcdcp(vl,g1,&gc1); divsp(vl,g1,gc1,&gp1);
! 298: gcdcp(vl,g2,&gc2); divsp(vl,g2,gc2,&gp2);
! 299: gcdprsp(vl,gc1,gc2,&gcr);
! 300: sprs(vl,v1,gp1,gp2,&g);
! 301:
! 302: if ( VR(g) == v1 ) {
! 303: ptozp0(g,&gp);
! 304: gcdcp(vl,gp,&gc); divsp(vl,gp,gc,&gp1);
! 305: mulp(vl,gp1,gcr,pr);
! 306:
! 307: } else
! 308: *pr = gcr;
! 309: } else {
! 310: while ( v1 != vl->v && v2 != vl->v )
! 311: vl = NEXT(vl);
! 312: if ( v1 == vl->v ) {
! 313: gcdcp(vl,g1,&gc1); gcdprsp(vl,gc1,g2,pr);
! 314: } else {
! 315: gcdcp(vl,g2,&gc2); gcdprsp(vl,gc2,g1,pr);
! 316: }
! 317: }
! 318: }
1.1 noro 319: }
320:
1.8 noro 321: void gcdcp(VL vl,P p,P *pr)
1.1 noro 322: {
1.16 ! noro 323: P g,g1;
! 324: DCP dc;
1.1 noro 325:
1.16 ! noro 326: if ( NUM(p) )
! 327: *pr = (P)ONE;
! 328: else {
! 329: dc = DC(p);
! 330: g = COEF(dc);
! 331: for ( dc = NEXT(dc); dc; dc = NEXT(dc) ) {
! 332: gcdprsp(vl,g,COEF(dc),&g1);
! 333: g = g1;
! 334: }
! 335: *pr = g;
! 336: }
1.1 noro 337: }
338:
1.8 noro 339: void sprs(VL vl,V v,P p1,P p2,P *pr)
1.1 noro 340: {
1.16 ! noro 341: P q1,q2,m,m1,m2,x,h,r,g1,g2;
! 342: int d;
! 343: Q dq;
! 344: VL nvl;
! 345:
! 346: reordvar(vl,v,&nvl);
! 347: reorderp(nvl,vl,p1,&q1); reorderp(nvl,vl,p2,&q2);
! 348:
! 349: if ( ( VR(q1) != v ) || ( VR(q2) != v ) ) {
! 350: *pr = 0;
! 351: return;
! 352: }
! 353:
! 354: if ( deg(v,q1) >= deg(v,q2) ) {
! 355: g1 = q1; g2 = q2;
! 356: } else {
! 357: g2 = q1; g1 = q2;
! 358: }
! 359:
! 360: for ( h = (P)ONE, x = (P)ONE; ; ) {
! 361: if ( !deg(v,g2) )
! 362: break;
! 363:
! 364: premp(nvl,g1,g2,&r);
! 365: if ( !r )
! 366: break;
! 367:
! 368: d = deg(v,g1) - deg(v,g2); STOQ(d,dq);
! 369: pwrp(nvl,h,dq,&m); mulp(nvl,m,x,&m1); g1 = g2;
! 370: divsp(nvl,r,m1,&g2); x = LC(g1); /* g1 is not const w.r.t v */
! 371: pwrp(nvl,x,dq,&m1); mulp(nvl,m1,h,&m2);
! 372: divsp(nvl,m2,m,&h);
! 373: }
! 374: *pr = g2;
1.1 noro 375: }
376:
1.8 noro 377: void resultp(VL vl,V v,P p1,P p2,P *pr)
1.1 noro 378: {
1.16 ! noro 379: P q1,q2,m,m1,m2,lc,q,r,t,g1,g2,adj;
! 380: int d,d1,d2,j,k;
! 381: VL nvl;
! 382: Q dq;
! 383:
! 384: if ( !p1 || !p2 ) {
! 385: *pr = 0; return;
! 386: }
! 387: reordvar(vl,v,&nvl);
! 388: reorderp(nvl,vl,p1,&q1); reorderp(nvl,vl,p2,&q2);
! 389:
! 390: if ( VR(q1) != v )
! 391: if ( VR(q2) != v ) {
! 392: *pr = 0;
! 393: return;
! 394: } else {
! 395: d = deg(v,q2); STOQ(d,dq);
! 396: pwrp(vl,q1,dq,pr);
! 397: return;
! 398: }
! 399: else if ( VR(q2) != v ) {
! 400: d = deg(v,q1); STOQ(d,dq);
! 401: pwrp(vl,q2,dq,pr);
! 402: return;
! 403: }
! 404:
! 405: if ( ( VR(q1) != v ) || ( VR(q2) != v ) ) {
! 406: *pr = 0;
! 407: return;
! 408: }
! 409:
! 410: d1 = deg(v,q1); d2 = deg(v,q2);
! 411: if ( d1 > d2 ) {
! 412: g1 = q1; g2 = q2; adj = (P)ONE;
! 413: } else if ( d1 < d2 ) {
! 414: g2 = q1; g1 = q2;
! 415: if ( (d1 % 2) && (d2 % 2) ) {
! 416: STOQ(-1,dq); adj = (P)dq;
! 417: } else
! 418: adj = (P)ONE;
! 419: } else {
! 420: premp(nvl,q1,q2,&t);
! 421: d = deg(v,t); STOQ(d,dq); pwrp(nvl,LC(q2),dq,&adj);
! 422: g1 = q2; g2 = t;
! 423: if ( d1 % 2 ) {
! 424: chsgnp(adj,&t); adj = t;
! 425: }
! 426: }
! 427: d1 = deg(v,g1); j = d1 - 1;
! 428:
! 429: for ( lc = (P)ONE; ; ) {
! 430: if ( ( k = deg(v,g2) ) < 0 ) {
! 431: *pr = 0;
! 432: return;
! 433: }
! 434:
! 435: if ( k == j )
! 436: if ( !k ) {
! 437: divsp(nvl,g2,adj,pr);
! 438: return;
! 439: } else {
! 440: premp(nvl,g1,g2,&r); mulp(nvl,lc,lc,&m);
! 441: divsp(nvl,r,m,&q);
! 442: g1 = g2; g2 = q;
! 443: lc = LC(g1); /* g1 is not const */
! 444: j = k - 1;
! 445: }
! 446: else {
! 447: d = j - k; STOQ(d,dq);
! 448: pwrp(nvl,(VR(g2)==v?LC(g2):g2),dq,&m);
! 449: mulp(nvl,g2,m,&m1);
! 450: pwrp(nvl,lc,dq,&m); divsp(nvl,m1,m,&t);
! 451: if ( k == 0 ) {
! 452: divsp(nvl,t,adj,pr);
! 453: return;
! 454: } else {
! 455: premp(nvl,g1,g2,&r);
! 456: mulp(nvl,lc,lc,&m1); mulp(nvl,m,m1,&m2);
! 457: divsp(nvl,r,m2,&q);
! 458: g1 = t; g2 = q;
! 459: if ( d % 2 ) {
! 460: chsgnp(g2,&t); g2 = t;
! 461: }
! 462: lc = LC(g1); /* g1 is not const */
! 463: j = k - 1;
! 464: }
! 465: }
! 466: }
1.1 noro 467: }
468:
1.8 noro 469: void srch2(VL vl,V v,P p1,P p2,P *pr)
1.1 noro 470: {
1.16 ! noro 471: P q1,q2,m,m1,m2,lc,q,r,t,s,g1,g2,adj;
! 472: int d,d1,d2,j,k;
! 473: VL nvl;
! 474: Q dq;
! 475:
! 476: reordvar(vl,v,&nvl);
! 477: reorderp(nvl,vl,p1,&q1); reorderp(nvl,vl,p2,&q2);
! 478:
! 479: if ( VR(q1) != v )
! 480: if ( VR(q2) != v ) {
! 481: *pr = 0;
! 482: return;
! 483: } else {
! 484: d = deg(v,q2); STOQ(d,dq);
! 485: pwrp(vl,q1,dq,pr);
! 486: return;
! 487: }
! 488: else if ( VR(q2) != v ) {
! 489: d = deg(v,q1); STOQ(d,dq);
! 490: pwrp(vl,q2,dq,pr);
! 491: return;
! 492: }
! 493:
! 494: if ( ( VR(q1) != v ) || ( VR(q2) != v ) ) {
! 495: *pr = 0;
! 496: return;
! 497: }
! 498:
! 499: if ( deg(v,q1) >= deg(v,q2) ) {
! 500: g1 = q1; g2 = q2;
! 501: } else {
! 502: g2 = q1; g1 = q2;
! 503: }
! 504:
! 505:
! 506: if ( ( d1 = deg(v,g1) ) > ( d2 = deg(v,g2) ) ) {
! 507: j = d1 - 1;
! 508: adj = (P)ONE;
! 509: } else {
! 510: premp(nvl,g1,g2,&t);
! 511: d = deg(v,t); STOQ(d,dq);
! 512: pwrp(nvl,LC(g2),dq,&adj);
! 513: g1 = g2; g2 = t;
! 514: j = deg(v,g1) - 1;
! 515: }
! 516:
! 517: for ( lc = (P)ONE; ; ) {
! 518: if ( ( k = deg(v,g2) ) < 0 ) {
! 519: *pr = 0;
! 520: return;
! 521: }
! 522:
! 523: ptozp(g1,1,(Q *)&t,&s); g1 = s; ptozp(g2,1,(Q *)&t,&s); g2 = s;
! 524: if ( k == j )
! 525: if ( !k ) {
! 526: divsp(nvl,g2,adj,pr);
! 527: return;
! 528: } else {
! 529: premp(nvl,g1,g2,&r); mulp(nvl,lc,lc,&m);
! 530: divsp(nvl,r,m,&q);
! 531: g1 = g2; g2 = q;
! 532: lc = LC(g1); /* g1 is not const */
! 533: j = k - 1;
! 534: }
! 535: else {
! 536: d = j - k; STOQ(d,dq);
! 537: pwrp(nvl,(VR(g2)==v?LC(g2):g2),dq,&m);
! 538: mulp(nvl,g2,m,&m1);
! 539: pwrp(nvl,lc,dq,&m); divsp(nvl,m1,m,&t);
! 540: if ( k == 0 ) {
! 541: divsp(nvl,t,adj,pr);
! 542: return;
! 543: } else {
! 544: premp(nvl,g1,g2,&r);
! 545: mulp(nvl,lc,lc,&m1); mulp(nvl,m,m1,&m2);
! 546: divsp(nvl,r,m2,&q);
! 547: g1 = t; g2 = q;
! 548: if ( d % 2 ) {
! 549: chsgnp(g2,&t); g2 = t;
! 550: }
! 551: lc = LC(g1); /* g1 is not const */
! 552: j = k - 1;
! 553: }
! 554: }
! 555: }
1.1 noro 556: }
557:
1.8 noro 558: void srcr(VL vl,V v,P p1,P p2,P *pr)
1.1 noro 559: {
1.16 ! noro 560: P q1,q2,c,c1;
! 561: P tg,tg1,tg2,resg;
! 562: int index,mod;
! 563: Q a,b,f,q,t,s,u,n,m;
! 564: VL nvl;
! 565:
! 566: reordvar(vl,v,&nvl);
! 567: reorderp(nvl,vl,p1,&q1); reorderp(nvl,vl,p2,&q2);
! 568:
! 569: if ( ( VR(q1) != v ) && ( VR(q2) != v ) ) {
! 570: *pr = 0;
! 571: return;
! 572: }
! 573: if ( VR(q1) != v ) {
! 574: pwrp(vl,q1,DEG(DC(q2)),pr);
! 575: return;
! 576: }
! 577: if ( VR(q2) != v ) {
! 578: pwrp(vl,q2,DEG(DC(q1)),pr);
! 579: return;
! 580: }
! 581: norm1c(q1,&a); norm1c(q2,&b);
! 582: n = DEG(DC(q1)); m = DEG(DC(q2));
! 583: pwrq(a,m,&t); pwrq(b,n,&s); mulq(t,s,&u);
! 584: factorial(QTOS(n)+QTOS(m),&t);
! 585: mulq(u,t,&s); addq(s,s,&f);
! 586: for ( index = 0, q = ONE, c = 0; cmpq(f,q) >= 0; ) {
! 587: mod = get_lprime(index++);
! 588: ptomp(mod,LC(q1),&tg);
! 589: if ( !tg )
! 590: continue;
! 591: ptomp(mod,LC(q2),&tg);
! 592: if ( !tg )
! 593: continue;
! 594: ptomp(mod,q1,&tg1); ptomp(mod,q2,&tg2);
! 595: srchmp(nvl,mod,v,tg1,tg2,&resg);
! 596: chnremp(nvl,mod,c,q,resg,&c1); c = c1;
! 597: STOQ(mod,t); mulq(q,t,&s); q = s;
! 598: }
! 599: *pr = c;
1.1 noro 600: }
601:
1.8 noro 602: void res_ch_det(VL vl,V v,P p1,P p2,P *pr)
1.1 noro 603: {
1.16 ! noro 604: P q1,q2,c,c1;
! 605: P tg,tg1,tg2,resg;
! 606: int index,mod;
! 607: Q a,b,f,q,t,s,u,n,m;
! 608: VL nvl;
! 609:
! 610: reordvar(vl,v,&nvl);
! 611: reorderp(nvl,vl,p1,&q1); reorderp(nvl,vl,p2,&q2);
! 612:
! 613: if ( ( VR(q1) != v ) && ( VR(q2) != v ) ) {
! 614: *pr = 0;
! 615: return;
! 616: }
! 617: if ( VR(q1) != v ) {
! 618: pwrp(vl,q1,DEG(DC(q2)),pr);
! 619: return;
! 620: }
! 621: if ( VR(q2) != v ) {
! 622: pwrp(vl,q2,DEG(DC(q1)),pr);
! 623: return;
! 624: }
! 625: norm1c(q1,&a); norm1c(q2,&b);
! 626: n = DEG(DC(q1)); m = DEG(DC(q2));
! 627: pwrq(a,m,&t); pwrq(b,n,&s); mulq(t,s,&u);
! 628: factorial(QTOS(n)+QTOS(m),&t);
! 629: mulq(u,t,&s); addq(s,s,&f);
! 630: for ( index = 0, q = ONE, c = 0; cmpq(f,q) >= 0; ) {
! 631: mod = get_lprime(index++);
! 632: ptomp(mod,LC(q1),&tg);
! 633: if ( !tg )
! 634: continue;
! 635: ptomp(mod,LC(q2),&tg);
! 636: if ( !tg )
! 637: continue;
! 638: ptomp(mod,q1,&tg1); ptomp(mod,q2,&tg2);
! 639: res_detmp(nvl,mod,v,tg1,tg2,&resg);
! 640: chnremp(nvl,mod,c,q,resg,&c1); c = c1;
! 641: STOQ(mod,t); mulq(q,t,&s); q = s;
! 642: }
! 643: *pr = c;
1.1 noro 644: }
645:
1.8 noro 646: void res_detmp(VL vl,int mod,V v,P p1,P p2,P *dp)
1.1 noro 647: {
1.16 ! noro 648: int n1,n2,n,sgn;
! 649: int i,j,k;
! 650: P mjj,mij,t,s,u,d;
! 651: P **mat;
! 652: P *mi,*mj;
! 653: DCP dc;
! 654:
! 655: n1 = UDEG(p1); n2 = UDEG(p2); n = n1+n2;
! 656: mat = (P **)almat_pointer(n,n);
! 657: for ( dc = DC(p1); dc; dc = NEXT(dc) )
! 658: mat[0][n1-QTOS(DEG(dc))] = COEF(dc);
! 659: for ( i = 1; i < n2; i++ )
! 660: for ( j = 0; j <= n1; j++ )
! 661: mat[i][i+j] = mat[0][j];
! 662: for ( dc = DC(p2); dc; dc = NEXT(dc) )
! 663: mat[n2][n2-QTOS(DEG(dc))] = COEF(dc);
! 664: for ( i = 1; i < n1; i++ )
! 665: for ( j = 0; j <= n2; j++ )
! 666: mat[i+n2][i+j] = mat[n2][j];
! 667: for ( j = 0, d = (P)ONEM, sgn = 1; j < n; j++ ) {
! 668: for ( i = j; (i < n) && !mat[i][j]; i++ );
! 669: if ( i == n ) {
! 670: *dp = 0; return;
! 671: }
! 672: for ( k = i; k < n; k++ )
! 673: if ( mat[k][j] && (nmonop(mat[k][j]) < nmonop(mat[i][j]) ) )
! 674: i = k;
! 675: if ( j != i ) {
! 676: mj = mat[j]; mat[j] = mat[i]; mat[i] = mj; sgn = -sgn;
! 677: }
! 678: for ( i = j + 1, mj = mat[j], mjj = mj[j]; i < n; i++ )
! 679: for ( k = j + 1, mi = mat[i], mij = mi[j]; k < n; k++ ) {
! 680: mulmp(vl,mod,mi[k],mjj,&t); mulmp(vl,mod,mj[k],mij,&s);
! 681: submp(vl,mod,t,s,&u); divsmp(vl,mod,u,d,&mi[k]);
! 682: }
! 683: d = mjj;
! 684: }
! 685: if ( sgn > 0 )
! 686: *dp = d;
! 687: else
! 688: chsgnmp(mod,d,dp);
1.1 noro 689: }
690:
691: #if 0
1.8 noro 692: showmat(VL vl,P **mat,int n)
1.1 noro 693: {
1.16 ! noro 694: int i,j;
! 695: P t;
1.1 noro 696:
1.16 ! noro 697: for ( i = 0; i < n; i++ ) {
! 698: for ( j = 0; j < n; j++ ) {
! 699: mptop(mat[i][j],&t); asir_printp(vl,t); fprintf(out," ");
! 700: }
! 701: fprintf(out,"\n");
! 702: }
! 703: fflush(out);
1.1 noro 704: }
705:
1.8 noro 706: showmp(VL vl,P p)
1.1 noro 707: {
1.16 ! noro 708: P t;
1.1 noro 709:
1.16 ! noro 710: mptop(p,&t); asir_printp(vl,t); fprintf(out,"\n");
1.1 noro 711: }
712: #endif
713:
1.8 noro 714: void premp(VL vl,P p1,P p2,P *pr)
1.1 noro 715: {
1.16 ! noro 716: P m,m1,m2;
! 717: P *pw;
! 718: DCP dc;
! 719: V v1,v2;
! 720: register int i,j;
! 721: int n1,n2,d;
! 722:
! 723: if ( NUM(p1) )
! 724: if ( NUM(p2) )
! 725: *pr = 0;
! 726: else
! 727: *pr = p1;
! 728: else if ( NUM(p2) )
! 729: *pr = 0;
! 730: else if ( ( v1 = VR(p1) ) == ( v2 = VR(p2) ) ) {
! 731: n1 = deg(v1,p1); n2 = deg(v1,p2);
1.15 noro 732: if ( n1 < n2 ) {
733: *pr = p1;
734: return;
735: }
1.16 ! noro 736: pw = (P *)ALLOCA((n1+1)*sizeof(P));
! 737: bzero((char *)pw,(int)((n1+1)*sizeof(P)));
1.1 noro 738:
1.16 ! noro 739: for ( dc = DC(p1); dc; dc = NEXT(dc) )
! 740: pw[QTOS(DEG(dc))] = COEF(dc);
1.1 noro 741:
1.16 ! noro 742: for ( i = n1; i >= n2; i-- ) {
! 743: if ( pw[i] ) {
! 744: m = pw[i];
! 745: for ( j = i; j >= 0; j-- ) {
! 746: mulp(vl,pw[j],LC(p2),&m1); pw[j] = m1;
! 747: }
! 748:
! 749: for ( dc = DC(p2), d = i - n2; dc; dc = NEXT(dc) ) {
! 750: mulp(vl,COEF(dc),m,&m1);
! 751: subp(vl,pw[QTOS(DEG(dc))+d],m1,&m2);
! 752: pw[QTOS(DEG(dc))+d] = m2;
! 753: }
! 754: } else
! 755: for ( j = i; j >= 0; j-- )
! 756: if ( pw[j] ) {
! 757: mulp(vl,pw[j],LC(p2),&m1); pw[j] = m1;
! 758: }
! 759: }
! 760: plisttop(pw,v1,n2-1,pr);
! 761: } else {
! 762: while ( v1 != vl->v && v2 != vl->v )
! 763: vl = NEXT(vl);
! 764: if ( v1 == vl->v )
! 765: *pr = 0;
! 766: else
! 767: *pr = p1;
! 768: }
1.1 noro 769: }
770:
1.8 noro 771: void ptozp0(P p,P *pr)
1.1 noro 772: {
1.16 ! noro 773: Q c;
1.1 noro 774:
1.16 ! noro 775: if ( qpcheck((Obj)p) )
! 776: ptozp(p,1,&c,pr);
! 777: else
! 778: *pr = p;
1.1 noro 779: }
780:
1.8 noro 781: void mindegp(VL vl,P p,VL *mvlp,P *pr)
1.1 noro 782: {
1.16 ! noro 783: P t;
! 784: VL nvl,tvl,avl;
! 785: V v;
! 786: int n,d;
! 787:
! 788: clctv(vl,p,&nvl); v = nvl->v; d = getdeg(nvl->v,p);
! 789: for ( avl = NEXT(nvl); avl; avl = NEXT(avl) ) {
! 790: n = getdeg(avl->v,p);
! 791: if ( n < d ) {
! 792: v = avl->v; d = n;
! 793: }
! 794: }
! 795: if ( v != nvl->v ) {
! 796: reordvar(nvl,v,&tvl); reorderp(tvl,nvl,p,&t);
! 797: *pr = t; *mvlp = tvl;
! 798: } else {
! 799: *pr = p; *mvlp = nvl;
! 800: }
1.1 noro 801: }
802:
1.8 noro 803: void maxdegp(VL vl,P p,VL *mvlp,P *pr)
1.1 noro 804: {
1.16 ! noro 805: P t;
! 806: VL nvl,tvl,avl;
! 807: V v;
! 808: int n,d;
! 809:
! 810: clctv(vl,p,&nvl); v = nvl->v; d = getdeg(nvl->v,p);
! 811: for ( avl = NEXT(nvl); avl; avl = NEXT(avl) ) {
! 812: n = getdeg(avl->v,p);
! 813: if ( n > d ) {
! 814: v = avl->v; d = n;
! 815: }
! 816: }
! 817: if ( v != nvl->v ) {
! 818: reordvar(nvl,v,&tvl); reorderp(tvl,nvl,p,&t);
! 819: *pr = t; *mvlp = tvl;
! 820: } else {
! 821: *pr = p; *mvlp = nvl;
! 822: }
1.1 noro 823: }
824:
1.8 noro 825: void min_common_vars_in_coefp(VL vl,P p,VL *mvlp,P *pr)
1.1 noro 826: {
1.16 ! noro 827: P u,p0;
! 828: VL tvl,cvl,svl,uvl,avl,vl0;
! 829: int n,n0,d,d0;
! 830: DCP dc;
! 831:
! 832: clctv(vl,p,&tvl); vl = tvl;
! 833: for ( tvl = vl, n0 = 0; tvl; tvl = NEXT(tvl), n0++ );
! 834: for ( avl = vl; avl; avl = NEXT(avl) ) {
! 835: if ( VR(p) != avl->v ) {
! 836: reordvar(vl,avl->v,&uvl); reorderp(uvl,vl,p,&u);
! 837: } else {
! 838: uvl = vl; u = p;
! 839: }
! 840: for ( cvl = NEXT(uvl), dc = DC(u); dc && cvl; dc = NEXT(dc) ) {
! 841: clctv(uvl,COEF(dc),&tvl); intersectv(cvl,tvl,&svl); cvl = svl;
! 842: }
! 843: if ( !cvl ) {
! 844: *mvlp = uvl; *pr = u; return;
! 845: } else {
! 846: for ( tvl = cvl, n = 0; tvl; tvl = NEXT(tvl), n++ );
! 847: if ( n < n0 ) {
! 848: vl0 = uvl; p0 = u; n0 = n; d0 = getdeg(uvl->v,u);
! 849: } else if ( (n == n0) && ((d = getdeg(uvl->v,u)) < d0) ) {
! 850: vl0 = uvl; p0 = u; n0 = n; d0 = d;
! 851: }
! 852: }
! 853: }
! 854: *pr = p0; *mvlp = vl0;
1.1 noro 855: }
856:
1.8 noro 857: void minlcdegp(VL vl,P p,VL *mvlp,P *pr)
1.1 noro 858: {
1.16 ! noro 859: P u,p0;
! 860: VL tvl,uvl,avl,vl0;
! 861: int d,d0;
! 862:
! 863: clctv(vl,p,&tvl); vl = tvl;
! 864: vl0 = vl; p0 = p; d0 = homdeg(COEF(DC(p)));
! 865: for ( avl = NEXT(vl); avl; avl = NEXT(avl) ) {
! 866: reordvar(vl,avl->v,&uvl); reorderp(uvl,vl,p,&u);
! 867: d = homdeg(COEF(DC(u)));
! 868: if ( d < d0 ) {
! 869: vl0 = uvl; p0 = u; d0 = d;
! 870: }
! 871: }
! 872: *pr = p0; *mvlp = vl0;
1.1 noro 873: }
874:
1.8 noro 875: void sort_by_deg(int n,P *p,P *pr)
1.1 noro 876: {
1.16 ! noro 877: int j,k,d,k0;
! 878: V v;
1.1 noro 879:
1.16 ! noro 880: for ( j = 0; j < n; j++ ) {
! 881: for ( k0 = k = j, d = deg(v = VR(p[0]),p[j]);
! 882: k < n; k++ )
! 883: if ( deg(v,p[k]) < d ) {
! 884: k0 = k;
! 885: d = deg(v,p[k]);
! 886: }
! 887: pr[j] = p[k0];
! 888: if ( j != k0 )
! 889: p[k0] = p[j];
! 890: }
1.1 noro 891: }
892:
1.8 noro 893: void sort_by_deg_rev(int n,P *p,P *pr)
1.1 noro 894: {
1.16 ! noro 895: int j,k,d,k0;
! 896: V v;
1.1 noro 897:
1.16 ! noro 898: for ( j = 0; j < n; j++ ) {
! 899: for ( k0 = k = j, d = deg(v = VR(p[0]),p[j]);
! 900: k < n; k++ )
! 901: if ( deg(v,p[k]) > d ) {
! 902: k0 = k;
! 903: d = deg(v,p[k]);
! 904: }
! 905: pr[j] = p[k0];
! 906: if ( j != k0 )
! 907: p[k0] = p[j];
! 908: }
1.1 noro 909: }
910:
911:
1.8 noro 912: void getmindeg(V v,P p,Q *dp)
1.1 noro 913: {
1.16 ! noro 914: Q dt,d;
! 915: DCP dc;
1.1 noro 916:
1.16 ! noro 917: if ( !p || NUM(p) )
! 918: *dp = 0;
! 919: else if ( v == VR(p) ) {
! 920: for ( dc = DC(p); NEXT(dc); dc = NEXT(dc) );
! 921: *dp = DEG(dc);
! 922: } else {
! 923: dc = DC(p);
! 924: getmindeg(v,COEF(dc),&d);
! 925: for ( dc = NEXT(dc); dc; dc = NEXT(dc) ) {
! 926: getmindeg(v,COEF(dc),&dt);
! 927: if ( cmpq(dt,d) < 0 )
! 928: d = dt;
! 929: }
! 930: *dp = d;
! 931: }
1.1 noro 932: }
933:
1.8 noro 934: void minchdegp(VL vl,P p,VL *mvlp,P *pr)
1.1 noro 935: {
1.16 ! noro 936: P t;
! 937: VL tvl,nvl,avl;
! 938: int n,d,z;
! 939: V v;
! 940:
! 941: if ( NUM(p) ) {
! 942: *mvlp = vl;
! 943: *pr = p;
! 944: return;
! 945: }
! 946: clctv(vl,p,&nvl);
! 947: v = nvl->v;
! 948: d = getchomdeg(v,p) + getlchomdeg(v,p,&z);
! 949: for ( avl = NEXT(nvl); avl; avl = NEXT(avl) ) {
! 950: n = getchomdeg(avl->v,p) + getlchomdeg(avl->v,p,&z);
! 951: if ( n < d ) {
! 952: v = avl->v; d = n;
! 953: }
! 954: }
! 955: if ( v != nvl->v ) {
! 956: reordvar(nvl,v,&tvl); reorderp(tvl,nvl,p,&t);
! 957: *pr = t; *mvlp = tvl;
! 958: } else {
! 959: *pr = p; *mvlp = nvl;
! 960: }
1.1 noro 961: }
962:
1.8 noro 963: int getchomdeg(V v,P p)
1.1 noro 964: {
1.16 ! noro 965: int m,m1;
! 966: DCP dc;
1.1 noro 967:
1.16 ! noro 968: if ( !p || NUM(p) )
! 969: return ( 0 );
! 970: else if ( VR(p) == v )
! 971: return ( dbound(v,p) );
! 972: else {
! 973: for ( dc = DC(p), m = 0; dc; dc = NEXT(dc) ) {
! 974: m1 = getchomdeg(v,COEF(dc))+QTOS(DEG(dc));
! 975: m = MAX(m,m1);
! 976: }
! 977: return ( m );
! 978: }
1.1 noro 979: }
980:
1.8 noro 981: int getlchomdeg(V v,P p,int *d)
1.1 noro 982: {
1.16 ! noro 983: int m0,m1,d0,d1;
! 984: DCP dc;
1.1 noro 985:
1.16 ! noro 986: if ( !p || NUM(p) ) {
! 987: *d = 0;
! 988: return ( 0 );
! 989: } else if ( VR(p) == v ) {
! 990: *d = QTOS(DEG(DC(p)));
! 991: return ( homdeg(LC(p)) );
! 992: } else {
! 993: for ( dc = DC(p), m0 = 0, d0 = 0; dc; dc = NEXT(dc) ) {
! 994: m1 = getlchomdeg(v,COEF(dc),&d1)+QTOS(DEG(dc));
! 995: if ( d1 > d0 ) {
! 996: m0 = m1;
! 997: d0 = d1;
! 998: } else if ( d1 == d0 )
! 999: m0 = MAX(m0,m1);
! 1000: }
! 1001: *d = d0;
! 1002: return ( m0 );
! 1003: }
1.1 noro 1004: }
1005:
1.8 noro 1006: int nmonop(P p)
1.1 noro 1007: {
1.16 ! noro 1008: int s;
! 1009: DCP dc;
1.1 noro 1010:
1.16 ! noro 1011: if ( !p )
! 1012: return 0;
! 1013: else
! 1014: switch ( OID(p) ) {
! 1015: case O_N:
! 1016: return 1; break;
! 1017: case O_P:
! 1018: for ( dc = DC((P)p), s = 0; dc; dc = NEXT(dc) )
! 1019: s += nmonop(COEF(dc));
! 1020: return s; break;
! 1021: default:
! 1022: return 0;
! 1023: }
1.1 noro 1024: }
1025:
1.8 noro 1026: int qpcheck(Obj p)
1.1 noro 1027: {
1.16 ! noro 1028: DCP dc;
1.1 noro 1029:
1.16 ! noro 1030: if ( !p )
! 1031: return 1;
! 1032: else
! 1033: switch ( OID(p) ) {
! 1034: case O_N:
! 1035: return RATN((Num)p)?1:0;
! 1036: case O_P:
! 1037: for ( dc = DC((P)p); dc; dc = NEXT(dc) )
! 1038: if ( !qpcheck((Obj)COEF(dc)) )
! 1039: return 0;
! 1040: return 1;
! 1041: default:
! 1042: return 0;
! 1043: }
1.1 noro 1044: }
1045:
1046: /* check if p is univariate and all coeffs are INT or LM */
1047:
1.8 noro 1048: int uzpcheck(Obj p)
1.1 noro 1049: {
1.16 ! noro 1050: DCP dc;
! 1051: P c;
1.1 noro 1052:
1.16 ! noro 1053: if ( !p )
! 1054: return 1;
! 1055: else
! 1056: switch ( OID(p) ) {
! 1057: case O_N:
! 1058: return (RATN((Num)p)&&INT(p))||(NID((Num)p)==N_LM);
! 1059: case O_P:
! 1060: for ( dc = DC((P)p); dc; dc = NEXT(dc) ) {
! 1061: c = COEF(dc);
! 1062: if ( !NUM(c) || !uzpcheck((Obj)c) )
! 1063: return 0;
! 1064: }
! 1065: return 1;
! 1066: default:
! 1067: return 0;
! 1068: }
1.1 noro 1069: }
1070:
1.8 noro 1071: int p_mag(P p)
1.1 noro 1072: {
1.16 ! noro 1073: int s;
! 1074: DCP dc;
1.1 noro 1075:
1.16 ! noro 1076: if ( !p )
! 1077: return 0;
! 1078: else if ( OID(p) == O_N )
! 1079: return n_bits(NM((Q)p))+(INT((Q)p)?0:n_bits(DN((Q)p)));
! 1080: else {
! 1081: for ( dc = DC(p), s = 0; dc; dc = NEXT(dc) )
! 1082: s += p_mag(COEF(dc));
! 1083: return s;
! 1084: }
1.1 noro 1085: }
1.2 noro 1086:
1.8 noro 1087: int maxblenp(P p)
1.2 noro 1088: {
1.16 ! noro 1089: int s,t;
! 1090: DCP dc;
1.2 noro 1091:
1.16 ! noro 1092: if ( !p )
! 1093: return 0;
! 1094: else if ( OID(p) == O_N )
! 1095: return n_bits(NM((Q)p))+(INT((Q)p)?0:n_bits(DN((Q)p)));
! 1096: else {
! 1097: for ( dc = DC(p), s = 0; dc; dc = NEXT(dc) ) {
! 1098: t = maxblenp(COEF(dc));
! 1099: s = MAX(t,s);
! 1100: }
! 1101: return s;
! 1102: }
1.2 noro 1103: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>