2009年6月3日

Excel VBA 作矩陣相乘運算

雖然到最後你還是沒留下你的名字...


今天就來介紹一下,如何用程式撰寫多維矩陣乘法運算

首先要了解一下矩陣乘法的計算方式
  • (m1 x n1) * (m2 x n2) 結果會是 (m1 x n2)的矩陣
  • 上例中的 n1 = m2
  • 矩陣乘法位置互換結果就會不同
(大家可以直接點上方的 wiki 連結,裡面有更詳盡的介紹)

接著就是回到 Excel 啦
首先在 Sheet 上佈置一個 CommandButton
(沒看到的話,請到工具列→點右鍵→把設計工具箱打開)
然後在 Sheet 的儲存格上隨意填入一些值,等等要來當作矩陣的輸入值

接著在 Button 上點兩下進入 VBA 編輯畫面 (記得要在設計模式)
然後就是進入 VBA 的程式撰寫啦 >w<
  • 首先用 Application.InputBox 方法讓使用者選取畫面上的儲存格,Type=8表示回傳值為 Range 物件
  • 取得兩個 Range 物件的 Row Count 及 Column Count (切丁備用)
  • 依前面的規則判斷是否可運算 (範例裡的 M1C 要等於 M2R)
  • 建立兩個陣列物件,並將長度指定為第一個矩陣的 Column Count (或是第二個矩陣的 Row Count,它們兩個應該要相同)
到目前為止應該還算ok吧???
接著就是如何去計算結果矩陣裡的值
坎尼是用 wiki 裡提到的 這個方法

AB (結果矩陣) 中的 (1,2) 這格就是用 A 的第1列乘上 B 的第2欄

用下面這個動畫圖應該可以了解 (圖片來源:Scalar and Matrix Multiplication


所以再回到程式裡
坎尼用了兩個 For 迴圈將目標裡的值一格一格算出來
先是取得第一個矩陣的第一列(一維陣列),再去乘上第二個矩陣裡的一行(一維陣列)
可以得到結果矩陣第一列所有的值 (傳入 CellValue 裡計算)

接著再抓第一個矩陣的第二列去乘上第二個矩陣裡的每一行....以此類推

CellValue 是坎尼用來計算結果值的 Function
傳入兩個陣列即會把對應的 index 值相乘,最後再加總回傳 (回顧一下公式)


再來就是執行結果,先把模式改為執行模式 (點一下設計工具箱的三角板)
點「選取陣列」的按鈕,就會跳出選擇矩陣的方塊,此時可以在 Excel 儲存格上選取

矩陣1選完會再要求選擇矩陣2
記得,(m1 x n1) * (m2 x n2) 裡的 n1 = m2

選完之後,若是可以計算的兩個矩陣,會出現提示

Sheet2 裡果然有值

但是答案是否正確呢?
大家可以上 WIMS Online Matrix Multiplier 把相同的矩陣丟進去算算看
或是拿起筆來自己算吧 XDDD

由於中間省略了很多步驟,可能沒寫過 VBA 的人不知道坎尼在幹嘛吧 XD
坎尼今天上網有看到一個不錯的 Excel VBA 教學站 威廉博客
有興趣想學 Excel VBA 的人就過去看看吧 :D

矩陣這東西離坎尼好久遠了,好在有前人種好的大樹 - wiki
K了兩個晚上總算是有點成果
但是否還有更好的程式邏輯就請路過的大師們指教啦 哈哈哈
範例程式下載 要使用範例請先允許巨集執行

另外就是歡迎讀者發問
不過請留下可以連絡的方式,有時坎尼看不懂問題會睡不著覺啊啊啊~
另外要交作業的請不要問坎尼,這可是要收錢的,很貴的

2 則留言:

布丁 提到...

坎尼大您好:
感謝您特地開文章教學,小弟我已經閱讀過了,確實解決了小弟的疑惑。

小弟原本深陷於以「一個按鈕就想運算出結果」的窘境,想不到還可以用範圍選取的方式來做矩陣運算,這招還蠻帥氣的!
真的非常感謝您的相助!^^

對了,小弟我叫布丁,之前並不是有意要匿名發問的,請大大不要介意。

坎尼 提到...

名字那個是開玩笑啦
布丁你也不要介意 XD

另外我有做了個網頁版本,可以去玩一下
請點我

Google Spreadsheet 裡用規則運算式

最近因為工作關係,遇到要用 Google Form 及 Google Sheet 所以研究了 Google Sheet 裡的一些 function 怎麼用 首先,分享一下如何在 Google Sheet 裡用規則運算 :D