為什麼這篇一維 二維陣列鄉民發文收入到精華區:因為在一維 二維陣列這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者tropical72 (藍影)看板C_and_CPP標題Re: [問題] 二維陣列相乘時間Tue...
※ 引述《lovelu8888 (華小穎)》之銘言:
: 不好意思 我是新手
matrix 問題其實也不算好解, 無關新舊手問題。
: 還有在C裡面可以二維陣列乘一維陣列嗎?
: ex (8*8)*(8*1)=(8*1)
: 我剛剛自己試了好像是不行 所以八乘一的矩陣 就只能乖乖寫成八乘八的矩陣嗎?
: 感謝
一般在寫 matrix mult 時,我比較建議先去學 excel 怎麼進行 matrix mult.
方便到時驗證答案 (其實其它的 matrix 問題也可用 excel 協助驗證),
另一部份為, 手邊一定要有本線性代數的書, 要特別注意 matrix 運算時的條件與限制。
在做 matrix 相乘時,以 A[row_a][col_a] , B[row_b][col_b],
其實只有一個限制, col_a = row_b ,得到結果為 C[row_a][col_b],
其它的完全沒限制。以你的例子而言, C[8][1] = A[8][8] * B[8][1],
還是可以用二維陣列完成,沒必要刻意硬把 B 調成 B[8][8] 或是 B[8],
基於為 C 語言程式碼,程式碼參考如下
#define True 1
#define False 0
typedef float MType; // 定義 matrix 元素資料型態為 MType
typedef int Bool ;
#define row_a 8
#define col_a 8
#define row_b 8
#define col_b 1
#define row_c 8
#define col_c 1
int main()
{
MType a[row_a][col_a]={...};
MType b[row_b][col_b]={...};
MType c[row_c][col_c]={0.0f};
int i, j, k;
if(col_a != row_b) {
puts("a and b can't mult!!\n");
}
else if(row_c!=row_a || col_c!=col_b) {
puts("c can't receive the result!!\n");
}
else {
for(i=0; i!=row_a; ++i)
for(j=0; j!=col_b; ++j)
for(c[i][j]=0.0f, k=0; k<row_b; ++k)
c[i][j] = c[i][j] + a[i][k] * b[k][j];
// ending, you can output matrix c
}
return 0;
}
上面程式碼中,b c 都是二維陣列, 只是它們不是方陣,
且程式碼中之 i, j, k 與範例,這個線性代數課本上一定會用 Σ 公式寫出來,
C(m,n) = A(m,p) * B (p, n)
p
C(i, j) = Σ A(i,k) * B(k,j) , for 1 <= i <= m
k=1 for 1 <= j <= n
一般線代課本公式大概長這樣,其實仔細對照 for loop,
會發現只差在 index 起始值是 1 不是 0 ,稍會自己 shift 一下就好了,
會發現寫起來真的算是直覺了。Σ 和 丌 是寫數學程式會很喜歡看到這兩個符號,
因為真的只是看圖說故事(當然看圖說故事會有點效率面的問題,不過還不是現在考量)。
-----
再回到另一問題,上面主要在 B 有爭議,它是用 B[8][1], 二維陣列,
不是真正的一維陣列,若要把 B 改成一維陣列的話也可以做,
C 要怎麼改想清楚便可,但改法這樣湊一湊就四種了,
(B二維,C二維 ; B一維, C一維 ; B二維, C一維 ; B一維, C 二維)
於此只做 B, C 均一維,其餘不再實做其它可能性。
先看一下原本的重點
for(i=0; i!=row_a; ++i)
for(j=0; j!=col_b; ++j)
for(c[i][j]=0.0f, k=0; k<row_b; ++k)
c[i][j] = c[i][j] + a[i][k] * b[k][j];
注意到,col_b = 1,意思是 j loop 只會執行一次而已,
於是將所有有 j 之 index 全拿掉
for(i=0; i!=row_a; ++i)
for(j=0; j!=col_b; ++j)
for(c[i][j]=0.0f, k=0; k<row_b; ++k)
c[i][j]= c[i][j] + a[i][k] * b[k][j];
變成
for(i=0; i!=row_a; ++i)
for(c[i]=0.0f, k=0; k<row_b; ++k)
c[i]= c[i] + a[i][k] * b[k];
其它的宣告變成
MType a[8][8]; // a[row_a][col_a]
MType b[8]; // b[8][1], b[row_b]
MType c[8]; // c[8][1], c[row_c]
-----
如果 C language 不夠強的話就要先學數值分析,我認為不要太鑽牛角下去,
function 會、array 會、pointer 會、動態配置記憶體會,這些就夠去寫數值分析了。
其它,也歡迎有經驗之版友予以補充。
--
No matter how gifted you are,
alone, can not change the world.
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.78.41
※ 編輯: tropical72 來自: 180.177.78.41 (10/04 18:31)