看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《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)
lovelu8888:真是太強大了 受用無窮 感謝 10/04 18:26
FAITHY:推 厲害~ 10/04 21:28
hilorrk: 真是太強大了 受用無窮 感謝 10/05 00:31
diabloevagto:http://www.simunova.com/en/node/24 10/05 08:25
diabloevagto:Matrix Template Library 4 10/05 08:26