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

Annotation of OpenXM_contrib2/asir2000/engine/PU.c, Revision 1.7

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

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