標籤

2013年8月5日 星期一

陣列-sparse matrix的加法

// add sparse matrix c = a + b
void add_spm(spm *c, spm *a, spm *b)
{
   int ia = 1; // index for a
   int ib = 1; // index for b
   int ic = 1; // index for c

   // while both index are not yet reach the end
   while (ia <= a[0].val && ib <= b[0].val)
      // if a position > b position, then assign b to c
      if (a[ia].row > b[ib].row ||
          a[ia].row == b[ib].row && a[ia].col > b[ib].col)
         c[ic++] = b[ib++];
      // if a position < b position, then assign a to c
      else if (a[ia].row < b[ib].row ||
               a[ia].row == b[ib].row && a[ia].col < b[ib].col)
         c[ic++] = a[ia++];
      // if a position = b position, c = a+c
      else {
         // we only save non-zero elements
         int sum = a[ia].val + b[ib].val;
         if (sum != 0) {
            c[ic].row = a[ia].row;
            c[ic].col = a[ia].col;
            c[ic].val = sum;
            ic++;
         }
         ia++;
         ib++;
      }
   /* end while */

   // assign the rest elements a OR b to c
   while (ia <= a[0].val)
      c[ic++] = a[ia++];
   while (ib <= b[0].val)
      c[ic++] = b[ib++];
   // assgin the matrix info to c
   c[0].row = a[0].row;
   c[0].col = a[0].col;
   c[0].val = ic - 1;
}
加法其實很簡單,有overlap的elements就是直接加,沒有overlap的部分就是看row和column的位置,先判斷row在判斷column,row/column數字少的就直接遞給c。接著如果其中一方a或b已經把它自己的element都遞給c的時候,那麼另外一方就直接把剩餘的element都遞給c,因為已經不會有overlap的部分了。
  while (ia <= a[0].val && ib <= b[0].val)
首先這個迴圈,當a以及b皆有element要加的時候就會持續的做以下的加法。

      if (a[ia].row > b[ib].row ||
          a[ia].row == b[ib].row && a[ia].col > b[ib].col)
         c[ic++] = b[ib++];
在while迴圈仍有效的前提之下,開始判斷有沒有overlap的element。這邊就判定不是overlap,並且a的目前index的位置是在b之後的,所以我們就直接把b的element assign給c,並且各自的index往下一個element前進,而接著的else if則是相同的邏輯,只是是判定b的index在a之後。
      else {
         // we only save non-zero elements
         int sum = a[ia].val + b[ib].val;
         if (sum != 0) {
            c[ic].row = a[ia].row;
            c[ic].col = a[ia].col;
            c[ic].val = sum;
            ic++;
         }
接著最後則是a和b是overlap的element,把他們的值加上去之後assign給c,把c的index往後移之後
         ia++;
         ib++;
馬上把a和b的index都往後移,最後最外面的while迴圈跑完之後,有三種情形:1.(a沒有剩下了,b還有) 2.(b沒有剩下了,a還有) 3.(都沒有剩下了) 但不論是怎樣的情形,我們都會跑:
   while (ia <= a[0].val)
      c[ic++] = a[ia++];
   while (ib <= b[0].val)
      c[ic++] = b[ib++];
因為即使是情形1. a沒有剩下的element,我們跑while(ia <= a[0].val)它不會有element要執行,因此這邊是不會跑迴圈的,只會跑下面那個b,而情形2和情形3亦然是如此。最後我們再把這矩陣的資料assign給c就完成了。

沒有留言:

張貼留言