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>