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

Annotation of OpenXM_contrib2/asir2000/builtin/iarray.c, Revision 1.1

1.1     ! saito       1: /*
        !             2:  * $OpenXM$
        !             3: */
        !             4: #include "ca.h"
        !             5: #include "base.h"
        !             6: #include "parse.h"
        !             7: #include "inline.h"
        !             8:
        !             9: extern int StrassenSize;
        !            10:
        !            11: struct ftab imat_tab[] = {
        !            12:        {"newimat", Pnewimat,2},
        !            13:        {"m2im",  Pm2Im,1},
        !            14:        {"im2m",  PIm2m,1},
        !            15:        {0,0,0},
        !            16: };
        !            17:
        !            18: const IENT zent = { -1, -1, -1, 0}; /* last ient const */
        !            19:
        !            20: void MEnt(cr, row, col, trg, ent)
        !            21: int cr, row, col;
        !            22: Obj trg;
        !            23: IENT *ent;
        !            24: {
        !            25:        /* make Index Entry IENT */
        !            26:        /* set:cr, row, trag */
        !            27:        /* return: value ent */
        !            28:        /* MEnt(cr, row, col, trg, &ent); */
        !            29:
        !            30:        ent->cr = cr;
        !            31:        ent->row = row;
        !            32:        ent->col = col;
        !            33:        ent->body = (pointer)trg;
        !            34: }
        !            35:
        !            36: void GetNextIent(Im, ent, c)
        !            37: IMATC *Im;
        !            38: IENT *ent;
        !            39: int *c;
        !            40: {
        !            41:        /* get next IENT */
        !            42:        /* set: Im, c */
        !            43:        /* return: ent, c */
        !            44:        /* GetNextIent(&Im, &ent, &c); */
        !            45:
        !            46:        if( (++*c) >= IMATCH ){
        !            47:                if ( ! (IMATC)(*Im)->next ) {
        !            48:                /* no more IENT */
        !            49:                        *c = -1;
        !            50:                        return;
        !            51:                }
        !            52:                *Im = (IMATC)(*Im)->next;
        !            53:                *c = 0;
        !            54:        }
        !            55:        *ent = (*Im)->ient[*c];
        !            56: }
        !            57:
        !            58: void GetForeIent(Im, ent, c)
        !            59: IMATC *Im;
        !            60: IENT *ent;
        !            61: int *c;
        !            62: {
        !            63:        /* GetForeIent(&Im, &ent, &c); */
        !            64:
        !            65:        /* find last IENT */
        !            66:        if( (--*c) < 0 ){
        !            67:                if ( !(IMATC)(*Im)->fore ){
        !            68:                /* no more IENT */
        !            69:                        *c = -1;
        !            70:                        return;
        !            71:                }
        !            72:                /* next IENT block */
        !            73:                *Im = (IMATC)(*Im)->fore;
        !            74:                *c = IMATCH - 1;
        !            75:        }
        !            76:        *ent = (*Im)->ient[*c];
        !            77: }
        !            78:
        !            79: void AppendIent(m, row, col, body)
        !            80: IMAT m;
        !            81: int row, col;
        !            82: Obj body;
        !            83: {
        !            84:        /* append row, col, body to matrix m */
        !            85:        IMATC Im, Imt;
        !            86:        int d;
        !            87:
        !            88:        if ( ! body ) return;
        !            89:        if ( ! m->clen ) {
        !            90:                NEWIENT(Im);
        !            91:                m->root = (pointer)Im;
        !            92:                m->toor = (pointer)Im;
        !            93:                m->clen = 1;
        !            94:                MEnt(row * m->row + col, row, col, body, &Im->ient[0]);
        !            95:                Im->ient[1] = zent;
        !            96:        } else {
        !            97:                Im = (pointer)m->toor;
        !            98:                for( d = 0; Im->ient[d].cr != -1; d++);
        !            99:                if ( d == IMATCH - 1 ) {
        !           100:                        /* append point is chank end */
        !           101:                        NEWIENT(Imt);
        !           102:                        Im->next = (pointer)Imt;
        !           103:                        m->toor = (pointer)Imt;
        !           104:                        ++(m->clen);
        !           105:                        Imt->fore = (pointer)Im;
        !           106:                        Imt->next = 0;
        !           107:                        MEnt(row * m->row + col, row, col, body, &Im->ient[d]);
        !           108:                        Imt->ient[0] = zent;
        !           109:                } else {
        !           110:                        MEnt(row * m->row + col, row, col, body, &Im->ient[d]);
        !           111:                        Im->ient[d + 1] = zent;
        !           112:                }
        !           113:        }
        !           114: }
        !           115:
        !           116: void PutIent(m, row, col, trg)
        !           117: IMAT m;
        !           118: int row, col;
        !           119: Obj trg;
        !           120: {
        !           121:        /* insert or replace IENT */
        !           122:        IMATC Im, Imn;
        !           123:        IENT ent, tent;
        !           124:        int cr, c, d;
        !           125:
        !           126:        if ( m->row <= row || m->col <= col || row < 0 || col < 0 )
        !           127:                error("putim : Out of rage");
        !           128:        cr = row * m->row + col;
        !           129:        if ( ! m->clen ) {
        !           130:                if( trg == 0 ) return;
        !           131:                AppendIent(m, row, col, trg);
        !           132:                return;
        !           133:        }
        !           134:        MEnt(cr, row, col, trg, &tent);
        !           135:        Im = (pointer)m->root;
        !           136:        c = -1;
        !           137:        GetNextIent(&Im, &ent, &c);
        !           138:        while (ent.cr < cr) {
        !           139:                GetNextIent(&Im, &ent, &c);
        !           140:                if( c == -1 ) {
        !           141:                        /* zero insert case */
        !           142:                        if ( ! trg ) return;
        !           143:                        /* last append case */
        !           144:                        AppendIent(m, row, col, trg);
        !           145:                        return;
        !           146:                }
        !           147:        }
        !           148:        if ( ent.cr == cr ) {
        !           149:                /* same row and col (replace) case */
        !           150:                if ( ! trg ) {
        !           151:                        /* IENT remove case */
        !           152:                        Imn = Im;
        !           153:                        while ( c != -1 ) {
        !           154:                                GetNextIent( &Im, &ent, &c );
        !           155:                                if ( ! c ) {
        !           156:                                        Imn->ient[IMATCH-1] = ent;
        !           157:                                        Imn = Im;
        !           158:                                } else {
        !           159:                                        Im->ient[c - 1] = ent;
        !           160:                                }
        !           161:                        }
        !           162:                } else {
        !           163:                        /* replase case */
        !           164:                        Im->ient[c] = tent;
        !           165:                }
        !           166:        } else {
        !           167:                /* IENT insert case */
        !           168:                while( c != -1 ) {
        !           169:                        Im->ient[c] = tent;
        !           170:                        tent = ent;
        !           171:                        GetNextIent(&Im, &ent, &c);
        !           172:                }
        !           173:
        !           174:        }
        !           175: }
        !           176:
        !           177: void Pnewimat(arg, rp)
        !           178: NODE arg;
        !           179: IMAT *rp;
        !           180: {
        !           181:        /* make new index type matrix for parser */
        !           182:        int row,col;
        !           183:        IMAT m;
        !           184:
        !           185:        asir_assert(ARG0(arg),O_N,"newimat");
        !           186:        asir_assert(ARG1(arg),O_N,"newimat");
        !           187:        row = QTOS((Q)ARG0(arg)); col = QTOS((Q)ARG1(arg));
        !           188:        if ( row <= 0 || col <= 0 ) error("newimat : invalid size");
        !           189:        NEWIMAT(m);
        !           190:        m->col = col;
        !           191:        m->row = row;
        !           192:        *rp = m;
        !           193: }
        !           194:
        !           195: void GetIbody(m, row, col, trg)
        !           196: IMAT m;
        !           197: int col, row;
        !           198: Obj *trg;
        !           199: {
        !           200:        /* get entry body from m for parser */
        !           201:        IMATC Im;
        !           202:        IENT ent;
        !           203:        int cr;
        !           204:        int c;
        !           205:
        !           206:        if ( m->row <= row || m->col <= col || row < 0 || col < 0 )
        !           207:                error("putim : Out of rage");
        !           208:        if ( ! m->clen ) {
        !           209:        /* zero matrix case */
        !           210:                *trg = (Obj)0;
        !           211:        } else {
        !           212:                cr = row * m->row + col;
        !           213:                c = -1;
        !           214:                Im = (pointer)m->root;
        !           215:                GetNextIent( &Im, &ent, &c);
        !           216:                while( ent.cr < cr ) {
        !           217:                        if ( ent.cr == -1 ) {
        !           218:                        /* not fined ent to last case */
        !           219:                                *trg = (Obj)0;
        !           220:                                return;
        !           221:                        }
        !           222:                        GetNextIent( &Im, &ent, &c);
        !           223:                }
        !           224:                if ( ent.cr == cr ) *trg = (Obj)ent.body;
        !           225:                else *trg = (Obj)0; /* not fined end to mid case */
        !           226:        }
        !           227: }
        !           228:
        !           229: void PChsgnI(arg, rp)
        !           230: NODE arg;
        !           231: IMAT *rp;
        !           232: {
        !           233:        /* index type matrix all entry sgn cheng for parser */
        !           234:        VL vl;
        !           235:        IMAT m, n;
        !           236:
        !           237:        asir_assert(ARG0(arg),O_IMAT,"chsgnind");
        !           238:        vl = CO;
        !           239:        m = (IMAT)ARG0(arg);
        !           240:        ChsgnI(m, &n);
        !           241:        *rp = n;
        !           242: }
        !           243:
        !           244: void ChsgnI(a, c)
        !           245: IMAT a;
        !           246: IMAT *c;
        !           247: {
        !           248:        /* index type matrix all entry sgn chg */
        !           249:        IMAT b;
        !           250:        IMATC ac;
        !           251:        IENT aent;
        !           252:        Obj r;
        !           253:        int ai;
        !           254:
        !           255:        if( ! a->root ){
        !           256:                /* zero matrix case */
        !           257:                *c = a;
        !           258:        } else {
        !           259:                NEWIMAT(b);
        !           260:                b->col = a->col;
        !           261:                b->row = a->row;
        !           262:                ai = -1;
        !           263:                ac = (pointer)a->root;
        !           264:                GetNextIent(&ac, &aent, &ai);
        !           265:                while(aent.cr != -1){
        !           266:                        arf_chsgn((Obj)aent.body, (Obj *)&r);
        !           267:                        AppendIent(b, aent.row, aent.col, r);
        !           268:                        GetNextIent(&ac, &aent, &ai);
        !           269:                }
        !           270:                *c = b;
        !           271:        }
        !           272: }
        !           273:
        !           274: void Pm2Im(arg, rp)
        !           275: NODE arg;
        !           276: IMAT *rp;
        !           277: {
        !           278:        /* matrix type convert from MAT to IMAT */
        !           279:        int i,j, row, col;
        !           280:        MAT m;
        !           281:        IMAT Im;
        !           282:        pointer *a;
        !           283:
        !           284:        m = (MAT)ARG0(arg);
        !           285:        row = m->row;
        !           286:        col = m->col;
        !           287:        NEWIMAT(Im);
        !           288:        Im->col = m->col;
        !           289:        Im->row = m->row;
        !           290:        for (i = 0; i < row; i++)
        !           291:                for (j = 0, a = BDY(m)[i]; j < col; j++)
        !           292:                        if (a[j]) AppendIent(Im, i, j, a[j]);
        !           293:        *rp = Im;
        !           294: }
        !           295:
        !           296: void PIm2m(arg, rp)
        !           297: NODE arg;
        !           298: MAT *rp;
        !           299: {
        !           300:        /* matrix type convert from IMAT to MAT */
        !           301:        IMAT Im;
        !           302:        MAT m;
        !           303:        int c, i, j;
        !           304:        IMATC Imc;
        !           305:        IENT ent;
        !           306:
        !           307:        Im = (IMAT)ARG0(arg);
        !           308:        MKMAT(m,Im->row,Im->col);
        !           309:        if ( Im->root ) {
        !           310:                /* non zero matrix case */
        !           311:                Imc = (pointer)Im->root;
        !           312:                c = -1;
        !           313:                GetNextIent(&Imc, &ent, &c);
        !           314:                while (ent.cr != -1) {
        !           315:                        BDY(m)[ent.row][ent.col] = ent.body;
        !           316:                        GetNextIent(&Imc, &ent, &c);
        !           317:                }
        !           318:        }
        !           319:        *rp = m;
        !           320: }
        !           321:
        !           322: void AddMatI(vl, a, b, c)
        !           323: VL vl;
        !           324: IMAT a, b, *c;
        !           325: {
        !           326:        /* add index type matrix */
        !           327:        int ai, bi;
        !           328:        IMAT m;
        !           329:        IMATC ac, bc;
        !           330:        IENT aent, bent;
        !           331:        Obj pc;
        !           332:
        !           333:        if ( a->col != b->col ) {
        !           334:                error("addmati : colum size mismatch");
        !           335:                *c = 0;
        !           336:        } else if ( a->row != b->row ) {
        !           337:                error("addmati : row size mismatch");
        !           338:                *c = 0;
        !           339:        } else if ( ! a->root ) {
        !           340:                *c = b; /* a : zero matrox */
        !           341:        } else if ( ! b->root ) {
        !           342:                *c = a; /* b : zero matrix */
        !           343:        } else {
        !           344:                NEWIMAT(m);
        !           345:                m->col = a->col;
        !           346:                m->row = a->row;
        !           347:                ai = -1;
        !           348:                ac = (pointer)a->root;
        !           349:                bi = -1;
        !           350:                bc = (pointer)b->root;
        !           351:                GetNextIent(&ac, &aent, &ai);
        !           352:                GetNextIent(&bc, &bent, &bi);
        !           353:                while( aent.cr != -1 ) {
        !           354:                        if( aent.cr == bent.cr ) {
        !           355:                                arf_add(vl, (Obj)aent.body, (Obj)bent.body, (Obj *)&pc);
        !           356:                                AppendIent( m, aent.row, aent.col, pc);
        !           357:                                GetNextIent( &ac, &aent, &ai );
        !           358:                                GetNextIent( &bc, &bent, &bi );
        !           359:                        } else if ( aent.cr < bent.cr ) {
        !           360:                                AppendIent( m, aent.row, aent.col, (Obj)aent.body);
        !           361:                                GetNextIent( &ac, &aent, &ai);
        !           362:                        } else if ( bent.cr == -1 ) {
        !           363:                                AppendIent( m, aent.row, aent.col, (Obj)aent.body);
        !           364:                                GetNextIent( &ac, &aent, &ai);
        !           365:                        } else {
        !           366:                                AppendIent( m, bent.row, bent.col, (Obj)bent.body);
        !           367:                                GetNextIent( &bc, &bent, &bi);
        !           368:                                if ( bent.cr == -1 ){
        !           369:                                        while(aent.cr != -1){
        !           370:                                                AppendIent(m, aent.row, aent.col, (Obj)aent.body);
        !           371:                                                GetNextIent( &ac, &aent, &ai );
        !           372:                                        }
        !           373:                                        break;
        !           374:                                }
        !           375:                        }
        !           376:                }
        !           377:                while(bent.cr != -1) {
        !           378:                        AppendIent( m, bent.row, bent.col, (Obj)bent.body);
        !           379:                        GetNextIent( &bc, &bent, &bi );
        !           380:                }
        !           381:                *c = m;
        !           382:        }
        !           383:        return;
        !           384: }
        !           385:
        !           386: void SubMatI(vl, a, b, c)
        !           387: VL vl;
        !           388: IMAT a, b, *c;
        !           389: {
        !           390:        /* subtract index type matrix */
        !           391:        int ai, bi;
        !           392:        IMAT m;
        !           393:        IMATC ac, bc;
        !           394:        IENT aent, bent;
        !           395:        Obj obj;
        !           396:
        !           397:        if ( a->col != b->col ) {
        !           398:                error("submati : colum size mismatch");
        !           399:                *c = 0;
        !           400:        } else if ( a->row != b->row ) {
        !           401:                error("submati : row size mismatch");
        !           402:                *c = 0;
        !           403:        } else if ( ! b->root ) {
        !           404:                *c = a;
        !           405:        } else if ( ! a->root ) {
        !           406:                ChsgnI(b, &m);
        !           407:                *c = m;
        !           408:        } else {
        !           409:                vl = CO;
        !           410:                NEWIMAT(m);
        !           411:                m->col = a->col;
        !           412:                m->row = a->row;
        !           413:                ai = -1;
        !           414:                ac = (pointer)a->root;
        !           415:                bi = -1;
        !           416:                bc = (pointer)b->root;
        !           417:
        !           418:                GetNextIent(&ac, &aent, &ai);
        !           419:                GetNextIent(&bc, &bent, &bi);
        !           420:                while(aent.cr != -1) {
        !           421:                        if( aent.cr == bent.cr ) {
        !           422:                                arf_sub(vl, (Obj)aent.body, (Obj)bent.body, (Obj *)&obj);
        !           423:                                AppendIent(m, aent.row, aent.col, obj);
        !           424:                                GetNextIent(&ac, &aent, &ai);
        !           425:                                GetNextIent(&bc, &bent, &bi);
        !           426:                        } else if ( aent.cr < bent.cr ) {
        !           427:                                AppendIent( m, aent.row, aent.col, (Obj)aent.body);
        !           428:                                GetNextIent(&ac, &aent, &ai);
        !           429:                        } else if ( bent.cr == -1 ) {
        !           430:                                AppendIent( m, aent.row, aent.col, (Obj)aent.body);
        !           431:                                GetNextIent(&ac, &aent, &ai);
        !           432:                        } else {
        !           433:                                arf_chsgn((Obj)bent.body, (Obj *)&obj);
        !           434:                                AppendIent( m, bent.row, bent.col, (Obj)obj);
        !           435:                                GetNextIent(&bc, &bent, &bi);
        !           436:                                if (bent.cr == -1){
        !           437:                                        while(aent.cr != -1){
        !           438:                                                AppendIent(m, aent.row, aent.col, (Obj)aent.body);
        !           439:                                                GetNextIent(&ac, &aent, &ai);
        !           440:                                        }
        !           441:                                        break;
        !           442:                                }
        !           443:                        }
        !           444:                }
        !           445:                while(bent.cr != -1) {
        !           446:                        arf_chsgn((Obj)bent.body, (Obj *)&obj);
        !           447:                        AppendIent( m, bent.row, bent.col, (Obj)obj);
        !           448:                        GetNextIent(&bc, &bent, &bi);
        !           449:                }
        !           450:                *c = m;
        !           451:        }
        !           452: }
        !           453:
        !           454: void MulrMatI(vl, a, b, rp)
        !           455: VL vl;
        !           456: Obj a, b, *rp;
        !           457: {
        !           458:        /* multiply a expression and a index type matrix */
        !           459:        IMAT m;
        !           460:        IENT ent;
        !           461:        IMATC Im;
        !           462:        Obj p;
        !           463:        int ia;
        !           464:
        !           465:        NEWIMAT(m);
        !           466:        m->col = ((IMAT)b)->col;
        !           467:        m->row = ((IMAT)b)->row;
        !           468:        Im = (IMATC)(((IMAT)b)->root);
        !           469:        ia = -1;
        !           470:        GetNextIent(&Im, &ent, &ia);
        !           471:        while(ent.cr != -1) {
        !           472:                arf_mul(vl, (Obj)a, (Obj)ent.body, (Obj *)&p);
        !           473:                AppendIent(m, ent.row, ent.col, (Obj)p);
        !           474:                GetNextIent(&Im, &ent, &ia);
        !           475:        }
        !           476:        *rp = (Obj)m;
        !           477: }
        !           478:
        !           479: void MulMatG(vl, a, b, c)
        !           480: VL vl;
        !           481: Obj a, b, *c;
        !           482: {
        !           483:        /* multiply index type matrix general procedure */
        !           484:        IMAT m;
        !           485:
        !           486:        if ( !a ) {
        !           487:                NEWIMAT(m);
        !           488:                m->col = ((IMAT)b)->col;
        !           489:                m->row = ((IMAT)b)->row;
        !           490:                *c = (Obj)m;
        !           491:        } else if ( !b ) {
        !           492:                NEWIMAT(m);
        !           493:                m->col = ((IMAT)a)->col;
        !           494:                m->row = ((IMAT)a)->row;
        !           495:                *c = (Obj)m;
        !           496:        } else if ( OID(a) <= O_R ) MulrMatI(vl, (Obj)a, (Obj)b, (Obj *)c);
        !           497:        else if ( OID(b) <= O_R ) MulrMatI(vl, (Obj)b, (Obj)a, (Obj *)c);
        !           498:        else MulMatS(vl, (IMAT)a, (IMAT)b, (IMAT *)c);
        !           499: }
        !           500:
        !           501: void MulMatS(vl, m,n,rp)
        !           502: VL vl;
        !           503: IMAT m, n, *rp;
        !           504: {
        !           505:        /* multiply index type matrix and index type matrix */
        !           506:        IMAT r, a11, a12, a21, a22, b11, b12, b21, b22;
        !           507:        IMAT ans1, ans2, c11, c12, c21, c22, s1, s2, t1, t2, u1, v1, w1;
        !           508:        pointer u, v, *ab;
        !           509:        int hmcol, hmrow, hncol, hnrow;
        !           510:        IENT ent, entn, entm;
        !           511:        IMATC in,im;
        !           512:        int *c, ai, bi, cr, row, col, ca11,ca12,ca21,ca22;
        !           513:        if ( m->col != n->row ) {
        !           514:                *rp =0; error("mulmati : size mismatch");
        !           515:        }
        !           516:        vl = CO;
        !           517:        NEWIMAT(r);
        !           518:        r->row = m->row;
        !           519:        r->col = n->col;
        !           520:        if( m->clen == 0 || n->clen == 0){
        !           521:        /* zero matrix case */
        !           522:                *rp = (pointer)r;
        !           523:                return;
        !           524:        } else if(StrassenSize == 0) {
        !           525:        /* not use Strassen algorithm */
        !           526:                MulMatI(vl, m, n, &r);
        !           527:                *rp = (pointer)r;
        !           528:                return;
        !           529: #if 0
        !           530:        } else if(m->row == 1){
        !           531:                ab = (pointer)MALLOC((n->col +1)*sizeof(Obj));
        !           532:                ai = -1;
        !           533:                im = (pointer)m->root;
        !           534:                GetNextIent(&im, &entm, &ai);
        !           535:                bi = -1;
        !           536:                in = (pointer)n->root;
        !           537:                GetNextIent(&in, &entn, &bi);
        !           538:                while( entn.cr != -1 ){
        !           539:                        if( entn.row == entm.col ){
        !           540:                                arf_mul(vl,(Obj)entm.body,(Obj)entm.body,(Obj *)&u);
        !           541:                                arf_add(vl,(Obj)u,(Obj)ab[entn.col],(Obj *)&v);
        !           542:                                ab[entn.col] = (pointer)v;
        !           543:                                GetNextIent(&in, &entn, &bi);
        !           544:                        } else if( entn.row < entm.col ) {
        !           545:                                GetNextIent(&in, &entn, &bi);
        !           546:                        } else {
        !           547:                                GetNextIent(&im, &entm, &ai);
        !           548:                        }
        !           549:                }
        !           550:                for(ai=0; ai< m->col; ai++){
        !           551:                        if(ab[ai] != 0) AppendIent(r, 1, ai, (Obj)&ab[ai]);
        !           552:                }
        !           553:                *rp=r;
        !           554:                return;
        !           555:        } else if(n->col == 1){
        !           556:        /* not yet */
        !           557:                *rp=0;
        !           558:                return;
        !           559:        } else if(m->col == 1){
        !           560:                ai = -1;
        !           561:                im = (pointer)m->root;
        !           562:                GetNextIent(&im, &entm, &ai);
        !           563:                while( entm.cr != -1 ){
        !           564:                        bi = -1;
        !           565:                        in = (pointer)n->root;
        !           566:                        GetNextIent(&in, &entn, &bi);
        !           567:                        while( entn.cr != -1 ){
        !           568:                                arf_mul(vl,(Obj)entm.body,(Obj)entn.body,(Obj *)&u);
        !           569:                                AppendIent(r, entm.row, entn.col, (Obj)&u);
        !           570:                                GetNextIent(&in, &entn, &bi);
        !           571:                        }
        !           572:                        GetNextIent(&im, &entm, &ai);
        !           573:                }
        !           574:                *rp = r;
        !           575:                return;
        !           576: #endif
        !           577:        } else if((m->row<=StrassenSize)||(m->col<=StrassenSize)|| (n->col<=StrassenSize)) {
        !           578:        /* not use Strassen algorithm */
        !           579:                MulMatI(vl, m, n, &r);
        !           580:                *rp = (pointer)r;
        !           581:                return;
        !           582:        }
        !           583:        /* Strassen Algorithm */
        !           584:        /* calcrate matrix half size */
        !           585:        hmrow = (m->row + (m->row & 1)) >> 1;
        !           586:        hmcol = (m->col + (m->col & 1)) >> 1;
        !           587:        hnrow = (n->row + (n->row & 1)) >> 1;
        !           588:        hncol = (n->col + (n->col & 1)) >> 1;
        !           589:        NEWIMAT(a11); a11->col = hmcol; a11->row = hmrow;
        !           590:        NEWIMAT(a12); a12->col = hmcol; a12->row = hmrow;
        !           591:        NEWIMAT(a21); a21->col = hmcol; a21->row = hmrow;
        !           592:        NEWIMAT(a22); a22->col = hmcol; a22->row = hmrow;
        !           593:        NEWIMAT(b11); b11->col = hncol; b11->row = hnrow;
        !           594:        NEWIMAT(b12); b12->col = hncol; b12->row = hnrow;
        !           595:        NEWIMAT(b21); b21->col = hncol; b21->row = hnrow;
        !           596:        NEWIMAT(b22); b22->col = hncol; b22->row = hnrow;
        !           597:
        !           598:        /* copy matrix n to 4 small matrix a11,a12,a21,a22 */
        !           599:        im = (pointer)m->root;
        !           600:        ai = -1;
        !           601:        GetNextIent(&im, &ent, &ai);
        !           602:        while( ent.cr != -1 ){
        !           603:                if(ent.col < hmcol){
        !           604:                        if(ent.row < hmrow){
        !           605:                                AppendIent(a11,ent.row,ent.col,(Obj)ent.body);
        !           606:                        } else {
        !           607:                                AppendIent(a21,ent.row-hmrow,ent.col,(Obj)ent.body);
        !           608:                        }
        !           609:                } else {
        !           610:                        if(ent.row < hmrow){
        !           611:                                AppendIent(a12,ent.row,ent.col-hmcol,(Obj)ent.body);
        !           612:                        } else {
        !           613:                                AppendIent(a22,ent.row-hmrow,ent.col-hmcol,(Obj)ent.body);
        !           614:                        }
        !           615:                }
        !           616:                GetNextIent(&im, &ent, &ai);
        !           617:        }
        !           618:        /* copy matrix m to 4 small matrix b11,b12,b21,b22 */
        !           619:        im = (pointer)n->root;
        !           620:        ai = -1;
        !           621:        GetNextIent(&im, &ent, &ai);
        !           622:        while( ent.cr != -1 ){
        !           623:                if(ent.col < hmcol){
        !           624:                        if(ent.row < hnrow){
        !           625:                                AppendIent(b11,ent.row,ent.col,(Obj)ent.body);
        !           626:                        } else {
        !           627:                                AppendIent(b21,ent.row-hnrow,ent.col,(Obj)ent.body);
        !           628:                        }
        !           629:                } else {
        !           630:                        if(ent.row < hnrow){
        !           631:                                AppendIent(b12,ent.row,ent.col-hncol,(Obj)ent.body);
        !           632:                        } else {
        !           633:                                AppendIent(b22,ent.row-hnrow,ent.col-hncol,(Obj)ent.body);
        !           634:                        }
        !           635:                }
        !           636:                GetNextIent(&im, &ent, &ai);
        !           637:        }
        !           638:        /* expand matrix by Strassen-Winograd algorithm */
        !           639:        /* s1 = A21 + A22 */
        !           640:        AddMatI(vl,a21,a22, &s1);
        !           641:
        !           642:        /* s2=s1-A11 */
        !           643:        SubMatI(vl,s1,a11,&s2);
        !           644:
        !           645:        /* t1=B12-B11 */
        !           646:        SubMatI(vl,b12,b11,&t1);
        !           647:
        !           648:        /* t2=B22-t1 */
        !           649:        SubMatI(vl,b22,t1,&t2);
        !           650:
        !           651:        /* u=(A11-A21)*(B22-B12) */
        !           652:        SubMatI(vl,a11,a21,&ans1);
        !           653:        SubMatI(vl,b22,b12,&ans2);
        !           654:        MulMatS(vl, ans1,ans2,&u1);
        !           655:
        !           656:        /* v=s1*t1 */
        !           657:        MulMatS(vl, s1,t1,&v1);
        !           658:
        !           659:        /* w=A11*B11+s2*t2 */
        !           660:        MulMatS(vl, a11,b11,&ans1);
        !           661:        MulMatS(vl, s2,t2,&ans2);
        !           662:        AddMatI(vl,ans1,ans2,&w1);
        !           663:
        !           664:        /* C11 = A11*B11+A12*B21 */
        !           665:        MulMatS(vl, a12,b21,&ans2);
        !           666:        AddMatI(vl,ans1,ans2,&c11);
        !           667:
        !           668:        /* C12 = w1+v1+(A12-s2)*B22 */
        !           669:        SubMatI(vl,a12,s2,&ans1);
        !           670:        MulMatS(vl, ans1, b22, &ans2);
        !           671:        AddMatI(vl, w1, v1, &ans1);
        !           672:        AddMatI(vl, ans1, ans2, &c12);
        !           673:
        !           674:        /* C21 = w1+u1+A22*(B21-t2) */
        !           675:        SubMatI(vl, b21, t2, &ans1);
        !           676:        MulMatS(vl, a22, ans1, &ans2);
        !           677:        AddMatI(vl, w1, u1, &ans1);
        !           678:        AddMatI(vl, ans1, ans2, &c21);
        !           679:
        !           680:        /* C22 = w1 + u1 + v1 */
        !           681:        AddMatI(vl, ans1, v1, &c22);
        !           682:
        !           683:        /* create return i matrix */
        !           684:        r->col = m->col;
        !           685:        r->row = n->row;
        !           686:
        !           687:        /* copy c11 to r */
        !           688:        ca11 = -1;
        !           689:        if( c11->root ){
        !           690:                im = (pointer)c11->root;
        !           691:                ai = -1;
        !           692:                GetNextIent(&im, &ent, &ai);
        !           693:                while( ai != -1 ){
        !           694:                        AppendIent(r,ent.row,ent.col,(Obj)ent.body);
        !           695:                        GetNextIent(&im, &ent, &ai);
        !           696:                }
        !           697:        }
        !           698:        /* copy c21 to r */
        !           699:        if( c21->root ){
        !           700:                im = (pointer)c21->root;
        !           701:                ai = -1;
        !           702:                GetNextIent(&im, &ent, &ai);
        !           703:                while( ent.cr != -1 ){
        !           704:                        PutIent(r, ent.row + hmrow, ent.col, (Obj)ent.body);
        !           705:                        GetNextIent(&im, &ent, &ai);
        !           706:                }
        !           707:        }
        !           708:        /* copy c12 to r */
        !           709:        if( c12->root ){
        !           710:                im = (pointer)c12->root;
        !           711:                ai = -1;
        !           712:                GetNextIent(&im, &ent, &ai);
        !           713:                while( ent.cr != -1 ){
        !           714:                        PutIent(r, ent.row, ent.col + hncol, (Obj)ent.body);
        !           715:                        GetNextIent(&im, &ent, &ai);
        !           716:                }
        !           717:        }
        !           718:        /* copy c22 to r */
        !           719:        if( c22->root ){
        !           720:                im = (pointer)c22->root;
        !           721:                ai = -1;
        !           722:                GetNextIent(&im, &ent, &ai);
        !           723:                while( ent.cr != -1 ){
        !           724:                        PutIent(r, ent.row + hmrow, ent.col + hncol, (Obj)ent.body);
        !           725:                        GetNextIent(&im, &ent, &ai);
        !           726:                }
        !           727:        }
        !           728:        *rp = (pointer)r;
        !           729:        return;
        !           730: }
        !           731:
        !           732: void MulMatI(vl,m,n,r)
        !           733: VL vl;
        !           734: IMAT m, n, *r;
        !           735: {
        !           736:        /* inner prodocut algorithm for index type multiply procedure */
        !           737:        IMAT l;
        !           738:        IMATC im, imt;
        !           739:        IENT ent, tent;
        !           740:        int bc, bend, ac, aend;
        !           741:        int col, row, tcol, trow;
        !           742:        int i, j, k, ai, bi;
        !           743:        int bj, ik,kj;
        !           744:        pointer s, u, v;
        !           745:
        !           746:        typedef struct oIND {
        !           747:                int row, col;
        !           748:                pointer body;
        !           749:        } *IND;
        !           750:        IND a,b;
        !           751:        /* make trans(n) */
        !           752:        a = (IND)MALLOC(IMATCH * m->clen *sizeof(struct oIND)+1);
        !           753:        b = (IND)MALLOC(IMATCH * n->clen *sizeof(struct oIND)+1);
        !           754:
        !           755:        bend = -1;
        !           756:        row = n->row;
        !           757:        col = n->col;
        !           758:        bc = -1;
        !           759:        im = (pointer)n->root;
        !           760:        GetNextIent(&im, &ent, &bc);
        !           761:        b[++bend].body = ent.body;
        !           762:        b[bend].row = ent.col;
        !           763:        b[bend].col = ent.row;
        !           764:        GetNextIent(&im, &ent, &bc);
        !           765:        while ( ent.cr != -1 ) {
        !           766:                trow = ent.col;
        !           767:                tcol = ent.row;
        !           768:                for( i = bend; i >= 0; i--) {
        !           769:                        if( b[i].row > trow ) {
        !           770:                                b[i + 1] = b[i];
        !           771:                        } else if ( b[i].col > tcol ) {
        !           772:                                b[i + 1] = b[i];
        !           773:                        } else {
        !           774:                                b[i+1].col = tcol;
        !           775:                                b[i+1].row = trow;
        !           776:                                b[i+1].body = ent.body;
        !           777:                                break;
        !           778:                        }
        !           779:                }
        !           780:                if ( i == -1 ) {
        !           781:                        b[0].col = tcol;
        !           782:                        b[0].row = trow;
        !           783:                        b[0].body = ent.body;
        !           784:                }
        !           785:                bend++;
        !           786:                GetNextIent(&im, &ent, &bc);
        !           787:        }
        !           788:
        !           789:        im = (pointer)m->root;
        !           790:        ac = -1;
        !           791:        GetNextIent(&im, &ent, &ac);
        !           792:        aend = -1;
        !           793:        while( ent.cr != -1 ){
        !           794:                a[++aend].col = ent.col;
        !           795:                a[aend].row = ent.row;
        !           796:                a[aend].body = ent.body;
        !           797:                GetNextIent(&im, &ent, &ac);
        !           798:        }
        !           799:        /* make return matrix */
        !           800:        NEWIMAT(l);
        !           801:        l->row = m->row;
        !           802:        l->col = n->col;
        !           803:        ac = -1;
        !           804:        for( i = 0; i<= aend;) {
        !           805:                ai = a[i].row;
        !           806:                bj = b[0].row;
        !           807:                s = 0;
        !           808:                ik=i;
        !           809:                for(j=0; j<= bend;){
        !           810:                        if( a[ik].col == b[j].col) {
        !           811:                                arf_mul(CO,(Obj)a[ik].body, (Obj)b[j].body, (Obj *)&u);
        !           812:                                arf_add(CO,(Obj)s,(Obj)u,(Obj *)&v);
        !           813:                                s = v;
        !           814:                                j++;
        !           815:                                if ( bj != b[j].row ) {
        !           816:                                        AppendIent(l, ai, bj, (Obj)s);
        !           817:                                        ik = i;
        !           818:                                        bj = b[j].row;
        !           819:                                        s = 0;
        !           820:                                } else {
        !           821:                                        ik++;
        !           822:                                        if ( ai != a[ik].row ) {
        !           823:                                                AppendIent(l, ai, bj, (Obj)s);
        !           824:                                                s = 0;
        !           825:                                                while ( bj == b[j].row ) {
        !           826:                                                        j++;
        !           827:                                                        if ( j > bend ) break;
        !           828:                                                }
        !           829:                                                ik = i;
        !           830:                                                bj = b[j].row;
        !           831:                                        }
        !           832:                                }
        !           833:                        } else if ( a[ik].col > b[j].col ) {
        !           834:                                j++;
        !           835:                                if ( bj != b[j].row ) {
        !           836:                                        AppendIent(l, ai, bj, (Obj)s);
        !           837:                                        s = 0;
        !           838:                                        ik = i;
        !           839:                                        bj = b[j].row;
        !           840:                                }
        !           841:                        } else /* if ( a[ik].col < b[j].col ) */ {
        !           842:                                ik++;
        !           843:                                if ( ai != a[ik].row ) {
        !           844:                                        AppendIent(l, ai, bj, (Obj)s);
        !           845:                                        s = 0;
        !           846:                                        while ( bj == b[j].row ) {
        !           847:                                                j++;
        !           848:                                                if ( j > bend ) break;
        !           849:                                        }
        !           850:                                        bj = b[j].row;
        !           851:                                        ik = i;
        !           852:                                }
        !           853:                        }
        !           854:                }
        !           855:                i = ik;
        !           856:                while ( ai == a[i].row ) {
        !           857:                        i++;
        !           858:                        if( i > aend) break;
        !           859:                }
        !           860:        }
        !           861:        *r = (IMAT)l;
        !           862:        FREE(a);
        !           863:        FREE(b);
        !           864:        return;
        !           865: }

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