行列の積を計算するEXCELマクロ

 M×Lの行列とL×Nの行列の積を計算するExcelマクロを作成する。

 Excelのワークシートの任意の場所に下図のようにデータ(一番上に行列の大きさを指示するM,L,
N、続けて積を求める2つの行列の値)を入力し、Mを記したセルをアクティブにして実行したとき、
1行空白行を空けて結果(積)を出力するマクロを作成する。データ個数がどのようなものであっても
同様に出力できるようにする。

   
  M   L   N
  ↓   ↓   ↓



     第1行列3×4 →



     第2行列4×5 →





     結果の出力先 →
   3
   4
   5
   
   
   
   1
   2
   3
   4
   
   
   5
   6
   7
   8
   
   
   9
   0
   1
   2
   
   
   1
   2
   3
   4
   5
   
   6
   7
   8
   9
   0
   
   1
   2
   3
   4
   5
   
   6
   7
   8
   9
   0
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
  (1) MとLとNを読み込む。Mを読み込み、アクティブセルを右に移動させてL、さらに右に移動させ  てNを読み込む。 M = ActiveCell ActiveCell.Offset(0, 1).Range("A1").Select L = ActiveCell ActiveCell.Offset(0, 1).Range("A1").Select N = ActiveCell (2) VBにおいては、配列(行列と同じ)は用意されておらず、使用するときに定義しなければならな  い。第1行列をA、第2行列をB、結果の行列をCを名付けることにする。このとき、配列の定義は  次のようになる。 ReDim A(M, L), B(L, N), C(M, N) (3) 行列Aを読み込むプログラムは次のようになる。 ActiveCell.Offset(1, -2).Range("A1").Select For i = 1 To M   For j = 1 To L    A(i, j) = ActiveCell    ActiveCell.Offset(0, 1).Range("A1").Select   Next j   ActiveCell.Offset(1, -L).Range("A1").Select Next i  第1行目は、アクティブセルがNを読み込んだ場所にあるので、行列の左上隅に移動させる命令であ  る。3行目から6行目は、行の先頭にアクティブセルがあるときに、読んで右移動を繰り返すための  ものである。7行目は、1行分のデータを読み終わった後で、次の行に先頭にアクティブセルを移動  させる命令である。2行目と8行目は、必要な行数分だけ繰り返すための命令である。 (4) 行列Bを読み込むプログラムは次のようになる。 For i = 1 To L   For j = 1 To N    B(i, j) = ActiveCell    ActiveCell.Offset(0, 1).Range("A1").Select   Next j   ActiveCell.Offset(1, -N).Range("A1").Select Next i  行列Aを読み込むときとの違いは、Aを読み終わったとき、アクティブセルが行列Bの左上隅にある  ことと、読み込む個数及び移動する個数が異なっていることのみである。 (5) 行列AとBの積Cを求める。行列Cのi-j要素C(i, j)は、Aの第i行とBの第j列の要素それぞ  れの積の総和である。すなわち C(i, j) = A(i, 1)*B(1, j) + A(i, 2)*B(2, j) + ・・・ + A(i, L)*B(L, j)  である。これを計算するプログラムは s = 0 For k = 1 To L   s = s + A(i, k) * B(k, j) Next k C(i, j) = s  となる。ここで、sの代わりに C(i, j) を用いれば最後の行が不要であるが、記述を簡単化するた  めにsを用いている。C全体を求めるためには、上のプログラムのiを1からMへ、jを1からNへ  変化させればよい。したがって、次のようになる。 For i = 1 To M   For j = 1 To N    s = 0    For k = 1 To L      s = s + A(i, k) * B(k, j)    Next k    C(i, j) = s   Next j Next i (6) 結果を出力する。現在のアクティブセルの位置は、空白行の先頭であるので、出力先の左上隅にア  クティブセルを移動させる。 ActiveCell.Offset(1, 0).Range("A1").Select  行列の出力は、読み込みの逆であり、行毎に出力して右移動を繰り返し、必要なだけ行出力を繰り返  せばよい。結果は次のようになる。 For i = 1 To M   For j = 1 To N    ActiveCell = C(i, j)    ActiveCell.Offset(0, 1).Range("A1").Select   Next j   ActiveCell.Offset(1, -N).Range("A1").Select Next i
 M×L1行列A、L1×L2行列B、L2×N行列Cの積、すなわちA・B・CをDに計算するプログラムは次 のようになる。複雑であるが、各自で確認してみてもらいたい。 For i = 1 To M   For j = 1 To N    s = 0    For k1 = 1 To L1 For k2 = 1 To L2   s = s + A(i, k1) * B(k1, k2) * C(k2, j) Next k2    Next k1    D(i, j) = s   Next j Next i