Annotation of OpenXM_contrib2/asir2018/builtin/iarray.c, Revision 1.1
1.1 ! noro 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->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");
! 188: row = QTOS((Q)ARG0(arg)); col = QTOS((Q)ARG1(arg));
! 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>