// 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就完成了。
沒有留言:
張貼留言