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

Annotation of OpenXM_contrib2/asir2018/builtin/iarray.c, Revision 1.2

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

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