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

Diff for /OpenXM_contrib2/asir2000/builtin/iarray.c between version 1.2 and 1.3

version 1.2, 2005/01/17 07:43:24 version 1.3, 2018/03/29 01:32:50
Line 1 
Line 1 
 /*  /*
  * $OpenXM: OpenXM_contrib2/asir2000/builtin/iarray.c,v 1.1 2004/12/18 16:50:10 saito Exp $   * $OpenXM: OpenXM_contrib2/asir2000/builtin/iarray.c,v 1.2 2005/01/17 07:43:24 saito Exp $
 */  */
 #include "ca.h"  #include "ca.h"
 #include "base.h"  #include "base.h"
Line 9 
Line 9 
 extern int StrassenSize;  extern int StrassenSize;
   
 struct ftab imat_tab[] = {  struct ftab imat_tab[] = {
         {"newimat", Pnewimat,2},    {"newimat", Pnewimat,2},
         {"m2im",  Pm2Im,1},    {"m2im",  Pm2Im,1},
         {"im2m",  PIm2m,1},    {"im2m",  PIm2m,1},
         {0,0,0},    {0,0,0},
 };  };
   
 const IENT zent = { -1, -1, -1, 0}; /* last ient const */  const IENT zent = { -1, -1, -1, 0}; /* last ient const */
Line 22  int cr, row, col;
Line 22  int cr, row, col;
 Obj trg;  Obj trg;
 IENT *ent;  IENT *ent;
 {  {
         /* make Index Entry IENT */    /* make Index Entry IENT */
         /* set:cr, row, trag */    /* set:cr, row, trag */
         /* return: value ent */    /* return: value ent */
         /* MEnt(cr, row, col, trg, &ent); */    /* MEnt(cr, row, col, trg, &ent); */
   
         ent->cr = cr;    ent->cr = cr;
         ent->row = row;    ent->row = row;
         ent->col = col;    ent->col = col;
         ent->body = (pointer)trg;    ent->body = (pointer)trg;
 }  }
   
 void GetNextIent(Im, ent, c)  void GetNextIent(Im, ent, c)
Line 38  IMATC *Im;
Line 38  IMATC *Im;
 IENT *ent;  IENT *ent;
 int *c;  int *c;
 {  {
         /* get next IENT */    /* get next IENT */
         /* set: Im, c */    /* set: Im, c */
         /* return: ent, c */    /* return: ent, c */
         /* GetNextIent(&Im, &ent, &c); */    /* GetNextIent(&Im, &ent, &c); */
   
         if( (++*c) >= IMATCH ){    if( (++*c) >= IMATCH ){
                 if ( ! (IMATC)(*Im)->next ) {      if ( ! (IMATC)(*Im)->next ) {
                 /* no more IENT */      /* no more IENT */
                         *c = -1;        *c = -1;
                         return;        return;
                 }      }
                 *Im = (IMATC)(*Im)->next;      *Im = (IMATC)(*Im)->next;
                 *c = 0;      *c = 0;
         }    }
         *ent = (*Im)->ient[*c];    *ent = (*Im)->ient[*c];
 }  }
   
 void GetForeIent(Im, ent, c)  void GetForeIent(Im, ent, c)
Line 60  IMATC *Im;
Line 60  IMATC *Im;
 IENT *ent;  IENT *ent;
 int *c;  int *c;
 {  {
         /* GetForeIent(&Im, &ent, &c); */    /* GetForeIent(&Im, &ent, &c); */
   
         /* find last IENT */    /* find last IENT */
         if( (--*c) < 0 ){    if( (--*c) < 0 ){
                 if ( !(IMATC)(*Im)->fore ){      if ( !(IMATC)(*Im)->fore ){
                 /* no more IENT */      /* no more IENT */
                         *c = -1;        *c = -1;
                         return;        return;
                 }      }
                 /* next IENT block */      /* next IENT block */
                 *Im = (IMATC)(*Im)->fore;      *Im = (IMATC)(*Im)->fore;
                 *c = IMATCH - 1;      *c = IMATCH - 1;
         }    }
         *ent = (*Im)->ient[*c];    *ent = (*Im)->ient[*c];
 }  }
   
 void AppendIent(m, row, col, body)  void AppendIent(m, row, col, body)
Line 81  IMAT m;
Line 81  IMAT m;
 int row, col;  int row, col;
 Obj body;  Obj body;
 {  {
         /* append row, col, body to matrix m */    /* append row, col, body to matrix m */
         IMATC Im, Imt;    IMATC Im, Imt;
         int d;    int d;
   
         if ( ! body ) return;    if ( ! body ) return;
         if ( ! m->clen ) {    if ( ! m->clen ) {
                 NEWIENT(Im);      NEWIENT(Im);
                 m->root = (pointer)Im;      m->root = (pointer)Im;
                 m->toor = (pointer)Im;      m->toor = (pointer)Im;
                 m->clen = 1;      m->clen = 1;
                 MEnt(row * m->col + col, row, col, body, &Im->ient[0]);      MEnt(row * m->col + col, row, col, body, &Im->ient[0]);
                 Im->ient[1] = zent;      Im->ient[1] = zent;
         } else {    } else {
                 Im = (pointer)m->toor;      Im = (pointer)m->toor;
                 for( d = 0; Im->ient[d].cr != -1; d++);      for( d = 0; Im->ient[d].cr != -1; d++);
                 if ( d == IMATCH - 1 ) {      if ( d == IMATCH - 1 ) {
                         /* append point is chank end */        /* append point is chank end */
                         NEWIENT(Imt);        NEWIENT(Imt);
                         Im->next = (pointer)Imt;        Im->next = (pointer)Imt;
                         m->toor = (pointer)Imt;        m->toor = (pointer)Imt;
                         ++(m->clen);        ++(m->clen);
                         Imt->fore = (pointer)Im;        Imt->fore = (pointer)Im;
                         Imt->next = 0;        Imt->next = 0;
                         MEnt(row *  m->col + col, row, col, body, &Im->ient[d]);        MEnt(row *  m->col + col, row, col, body, &Im->ient[d]);
                         Imt->ient[0] = zent;        Imt->ient[0] = zent;
                 } else {      } else {
                         MEnt(row * m->col + col, row, col, body, &Im->ient[d]);        MEnt(row * m->col + col, row, col, body, &Im->ient[d]);
                         Im->ient[d + 1] = zent;        Im->ient[d + 1] = zent;
                 }      }
         }    }
 }  }
   
 void PutIent(m, row, col, trg)  void PutIent(m, row, col, trg)
Line 118  IMAT m;
Line 118  IMAT m;
 int row, col;  int row, col;
 Obj trg;  Obj trg;
 {  {
         /* insert or replace IENT */    /* insert or replace IENT */
         IMATC Im, Imn;    IMATC Im, Imn;
         IENT ent, tent;    IENT ent, tent;
         int cr, c, d;    int cr, c, d;
   
         if ( m->row <= row || m->col <= col || row < 0 || col < 0 )    if ( m->row <= row || m->col <= col || row < 0 || col < 0 )
                 error("putim : Out of rage");      error("putim : Out of rage");
         cr = row * m->col + col;    cr = row * m->col + col;
 printf("cr = %d\n",cr);  printf("cr = %d\n",cr);
         if ( ! m->clen ) {    if ( ! m->clen ) {
                 if( trg == 0 ) return;      if( trg == 0 ) return;
                 AppendIent(m, row, col, trg);      AppendIent(m, row, col, trg);
                 return;      return;
         }    }
         MEnt(cr, row, col, trg, &tent);    MEnt(cr, row, col, trg, &tent);
         Im = (pointer)m->root;    Im = (pointer)m->root;
         c = -1;    c = -1;
         GetNextIent(&Im, &ent, &c);    GetNextIent(&Im, &ent, &c);
         while (ent.cr < cr) {    while (ent.cr < cr) {
                 GetNextIent(&Im, &ent, &c);      GetNextIent(&Im, &ent, &c);
                 if( c == -1 ) {      if( c == -1 ) {
                         /* zero insert case */        /* zero insert case */
                         if ( ! trg ) return;        if ( ! trg ) return;
                         /* last append case */        /* last append case */
                         AppendIent(m, row, col, trg);        AppendIent(m, row, col, trg);
                         return;        return;
                 }      }
         }    }
         if ( ent.cr == cr ) {    if ( ent.cr == cr ) {
                 /* same row and col (replace) case */      /* same row and col (replace) case */
                 if ( ! trg ) {      if ( ! trg ) {
                         /* IENT remove case */        /* IENT remove case */
                         Imn = Im;        Imn = Im;
                         while ( c != -1 ) {        while ( c != -1 ) {
                                 GetNextIent( &Im, &ent, &c );          GetNextIent( &Im, &ent, &c );
                                 if ( ! c ) {          if ( ! c ) {
                                         Imn->ient[IMATCH-1] = ent;            Imn->ient[IMATCH-1] = ent;
                                         Imn = Im;            Imn = Im;
                                 } else {          } else {
                                         Im->ient[c - 1] = ent;            Im->ient[c - 1] = ent;
                                 }          }
                         }        }
                 } else {      } else {
                         /* replase case */        /* replase case */
                         Im->ient[c] = tent;        Im->ient[c] = tent;
                 }      }
         } else {    } else {
                 /* IENT insert case */      /* IENT insert case */
                 while( c != -1 ) {      while( c != -1 ) {
                         Im->ient[c] = tent;        Im->ient[c] = tent;
                         tent = ent;        tent = ent;
                         GetNextIent(&Im, &ent, &c);        GetNextIent(&Im, &ent, &c);
                 }      }
   
         }    }
 }  }
   
 void Pnewimat(arg, rp)  void Pnewimat(arg, rp)
 NODE arg;  NODE arg;
 IMAT *rp;  IMAT *rp;
 {  {
         /* make new index type matrix for parser */    /* make new index type matrix for parser */
         int row,col;    int row,col;
         IMAT m;    IMAT m;
   
         asir_assert(ARG0(arg),O_N,"newimat");    asir_assert(ARG0(arg),O_N,"newimat");
         asir_assert(ARG1(arg),O_N,"newimat");    asir_assert(ARG1(arg),O_N,"newimat");
         row = QTOS((Q)ARG0(arg)); col = QTOS((Q)ARG1(arg));    row = QTOS((Q)ARG0(arg)); col = QTOS((Q)ARG1(arg));
         if ( row <= 0 || col <= 0 ) error("newimat : invalid size");    if ( row <= 0 || col <= 0 ) error("newimat : invalid size");
         NEWIMAT(m);    NEWIMAT(m);
         m->col = col;    m->col = col;
         m->row = row;    m->row = row;
         *rp = m;    *rp = m;
 }  }
   
 void GetIbody(m, row, col, trg)  void GetIbody(m, row, col, trg)
Line 198  IMAT m;
Line 198  IMAT m;
 int col, row;  int col, row;
 Obj *trg;  Obj *trg;
 {  {
         /* get entry body from m for parser */    /* get entry body from m for parser */
         IMATC Im;    IMATC Im;
         IENT ent;    IENT ent;
         int cr;    int cr;
         int c;    int c;
   
         if ( m->row <= row || m->col <= col || row < 0 || col < 0 )    if ( m->row <= row || m->col <= col || row < 0 || col < 0 )
                 error("putim : Out of rage");      error("putim : Out of rage");
         if ( ! m->clen ) {    if ( ! m->clen ) {
         /* zero matrix case */    /* zero matrix case */
                 *trg = (Obj)0;      *trg = (Obj)0;
         } else {    } else {
                 cr = row * m->col + col;      cr = row * m->col + col;
                 c = -1;      c = -1;
                 Im = (pointer)m->root;      Im = (pointer)m->root;
                 GetNextIent( &Im, &ent, &c);      GetNextIent( &Im, &ent, &c);
                 while( ent.cr < cr ) {      while( ent.cr < cr ) {
                         if ( ent.cr == -1 ) {        if ( ent.cr == -1 ) {
                         /* not fined ent to last case */        /* not fined ent to last case */
                                 *trg = (Obj)0;          *trg = (Obj)0;
                                 return;          return;
                         }        }
                         GetNextIent( &Im, &ent, &c);        GetNextIent( &Im, &ent, &c);
                 }      }
                 if ( ent.cr == cr ) *trg = (Obj)ent.body;      if ( ent.cr == cr ) *trg = (Obj)ent.body;
                 else *trg = (Obj)0; /* not fined end to mid case */      else *trg = (Obj)0; /* not fined end to mid case */
         }    }
 }  }
   
 void PChsgnI(arg, rp)  void PChsgnI(arg, rp)
 NODE arg;  NODE arg;
 IMAT *rp;  IMAT *rp;
 {  {
         /* index type matrix all entry sgn cheng for parser */    /* index type matrix all entry sgn cheng for parser */
         VL vl;    VL vl;
         IMAT m, n;    IMAT m, n;
   
         asir_assert(ARG0(arg),O_IMAT,"chsgnind");    asir_assert(ARG0(arg),O_IMAT,"chsgnind");
         vl = CO;    vl = CO;
         m = (IMAT)ARG0(arg);    m = (IMAT)ARG0(arg);
         ChsgnI(m, &n);    ChsgnI(m, &n);
         *rp = n;    *rp = n;
 }  }
   
 void ChsgnI(a, c)  void ChsgnI(a, c)
 IMAT a;  IMAT a;
 IMAT *c;  IMAT *c;
 {  {
         /* index type matrix all entry sgn chg */    /* index type matrix all entry sgn chg */
         IMAT b;    IMAT b;
         IMATC ac;    IMATC ac;
         IENT aent;    IENT aent;
         Obj r;    Obj r;
         int ai;    int ai;
   
         if( ! a->root ){    if( ! a->root ){
                 /* zero matrix case */      /* zero matrix case */
                 *c = a;      *c = a;
         } else {    } else {
                 NEWIMAT(b);      NEWIMAT(b);
                 b->col = a->col;      b->col = a->col;
                 b->row = a->row;      b->row = a->row;
                 ai = -1;      ai = -1;
                 ac = (pointer)a->root;      ac = (pointer)a->root;
                 GetNextIent(&ac, &aent, &ai);      GetNextIent(&ac, &aent, &ai);
                 while(aent.cr != -1){      while(aent.cr != -1){
                         arf_chsgn((Obj)aent.body, (Obj *)&r);        arf_chsgn((Obj)aent.body, (Obj *)&r);
                         AppendIent(b, aent.row, aent.col, r);        AppendIent(b, aent.row, aent.col, r);
                         GetNextIent(&ac, &aent, &ai);        GetNextIent(&ac, &aent, &ai);
                 }      }
                 *c = b;      *c = b;
         }    }
 }  }
   
 void Pm2Im(arg, rp)  void Pm2Im(arg, rp)
 NODE arg;  NODE arg;
 IMAT *rp;  IMAT *rp;
 {  {
         /* matrix type convert from MAT to IMAT */    /* matrix type convert from MAT to IMAT */
         int i,j, row, col;    int i,j, row, col;
         MAT m;    MAT m;
         IMAT Im;    IMAT Im;
         pointer *a;    pointer *a;
   
         m = (MAT)ARG0(arg);    m = (MAT)ARG0(arg);
         row = m->row;    row = m->row;
         col = m->col;    col = m->col;
         NEWIMAT(Im);    NEWIMAT(Im);
         Im->col = m->col;    Im->col = m->col;
         Im->row = m->row;    Im->row = m->row;
         for (i = 0; i < row; i++)    for (i = 0; i < row; i++)
                 for (j = 0, a = BDY(m)[i]; j < col; j++)      for (j = 0, a = BDY(m)[i]; j < col; j++)
                         if (a[j]) AppendIent(Im, i, j, a[j]);        if (a[j]) AppendIent(Im, i, j, a[j]);
         *rp = Im;    *rp = Im;
 }  }
   
 void PIm2m(arg, rp)  void PIm2m(arg, rp)
 NODE arg;  NODE arg;
 MAT *rp;  MAT *rp;
 {  {
         /* matrix type convert from IMAT to MAT */    /* matrix type convert from IMAT to MAT */
         IMAT Im;    IMAT Im;
         MAT m;    MAT m;
         int c, i, j;    int c, i, j;
         IMATC Imc;    IMATC Imc;
         IENT ent;    IENT ent;
   
         Im = (IMAT)ARG0(arg);    Im = (IMAT)ARG0(arg);
         MKMAT(m,Im->row,Im->col);    MKMAT(m,Im->row,Im->col);
         if ( Im->root ) {    if ( Im->root ) {
                 /* non zero matrix case */      /* non zero matrix case */
                 Imc = (pointer)Im->root;      Imc = (pointer)Im->root;
                 c = -1;      c = -1;
                 GetNextIent(&Imc, &ent, &c);      GetNextIent(&Imc, &ent, &c);
                 while (ent.cr != -1) {      while (ent.cr != -1) {
                         BDY(m)[ent.row][ent.col] = ent.body;        BDY(m)[ent.row][ent.col] = ent.body;
                         GetNextIent(&Imc, &ent, &c);        GetNextIent(&Imc, &ent, &c);
                 }      }
         }    }
         *rp = m;    *rp = m;
 }  }
   
 void AddMatI(vl, a, b, c)  void AddMatI(vl, a, b, c)
 VL vl;  VL vl;
 IMAT a, b, *c;  IMAT a, b, *c;
 {  {
         /* add index type matrix */    /* add index type matrix */
         int ai, bi;    int ai, bi;
         IMAT m;    IMAT m;
         IMATC ac, bc;    IMATC ac, bc;
         IENT aent, bent;    IENT aent, bent;
         Obj pc;    Obj pc;
   
         if ( a->col != b->col ) {    if ( a->col != b->col ) {
                 error("addmati : colum size mismatch");      error("addmati : colum size mismatch");
                 *c = 0;      *c = 0;
         } else if ( a->row != b->row ) {    } else if ( a->row != b->row ) {
                 error("addmati : row size mismatch");      error("addmati : row size mismatch");
                 *c = 0;      *c = 0;
         } else if ( ! a->root ) {    } else if ( ! a->root ) {
                 *c = b; /* a : zero matrox */      *c = b; /* a : zero matrox */
         } else if ( ! b->root ) {    } else if ( ! b->root ) {
                 *c = a; /* b : zero matrix */      *c = a; /* b : zero matrix */
         } else {    } else {
                 NEWIMAT(m);      NEWIMAT(m);
                 m->col = a->col;      m->col = a->col;
                 m->row = a->row;      m->row = a->row;
                 ai = -1;      ai = -1;
                 ac = (pointer)a->root;      ac = (pointer)a->root;
                 bi = -1;      bi = -1;
                 bc = (pointer)b->root;      bc = (pointer)b->root;
                 GetNextIent(&ac, &aent, &ai);      GetNextIent(&ac, &aent, &ai);
                 GetNextIent(&bc, &bent, &bi);      GetNextIent(&bc, &bent, &bi);
                 while( aent.cr != -1 ) {      while( aent.cr != -1 ) {
                         if( aent.cr == bent.cr ) {        if( aent.cr == bent.cr ) {
                                 arf_add(vl, (Obj)aent.body, (Obj)bent.body, (Obj *)&pc);          arf_add(vl, (Obj)aent.body, (Obj)bent.body, (Obj *)&pc);
                                 AppendIent( m, aent.row, aent.col, pc);          AppendIent( m, aent.row, aent.col, pc);
                                 GetNextIent( &ac, &aent, &ai );          GetNextIent( &ac, &aent, &ai );
                                 GetNextIent( &bc, &bent, &bi );          GetNextIent( &bc, &bent, &bi );
                         } else if ( aent.cr < bent.cr ) {        } else if ( aent.cr < bent.cr ) {
                                 AppendIent( m, aent.row, aent.col, (Obj)aent.body);          AppendIent( m, aent.row, aent.col, (Obj)aent.body);
                                 GetNextIent( &ac, &aent, &ai);          GetNextIent( &ac, &aent, &ai);
                         } else if ( bent.cr == -1 ) {        } else if ( bent.cr == -1 ) {
                                 AppendIent( m, aent.row, aent.col, (Obj)aent.body);          AppendIent( m, aent.row, aent.col, (Obj)aent.body);
                                 GetNextIent( &ac, &aent, &ai);          GetNextIent( &ac, &aent, &ai);
                         } else {        } else {
                                 AppendIent( m, bent.row, bent.col, (Obj)bent.body);          AppendIent( m, bent.row, bent.col, (Obj)bent.body);
                                 GetNextIent( &bc, &bent, &bi);          GetNextIent( &bc, &bent, &bi);
                                 if ( bent.cr == -1 ){          if ( bent.cr == -1 ){
                                         while(aent.cr != -1){            while(aent.cr != -1){
                                                 AppendIent(m, aent.row, aent.col, (Obj)aent.body);              AppendIent(m, aent.row, aent.col, (Obj)aent.body);
                                                 GetNextIent( &ac, &aent, &ai );              GetNextIent( &ac, &aent, &ai );
                                         }            }
                                         break;            break;
                                 }          }
                         }        }
                 }      }
                 while(bent.cr != -1) {      while(bent.cr != -1) {
                         AppendIent( m, bent.row, bent.col, (Obj)bent.body);        AppendIent( m, bent.row, bent.col, (Obj)bent.body);
                         GetNextIent( &bc, &bent, &bi );        GetNextIent( &bc, &bent, &bi );
                 }      }
                 *c = m;      *c = m;
         }    }
         return;    return;
 }  }
   
 void SubMatI(vl, a, b, c)  void SubMatI(vl, a, b, c)
 VL vl;  VL vl;
 IMAT a, b, *c;  IMAT a, b, *c;
 {  {
         /* subtract index type matrix */    /* subtract index type matrix */
         int ai, bi;    int ai, bi;
         IMAT m;    IMAT m;
         IMATC ac, bc;    IMATC ac, bc;
         IENT aent, bent;    IENT aent, bent;
         Obj obj;    Obj obj;
   
         if ( a->col != b->col ) {    if ( a->col != b->col ) {
                 error("submati : colum size mismatch");      error("submati : colum size mismatch");
                 *c = 0;      *c = 0;
         } else if ( a->row != b->row ) {    } else if ( a->row != b->row ) {
                 error("submati : row size mismatch");      error("submati : row size mismatch");
                 *c = 0;      *c = 0;
         } else if ( ! b->root ) {    } else if ( ! b->root ) {
                 *c = a;      *c = a;
         } else if ( ! a->root ) {    } else if ( ! a->root ) {
                 ChsgnI(b, &m);      ChsgnI(b, &m);
                 *c = m;      *c = m;
         } else {    } else {
                 vl = CO;      vl = CO;
                 NEWIMAT(m);      NEWIMAT(m);
                 m->col = a->col;      m->col = a->col;
                 m->row = a->row;      m->row = a->row;
                 ai = -1;      ai = -1;
                 ac = (pointer)a->root;      ac = (pointer)a->root;
                 bi = -1;      bi = -1;
                 bc = (pointer)b->root;      bc = (pointer)b->root;
   
                 GetNextIent(&ac, &aent, &ai);      GetNextIent(&ac, &aent, &ai);
                 GetNextIent(&bc, &bent, &bi);      GetNextIent(&bc, &bent, &bi);
                 while(aent.cr != -1) {      while(aent.cr != -1) {
                         if( aent.cr == bent.cr ) {        if( aent.cr == bent.cr ) {
                                 arf_sub(vl, (Obj)aent.body, (Obj)bent.body, (Obj *)&obj);          arf_sub(vl, (Obj)aent.body, (Obj)bent.body, (Obj *)&obj);
                                 AppendIent(m, aent.row, aent.col, obj);          AppendIent(m, aent.row, aent.col, obj);
                                 GetNextIent(&ac, &aent, &ai);          GetNextIent(&ac, &aent, &ai);
                                 GetNextIent(&bc, &bent, &bi);          GetNextIent(&bc, &bent, &bi);
                         } else if ( aent.cr < bent.cr ) {        } else if ( aent.cr < bent.cr ) {
                                 AppendIent( m, aent.row, aent.col, (Obj)aent.body);          AppendIent( m, aent.row, aent.col, (Obj)aent.body);
                                 GetNextIent(&ac, &aent, &ai);          GetNextIent(&ac, &aent, &ai);
                         } else if ( bent.cr == -1 ) {        } else if ( bent.cr == -1 ) {
                                 AppendIent( m, aent.row, aent.col, (Obj)aent.body);          AppendIent( m, aent.row, aent.col, (Obj)aent.body);
                                 GetNextIent(&ac, &aent, &ai);          GetNextIent(&ac, &aent, &ai);
                         } else {        } else {
                                 arf_chsgn((Obj)bent.body, (Obj *)&obj);          arf_chsgn((Obj)bent.body, (Obj *)&obj);
                                 AppendIent( m, bent.row, bent.col, (Obj)obj);          AppendIent( m, bent.row, bent.col, (Obj)obj);
                                 GetNextIent(&bc, &bent, &bi);          GetNextIent(&bc, &bent, &bi);
                                 if (bent.cr == -1){          if (bent.cr == -1){
                                         while(aent.cr != -1){            while(aent.cr != -1){
                                                 AppendIent(m, aent.row, aent.col, (Obj)aent.body);              AppendIent(m, aent.row, aent.col, (Obj)aent.body);
                                                 GetNextIent(&ac, &aent, &ai);              GetNextIent(&ac, &aent, &ai);
                                         }            }
                                         break;            break;
                                 }          }
                         }        }
                 }      }
                 while(bent.cr != -1) {      while(bent.cr != -1) {
                         arf_chsgn((Obj)bent.body, (Obj *)&obj);        arf_chsgn((Obj)bent.body, (Obj *)&obj);
                         AppendIent( m, bent.row, bent.col, (Obj)obj);        AppendIent( m, bent.row, bent.col, (Obj)obj);
                         GetNextIent(&bc, &bent, &bi);        GetNextIent(&bc, &bent, &bi);
                 }      }
                 *c = m;      *c = m;
         }    }
 }  }
   
 void MulrMatI(vl, a, b, rp)  void MulrMatI(vl, a, b, rp)
 VL vl;  VL vl;
 Obj a, b, *rp;  Obj a, b, *rp;
 {  {
         /* multiply a expression and a index type matrix */    /* multiply a expression and a index type matrix */
         IMAT m;    IMAT m;
         IENT ent;    IENT ent;
         IMATC Im;    IMATC Im;
         Obj p;    Obj p;
         int ia;    int ia;
   
         NEWIMAT(m);    NEWIMAT(m);
         m->col = ((IMAT)b)->col;    m->col = ((IMAT)b)->col;
         m->row = ((IMAT)b)->row;    m->row = ((IMAT)b)->row;
         Im = (IMATC)(((IMAT)b)->root);    Im = (IMATC)(((IMAT)b)->root);
         ia = -1;    ia = -1;
         GetNextIent(&Im, &ent, &ia);    GetNextIent(&Im, &ent, &ia);
         while(ent.cr != -1) {    while(ent.cr != -1) {
                 arf_mul(vl, (Obj)a, (Obj)ent.body, (Obj *)&p);      arf_mul(vl, (Obj)a, (Obj)ent.body, (Obj *)&p);
                 AppendIent(m, ent.row, ent.col, (Obj)p);      AppendIent(m, ent.row, ent.col, (Obj)p);
                 GetNextIent(&Im, &ent, &ia);      GetNextIent(&Im, &ent, &ia);
         }    }
         *rp = (Obj)m;    *rp = (Obj)m;
 }  }
   
 void MulMatG(vl, a, b, c)  void MulMatG(vl, a, b, c)
 VL vl;  VL vl;
 Obj a, b, *c;  Obj a, b, *c;
 {  {
         /* multiply index type matrix general procedure */    /* multiply index type matrix general procedure */
         IMAT m;    IMAT m;
   
         if ( !a ) {    if ( !a ) {
                 NEWIMAT(m);      NEWIMAT(m);
                 m->col = ((IMAT)b)->col;      m->col = ((IMAT)b)->col;
                 m->row = ((IMAT)b)->row;      m->row = ((IMAT)b)->row;
                 *c = (Obj)m;      *c = (Obj)m;
         } else if ( !b ) {    } else if ( !b ) {
                 NEWIMAT(m);      NEWIMAT(m);
                 m->col = ((IMAT)a)->col;      m->col = ((IMAT)a)->col;
                 m->row = ((IMAT)a)->row;      m->row = ((IMAT)a)->row;
                 *c = (Obj)m;      *c = (Obj)m;
         } else if ( OID(a) <= O_R ) MulrMatI(vl, (Obj)a, (Obj)b, (Obj *)c);    } else if ( OID(a) <= O_R ) MulrMatI(vl, (Obj)a, (Obj)b, (Obj *)c);
         else if ( OID(b) <= O_R ) MulrMatI(vl, (Obj)b, (Obj)a, (Obj *)c);    else if ( OID(b) <= O_R ) MulrMatI(vl, (Obj)b, (Obj)a, (Obj *)c);
         else MulMatS(vl, (IMAT)a, (IMAT)b, (IMAT *)c);    else MulMatS(vl, (IMAT)a, (IMAT)b, (IMAT *)c);
 }  }
   
 void MulMatS(vl, m,n,rp)  void MulMatS(vl, m,n,rp)
 VL vl;  VL vl;
 IMAT m, n, *rp;  IMAT m, n, *rp;
 {  {
         /* multiply index type matrix and index type matrix */    /* multiply index type matrix and index type matrix */
         IMAT r, a11, a12, a21, a22, b11, b12, b21, b22;    IMAT r, a11, a12, a21, a22, b11, b12, b21, b22;
         IMAT ans1, ans2, c11, c12, c21, c22, s1, s2, t1, t2, u1, v1, w1;    IMAT ans1, ans2, c11, c12, c21, c22, s1, s2, t1, t2, u1, v1, w1;
         pointer u, v, *ab;    pointer u, v, *ab;
         int hmcol, hmrow, hncol, hnrow;    int hmcol, hmrow, hncol, hnrow;
         IENT ent, entn, entm;    IENT ent, entn, entm;
         IMATC in,im;    IMATC in,im;
         int *c, ai, bi, cr, row, col, ca11,ca12,ca21,ca22;    int *c, ai, bi, cr, row, col, ca11,ca12,ca21,ca22;
         if ( m->col != n->row ) {    if ( m->col != n->row ) {
                 *rp =0; error("mulmati : size mismatch");      *rp =0; error("mulmati : size mismatch");
         }    }
         vl = CO;    vl = CO;
         NEWIMAT(r);    NEWIMAT(r);
         r->row = m->row;    r->row = m->row;
         r->col = n->col;    r->col = n->col;
         if( m->clen == 0 || n->clen == 0){    if( m->clen == 0 || n->clen == 0){
         /* zero matrix case */    /* zero matrix case */
                 *rp = (pointer)r;      *rp = (pointer)r;
                 return;      return;
         } else if(StrassenSize == 0) {    } else if(StrassenSize == 0) {
         /* not use Strassen algorithm */    /* not use Strassen algorithm */
                 MulMatI(vl, m, n, &r);      MulMatI(vl, m, n, &r);
                 *rp = (pointer)r;      *rp = (pointer)r;
                 return;      return;
 #if 0  #if 0
         } else if(m->row == 1){    } else if(m->row == 1){
                 ab = (pointer)MALLOC((n->col +1)*sizeof(Obj));      ab = (pointer)MALLOC((n->col +1)*sizeof(Obj));
                 ai = -1;      ai = -1;
                 im = (pointer)m->root;      im = (pointer)m->root;
                 GetNextIent(&im, &entm, &ai);      GetNextIent(&im, &entm, &ai);
                 bi = -1;      bi = -1;
                 in = (pointer)n->root;      in = (pointer)n->root;
                 GetNextIent(&in, &entn, &bi);      GetNextIent(&in, &entn, &bi);
                 while( entn.cr != -1 ){      while( entn.cr != -1 ){
                         if( entn.row == entm.col ){        if( entn.row == entm.col ){
                                 arf_mul(vl,(Obj)entm.body,(Obj)entm.body,(Obj *)&u);          arf_mul(vl,(Obj)entm.body,(Obj)entm.body,(Obj *)&u);
                                 arf_add(vl,(Obj)u,(Obj)ab[entn.col],(Obj *)&v);          arf_add(vl,(Obj)u,(Obj)ab[entn.col],(Obj *)&v);
                                 ab[entn.col] = (pointer)v;          ab[entn.col] = (pointer)v;
                                 GetNextIent(&in, &entn, &bi);          GetNextIent(&in, &entn, &bi);
                         } else if( entn.row < entm.col ) {        } else if( entn.row < entm.col ) {
                                 GetNextIent(&in, &entn, &bi);          GetNextIent(&in, &entn, &bi);
                         } else {        } else {
                                 GetNextIent(&im, &entm, &ai);          GetNextIent(&im, &entm, &ai);
                         }        }
                 }      }
                 for(ai=0; ai< m->col; ai++){      for(ai=0; ai< m->col; ai++){
                         if(ab[ai] != 0) AppendIent(r, 1, ai, (Obj)&ab[ai]);        if(ab[ai] != 0) AppendIent(r, 1, ai, (Obj)&ab[ai]);
                 }      }
                 *rp=r;      *rp=r;
                 return;      return;
         } else if(n->col == 1){    } else if(n->col == 1){
         /* not yet */    /* not yet */
                 *rp=0;      *rp=0;
                 return;      return;
         } else if(m->col == 1){    } else if(m->col == 1){
                 ai = -1;      ai = -1;
                 im = (pointer)m->root;      im = (pointer)m->root;
                 GetNextIent(&im, &entm, &ai);      GetNextIent(&im, &entm, &ai);
                 while( entm.cr != -1 ){      while( entm.cr != -1 ){
                         bi = -1;        bi = -1;
                         in = (pointer)n->root;        in = (pointer)n->root;
                         GetNextIent(&in, &entn, &bi);        GetNextIent(&in, &entn, &bi);
                         while( entn.cr != -1 ){        while( entn.cr != -1 ){
                                 arf_mul(vl,(Obj)entm.body,(Obj)entn.body,(Obj *)&u);          arf_mul(vl,(Obj)entm.body,(Obj)entn.body,(Obj *)&u);
                                 AppendIent(r, entm.row, entn.col, (Obj)&u);          AppendIent(r, entm.row, entn.col, (Obj)&u);
                                 GetNextIent(&in, &entn, &bi);          GetNextIent(&in, &entn, &bi);
                         }        }
                         GetNextIent(&im, &entm, &ai);        GetNextIent(&im, &entm, &ai);
                 }      }
                 *rp = r;      *rp = r;
                 return;      return;
 #endif  #endif
         } else if((m->row<=StrassenSize)||(m->col<=StrassenSize)|| (n->col<=StrassenSize)) {    } else if((m->row<=StrassenSize)||(m->col<=StrassenSize)|| (n->col<=StrassenSize)) {
         /* not use Strassen algorithm */    /* not use Strassen algorithm */
                 MulMatI(vl, m, n, &r);      MulMatI(vl, m, n, &r);
                 *rp = (pointer)r;      *rp = (pointer)r;
                 return;      return;
         }    }
         /* Strassen Algorithm */    /* Strassen Algorithm */
         /* calcrate matrix half size */    /* calcrate matrix half size */
         hmrow = (m->row + (m->row & 1)) >> 1;    hmrow = (m->row + (m->row & 1)) >> 1;
         hmcol = (m->col + (m->col & 1)) >> 1;    hmcol = (m->col + (m->col & 1)) >> 1;
         hnrow = (n->row + (n->row & 1)) >> 1;    hnrow = (n->row + (n->row & 1)) >> 1;
         hncol = (n->col + (n->col & 1)) >> 1;    hncol = (n->col + (n->col & 1)) >> 1;
         NEWIMAT(a11); a11->col = hmcol; a11->row = hmrow;    NEWIMAT(a11); a11->col = hmcol; a11->row = hmrow;
         NEWIMAT(a12); a12->col = hmcol; a12->row = hmrow;    NEWIMAT(a12); a12->col = hmcol; a12->row = hmrow;
         NEWIMAT(a21); a21->col = hmcol; a21->row = hmrow;    NEWIMAT(a21); a21->col = hmcol; a21->row = hmrow;
         NEWIMAT(a22); a22->col = hmcol; a22->row = hmrow;    NEWIMAT(a22); a22->col = hmcol; a22->row = hmrow;
         NEWIMAT(b11); b11->col = hncol; b11->row = hnrow;    NEWIMAT(b11); b11->col = hncol; b11->row = hnrow;
         NEWIMAT(b12); b12->col = hncol; b12->row = hnrow;    NEWIMAT(b12); b12->col = hncol; b12->row = hnrow;
         NEWIMAT(b21); b21->col = hncol; b21->row = hnrow;    NEWIMAT(b21); b21->col = hncol; b21->row = hnrow;
         NEWIMAT(b22); b22->col = hncol; b22->row = hnrow;    NEWIMAT(b22); b22->col = hncol; b22->row = hnrow;
   
         /* copy matrix n to 4 small matrix a11,a12,a21,a22 */    /* copy matrix n to 4 small matrix a11,a12,a21,a22 */
         im = (pointer)m->root;    im = (pointer)m->root;
         ai = -1;    ai = -1;
         GetNextIent(&im, &ent, &ai);    GetNextIent(&im, &ent, &ai);
         while( ent.cr != -1 ){    while( ent.cr != -1 ){
                 if(ent.col < hmcol){      if(ent.col < hmcol){
                         if(ent.row < hmrow){        if(ent.row < hmrow){
                                 AppendIent(a11,ent.row,ent.col,(Obj)ent.body);          AppendIent(a11,ent.row,ent.col,(Obj)ent.body);
                         } else {        } else {
                                 AppendIent(a21,ent.row-hmrow,ent.col,(Obj)ent.body);          AppendIent(a21,ent.row-hmrow,ent.col,(Obj)ent.body);
                         }        }
                 } else {      } else {
                         if(ent.row < hmrow){        if(ent.row < hmrow){
                                 AppendIent(a12,ent.row,ent.col-hmcol,(Obj)ent.body);          AppendIent(a12,ent.row,ent.col-hmcol,(Obj)ent.body);
                         } else {        } else {
                                 AppendIent(a22,ent.row-hmrow,ent.col-hmcol,(Obj)ent.body);          AppendIent(a22,ent.row-hmrow,ent.col-hmcol,(Obj)ent.body);
                         }        }
                 }      }
                 GetNextIent(&im, &ent, &ai);      GetNextIent(&im, &ent, &ai);
         }    }
         /* copy matrix m to 4 small matrix b11,b12,b21,b22 */    /* copy matrix m to 4 small matrix b11,b12,b21,b22 */
         im = (pointer)n->root;    im = (pointer)n->root;
         ai = -1;    ai = -1;
         GetNextIent(&im, &ent, &ai);    GetNextIent(&im, &ent, &ai);
         while( ent.cr != -1 ){    while( ent.cr != -1 ){
                 if(ent.col < hmcol){      if(ent.col < hmcol){
                         if(ent.row < hnrow){        if(ent.row < hnrow){
                                 AppendIent(b11,ent.row,ent.col,(Obj)ent.body);          AppendIent(b11,ent.row,ent.col,(Obj)ent.body);
                         } else {        } else {
                                 AppendIent(b21,ent.row-hnrow,ent.col,(Obj)ent.body);          AppendIent(b21,ent.row-hnrow,ent.col,(Obj)ent.body);
                         }        }
                 } else {      } else {
                         if(ent.row < hnrow){        if(ent.row < hnrow){
                                 AppendIent(b12,ent.row,ent.col-hncol,(Obj)ent.body);          AppendIent(b12,ent.row,ent.col-hncol,(Obj)ent.body);
                         } else {        } else {
                                 AppendIent(b22,ent.row-hnrow,ent.col-hncol,(Obj)ent.body);          AppendIent(b22,ent.row-hnrow,ent.col-hncol,(Obj)ent.body);
                         }        }
                 }      }
                 GetNextIent(&im, &ent, &ai);      GetNextIent(&im, &ent, &ai);
         }    }
         /* expand matrix by Strassen-Winograd algorithm */    /* expand matrix by Strassen-Winograd algorithm */
         /* s1 = A21 + A22 */    /* s1 = A21 + A22 */
         AddMatI(vl,a21,a22, &s1);    AddMatI(vl,a21,a22, &s1);
   
         /* s2=s1-A11 */    /* s2=s1-A11 */
         SubMatI(vl,s1,a11,&s2);    SubMatI(vl,s1,a11,&s2);
   
         /* t1=B12-B11 */    /* t1=B12-B11 */
         SubMatI(vl,b12,b11,&t1);    SubMatI(vl,b12,b11,&t1);
   
         /* t2=B22-t1 */    /* t2=B22-t1 */
         SubMatI(vl,b22,t1,&t2);    SubMatI(vl,b22,t1,&t2);
   
         /* u=(A11-A21)*(B22-B12) */    /* u=(A11-A21)*(B22-B12) */
         SubMatI(vl,a11,a21,&ans1);    SubMatI(vl,a11,a21,&ans1);
         SubMatI(vl,b22,b12,&ans2);    SubMatI(vl,b22,b12,&ans2);
         MulMatS(vl, ans1,ans2,&u1);    MulMatS(vl, ans1,ans2,&u1);
   
         /* v=s1*t1 */    /* v=s1*t1 */
         MulMatS(vl, s1,t1,&v1);    MulMatS(vl, s1,t1,&v1);
   
         /* w=A11*B11+s2*t2 */    /* w=A11*B11+s2*t2 */
         MulMatS(vl, a11,b11,&ans1);    MulMatS(vl, a11,b11,&ans1);
         MulMatS(vl, s2,t2,&ans2);    MulMatS(vl, s2,t2,&ans2);
         AddMatI(vl,ans1,ans2,&w1);    AddMatI(vl,ans1,ans2,&w1);
   
         /* C11 = A11*B11+A12*B21 */    /* C11 = A11*B11+A12*B21 */
         MulMatS(vl, a12,b21,&ans2);    MulMatS(vl, a12,b21,&ans2);
         AddMatI(vl,ans1,ans2,&c11);    AddMatI(vl,ans1,ans2,&c11);
   
         /* C12 = w1+v1+(A12-s2)*B22 */    /* C12 = w1+v1+(A12-s2)*B22 */
         SubMatI(vl,a12,s2,&ans1);    SubMatI(vl,a12,s2,&ans1);
         MulMatS(vl, ans1, b22, &ans2);    MulMatS(vl, ans1, b22, &ans2);
         AddMatI(vl, w1, v1, &ans1);    AddMatI(vl, w1, v1, &ans1);
         AddMatI(vl, ans1, ans2, &c12);    AddMatI(vl, ans1, ans2, &c12);
   
         /* C21 = w1+u1+A22*(B21-t2) */    /* C21 = w1+u1+A22*(B21-t2) */
         SubMatI(vl, b21, t2, &ans1);    SubMatI(vl, b21, t2, &ans1);
         MulMatS(vl, a22, ans1, &ans2);    MulMatS(vl, a22, ans1, &ans2);
         AddMatI(vl, w1, u1, &ans1);    AddMatI(vl, w1, u1, &ans1);
         AddMatI(vl, ans1, ans2, &c21);    AddMatI(vl, ans1, ans2, &c21);
   
         /* C22 = w1 + u1 + v1 */    /* C22 = w1 + u1 + v1 */
         AddMatI(vl, ans1, v1, &c22);    AddMatI(vl, ans1, v1, &c22);
   
         /* create return i matrix */    /* create return i matrix */
         r->col = m->col;    r->col = m->col;
         r->row = n->row;    r->row = n->row;
   
         /* copy c11 to r */    /* copy c11 to r */
         ca11 = -1;    ca11 = -1;
         if( c11->root ){    if( c11->root ){
                 im = (pointer)c11->root;      im = (pointer)c11->root;
                 ai = -1;      ai = -1;
                 GetNextIent(&im, &ent, &ai);      GetNextIent(&im, &ent, &ai);
                 while( ai != -1 ){      while( ai != -1 ){
                         AppendIent(r,ent.row,ent.col,(Obj)ent.body);        AppendIent(r,ent.row,ent.col,(Obj)ent.body);
                         GetNextIent(&im, &ent, &ai);        GetNextIent(&im, &ent, &ai);
                 }      }
         }    }
         /* copy c21 to r */    /* copy c21 to r */
         if( c21->root ){    if( c21->root ){
                 im = (pointer)c21->root;      im = (pointer)c21->root;
                 ai = -1;      ai = -1;
                 GetNextIent(&im, &ent, &ai);      GetNextIent(&im, &ent, &ai);
                 while( ent.cr != -1 ){      while( ent.cr != -1 ){
                         PutIent(r, ent.row + hmrow, ent.col, (Obj)ent.body);        PutIent(r, ent.row + hmrow, ent.col, (Obj)ent.body);
                         GetNextIent(&im, &ent, &ai);        GetNextIent(&im, &ent, &ai);
                 }      }
         }    }
         /* copy c12 to r */    /* copy c12 to r */
         if( c12->root ){    if( c12->root ){
                 im = (pointer)c12->root;      im = (pointer)c12->root;
                 ai = -1;      ai = -1;
                 GetNextIent(&im, &ent, &ai);      GetNextIent(&im, &ent, &ai);
                 while( ent.cr != -1 ){      while( ent.cr != -1 ){
                         PutIent(r, ent.row, ent.col + hncol, (Obj)ent.body);        PutIent(r, ent.row, ent.col + hncol, (Obj)ent.body);
                         GetNextIent(&im, &ent, &ai);        GetNextIent(&im, &ent, &ai);
                 }      }
         }    }
         /* copy c22 to r */    /* copy c22 to r */
         if( c22->root ){    if( c22->root ){
                 im = (pointer)c22->root;      im = (pointer)c22->root;
                 ai = -1;      ai = -1;
                 GetNextIent(&im, &ent, &ai);      GetNextIent(&im, &ent, &ai);
                 while( ent.cr != -1 ){      while( ent.cr != -1 ){
                         PutIent(r, ent.row + hmrow, ent.col + hncol, (Obj)ent.body);        PutIent(r, ent.row + hmrow, ent.col + hncol, (Obj)ent.body);
                         GetNextIent(&im, &ent, &ai);        GetNextIent(&im, &ent, &ai);
                 }      }
         }    }
         *rp = (pointer)r;    *rp = (pointer)r;
         return;    return;
 }  }
   
 void MulMatI(vl,m,n,r)  void MulMatI(vl,m,n,r)
 VL vl;  VL vl;
 IMAT m, n, *r;  IMAT m, n, *r;
 {  {
         /* inner prodocut algorithm for index type multiply procedure */    /* inner prodocut algorithm for index type multiply procedure */
         IMAT l;    IMAT l;
         IMATC im, imt;    IMATC im, imt;
         IENT ent, tent;    IENT ent, tent;
         int bc, bend, ac, aend;    int bc, bend, ac, aend;
         int col, row, tcol, trow;    int col, row, tcol, trow;
         int i, j, k, ai, bi;    int i, j, k, ai, bi;
         int bj, ik,kj;    int bj, ik,kj;
         pointer s, u, v;    pointer s, u, v;
   
         typedef struct oIND {    typedef struct oIND {
                 int row, col;      int row, col;
                 pointer body;      pointer body;
         } *IND;    } *IND;
         IND a,b;    IND a,b;
         /* make trans(n) */    /* make trans(n) */
         a = (IND)MALLOC(IMATCH * m->clen *sizeof(struct oIND)+1);    a = (IND)MALLOC(IMATCH * m->clen *sizeof(struct oIND)+1);
         b = (IND)MALLOC(IMATCH * n->clen *sizeof(struct oIND)+1);    b = (IND)MALLOC(IMATCH * n->clen *sizeof(struct oIND)+1);
   
         bend = -1;    bend = -1;
         row = n->row;    row = n->row;
         col = n->col;    col = n->col;
         bc = -1;    bc = -1;
         im = (pointer)n->root;    im = (pointer)n->root;
         GetNextIent(&im, &ent, &bc);    GetNextIent(&im, &ent, &bc);
         b[++bend].body = ent.body;    b[++bend].body = ent.body;
         b[bend].row = ent.col;    b[bend].row = ent.col;
         b[bend].col = ent.row;    b[bend].col = ent.row;
         GetNextIent(&im, &ent, &bc);    GetNextIent(&im, &ent, &bc);
         while ( ent.cr != -1 ) {    while ( ent.cr != -1 ) {
                 trow = ent.col;      trow = ent.col;
                 tcol = ent.row;      tcol = ent.row;
                 for( i = bend; i >= 0; i--) {      for( i = bend; i >= 0; i--) {
                         if( b[i].row > trow ) {        if( b[i].row > trow ) {
                                 b[i + 1] = b[i];          b[i + 1] = b[i];
                         } else if ( b[i].col > tcol ) {        } else if ( b[i].col > tcol ) {
                                 b[i + 1] = b[i];          b[i + 1] = b[i];
                         } else {        } else {
                                 b[i+1].col = tcol;          b[i+1].col = tcol;
                                 b[i+1].row = trow;          b[i+1].row = trow;
                                 b[i+1].body = ent.body;          b[i+1].body = ent.body;
                                 break;          break;
                         }        }
                 }      }
                 if ( i == -1 ) {      if ( i == -1 ) {
                         b[0].col = tcol;        b[0].col = tcol;
                         b[0].row = trow;        b[0].row = trow;
                         b[0].body = ent.body;        b[0].body = ent.body;
                 }      }
                 bend++;      bend++;
                 GetNextIent(&im, &ent, &bc);      GetNextIent(&im, &ent, &bc);
         }    }
   
         im = (pointer)m->root;    im = (pointer)m->root;
         ac = -1;    ac = -1;
         GetNextIent(&im, &ent, &ac);    GetNextIent(&im, &ent, &ac);
         aend = -1;    aend = -1;
         while( ent.cr != -1 ){    while( ent.cr != -1 ){
                 a[++aend].col = ent.col;      a[++aend].col = ent.col;
                 a[aend].row = ent.row;      a[aend].row = ent.row;
                 a[aend].body = ent.body;      a[aend].body = ent.body;
                 GetNextIent(&im, &ent, &ac);      GetNextIent(&im, &ent, &ac);
         }    }
         /* make return matrix */    /* make return matrix */
         NEWIMAT(l);    NEWIMAT(l);
         l->row = m->row;    l->row = m->row;
         l->col = n->col;    l->col = n->col;
         ac = -1;    ac = -1;
         for( i = 0; i<= aend;) {    for( i = 0; i<= aend;) {
                 ai = a[i].row;      ai = a[i].row;
                 bj = b[0].row;      bj = b[0].row;
                 s = 0;      s = 0;
                 ik=i;      ik=i;
                 for(j=0; j<= bend;){      for(j=0; j<= bend;){
                         if( a[ik].col == b[j].col) {        if( a[ik].col == b[j].col) {
                                 arf_mul(CO,(Obj)a[ik].body, (Obj)b[j].body, (Obj *)&u);          arf_mul(CO,(Obj)a[ik].body, (Obj)b[j].body, (Obj *)&u);
                                 arf_add(CO,(Obj)s,(Obj)u,(Obj *)&v);          arf_add(CO,(Obj)s,(Obj)u,(Obj *)&v);
                                 s = v;          s = v;
                                 j++;          j++;
                                 if ( bj != b[j].row ) {          if ( bj != b[j].row ) {
                                         AppendIent(l, ai, bj, (Obj)s);            AppendIent(l, ai, bj, (Obj)s);
                                         ik = i;            ik = i;
                                         bj = b[j].row;            bj = b[j].row;
                                         s = 0;            s = 0;
                                 } else {          } else {
                                         ik++;            ik++;
                                         if ( ai != a[ik].row ) {            if ( ai != a[ik].row ) {
                                                 AppendIent(l, ai, bj, (Obj)s);              AppendIent(l, ai, bj, (Obj)s);
                                                 s = 0;              s = 0;
                                                 while ( bj == b[j].row ) {              while ( bj == b[j].row ) {
                                                         j++;                j++;
                                                         if ( j > bend ) break;                if ( j > bend ) break;
                                                 }              }
                                                 ik = i;              ik = i;
                                                 bj = b[j].row;              bj = b[j].row;
                                         }            }
                                 }          }
                         } else if ( a[ik].col > b[j].col ) {        } else if ( a[ik].col > b[j].col ) {
                                 j++;          j++;
                                 if ( bj != b[j].row ) {          if ( bj != b[j].row ) {
                                         AppendIent(l, ai, bj, (Obj)s);            AppendIent(l, ai, bj, (Obj)s);
                                         s = 0;            s = 0;
                                         ik = i;            ik = i;
                                         bj = b[j].row;            bj = b[j].row;
                                 }          }
                         } else /* if ( a[ik].col < b[j].col ) */ {        } else /* if ( a[ik].col < b[j].col ) */ {
                                 ik++;          ik++;
                                 if ( ai != a[ik].row ) {          if ( ai != a[ik].row ) {
                                         AppendIent(l, ai, bj, (Obj)s);            AppendIent(l, ai, bj, (Obj)s);
                                         s = 0;            s = 0;
                                         while ( bj == b[j].row ) {            while ( bj == b[j].row ) {
                                                 j++;              j++;
                                                 if ( j > bend ) break;              if ( j > bend ) break;
                                         }            }
                                         bj = b[j].row;            bj = b[j].row;
                                         ik = i;            ik = i;
                                 }          }
                         }        }
                 }      }
                 i = ik;      i = ik;
                 while ( ai == a[i].row ) {      while ( ai == a[i].row ) {
                         i++;        i++;
                         if( i > aend) break;        if( i > aend) break;
                 }      }
         }    }
         *r = (IMAT)l;    *r = (IMAT)l;
         FREE(a);    FREE(a);
         FREE(b);    FREE(b);
         return;    return;
 }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

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