McCal Matrix Calculation

1. はじめに

このドキュメントは、McCalの行列計算に関する説明です。

McCalは、二次元の配列を利用して、数学の行列の各種計算を行うことができます。McCalの行列演算は、複素数要素の場合もよくサポートしています。

Version 4.3より、数多くの行列計算用の演算子が追加されました。簡単に行列操作を行うことができます。演算子は、MATLAB®風の演算子に合わせてあります。

このドキュメントでは、配列の要素を示すためにPrintコマンドを使っていますが、インスペクタやArrayViewerを用いて、スプレッドシート風に表示できます。タッチによるドラッグ移動や、フリックも使えますので、インスペクタやArrayViewerを使うことの方が多いと思われます。

 

2.1 行列を作る

行列データを作成するには、二つの方法があります。一つ目は、角括弧、Dim宣言文(Dimension)を使って、スクリプト内で作成します。他の方法は、Array Viewerを用いて、インタラクティブに行列データを作成します。最初に角括弧を使って初期化してみましょう。

 

角括弧の中にコンマで区切った要素をリストして、配列を指定できます。要素に算術式をいれることもできます。二次元以上の配列は、角かっこを入れ子にします。

a = [[2,3],[1, -1+2i]] 
Print a
▽2 ▽3
▽1 ▽-1+2i
▶︎ array[2][2]

Print a+a
▽4 ▽6
▽2 ▽-2+4i
▶︎ array[2][2]

現在のMcCal scriptでは、角かっこの式は、一行である必要があります。言い換えれば、改行は含めることができません。

 

Dim 文の中に領域サイズ指定を入れた場合、それを角括弧による要素の数より優先します。領域サイズの方が小さい場合、あふれるデータは捨てられます。

Dim a[3][3] = [[2,3],[1,-1]] 
Print a
▽2  ▽3  ▽0
▽1  ▽-1 ▽0
▽0  ▽0  ▽0
▶︎ array[3][3]

 

角かっこによる行列宣言をそのまま計算に使うこともできます。

Print [[2,0],[0, 2]] * [[#cos(30), -#sin(30)],[#sin(30),#cos(30)]] 
▽1.7321  ▽1.0000
▽1.0000  ▽1.7321
▶︎ array[2][2]

 

 

2.2 ArrayViewer

ArrayViewerを用いても、行列の各要素の値を設定することができます。最初に配列を宣言しておきましょう(サイズは、ArrayViewer内から変更可能です):

Dim c[4][4]

ViewerIconを押して、McCal Viewer を起動し、変数タブから変数cを選び、ArrayViewerを起動します。

セルの一つをダブルタップすると、赤色に選択され、画面上部の入力領域が活性化します。数式を入れ、 eval() キーを押せば、評価値がその要素に代入されます。

array

Array Viewerの使い方は、ArrayViewer Help を参照してください。

2.3 要素にアクセスする

配列の要素を指定するには、角かっこを用いてインデックスを指定します。下に例をしめします。'c[1,2]' と 'c[1][2]' の両方の記法が許されます。

Print c
▽1.7321  ▽1.0000
▽2i  ▽1.4142
▶︎ array[2][2]

c[0][0]
▶︎ 1.7321

c[1,0]
▶︎ 2i

行列のデータを指定するときも、インデックスを指定するときも、角かっこが使われることに注意してください。McCalは、変数名の後ろに角かっこがくると、配列インデックスとみなします。言い換えると、配列を返す関数の後ろに配列インデックスを指定することはできません。返り値を一度変数に代入してから、インデックスを指定してください。

 

2.4 範囲を指定して要素を取り出す

コロン演算子 (:) を用いて、配列のある範囲を取り出せます。コロン演算子は、”開始の値:終了の値”として指定します。増分は1であるとみなします。コロン演算子は、McCal Help Documentにも説明があります。

以下の例では、配列cを用いて説明します。

Print c
▽1.7321  ▽1.0000  ▽0.0000 
▽1.0000  ▽0.5000  ▽i
▽-12345  ▽0.0000  ▽1.0000 
▶︎ array[2][2]

 

行と列それぞれに、始点と終点を明示して範囲を指定します。

Print c[1:2][1:2]
▽0.5000  ▽i
▽0.0000  ▽1.0000 
▶︎ array[2][2]

始点あるいは終点を省略した場合、それぞれ0とインデックスの最大値になります。コロン演算子のみの場合、その行あるいは列の0から最大値までを指定したとみなします。

c[:,0]
▽1.7321  ▽1.0000  ▽-12345
▶︎ array[3]

 

3 行列の計算

行列の和の例。行列の和と差の演算は、行列のサイズが一致している必要があります。和と差は、3次元配列でも可能です。

Dim a = [[2,3],[1,-1]] 
Print a+a
▽4 ▽6
▽2 ▽-2

行列の積の例。

Dim a = [[2,3],[1,-1]] 
Print a=a*a
▽7 ▽3
▽1 ▽4

Dim b=[1,0]
Print ab
▽7 ▽1

上の例のように、乗算演算子(*)、および省略された乗算演算子は、行列積を計算します。一番目の行列の列のサイズ(横方向)と二番目の行列の行(縦方向)のサイズが一致している必要があります。一次元配列は、積演算においては列のサイズが1である二次元配列(つまり縦方向に一行)として扱われます。要素の値が複素数でも計算できます。

下の例の要素ごと乗算演算子(.*)は、要素ごとに(element-by-element)、積を計算します。演算子の両側の行列のサイズが一致している必要があります。

Dim a=[[2,3],[1,-1]], b=[[2,1],[3,i]]
Print a
▽7 ▽3
▽1 ▽4
Print b
▽2 ▽1
▽3 ▽0+i

Print a.*b
▽14 ▽3
▽3  ▽0+4i

 

3.1 行列演算子

行列計算、配列の要素ごとの計算のための新しい演算子のリストです。

演算子 名称 説明
/ 右除算演算子 A/B : 右側からBの逆行列をかけることに相当します。Bは、正則な正方行列。
\ 左除算演算子 A*x=Bの時 x=A\B : 左側からAの逆行列をかけることに相当します。
.\ 要素ごとの左除算演算子 A.\B : 要素ごとに左除算を計算します。
' 複素共役転置演算子 A' : Aを転置して複素数要素は共役複素数に置き換えられた行列を返す。
.' 配列の転置演算子 A.' : Aを転置して返す。
.^ 配列要素のべき乗 A.^B : 要素ごとに、べき乗を計算する。A, Bは、片方が数か、同じ大きさ・次元の配列でなければならない。
.* 配列要素の乗算 A.*B : 要素ごとに、積を計算する。A, Bは、片方が数か、同じ大きさ・次元の配列でなければならない。
./ 配列要素の除算 A./B : 要素ごとに、商を計算する。A, Bは、片方が数か、同じ大きさ・次元の配列でなければならない。

要素ごとの演算子のドット(.)を入力するには、小数点キー . で代用します。小数点キーを押してから掛け算 × 、除算 ÷ べき乗キー xy などを押してください。あるいは、 (Mx) ボタンを選択すると、上記演算子のいくつかへのショートカットダイアログが現れます。

 

3.2 べき乗

正方行列の場合、べき乗が計算可能です。指数は-1以上の整数である必要があります。

Dim b=[[2,1],[3,i]]
b^(3)
▽20+3i ▽6+2i
▽18+6i ▽6+5i
▶︎ array[2][2]

指数が0の場合、行列と同じサイズの単位行列を返します。もっとも簡単な単位行列を作る方法です。

Dim b=[[2,1],[3,i]]
I = b^(0)
Print I
▽1 ▽0
▽0 ▽1
▶︎ array[2][2]

指数が-1の場合、その行列の逆行列を求めます。

>Dim b=[[2,1],[3,i]]
Print b^(-1)
▽0.1538-0.2308i ▽0.2308+0.1538i
▽0.6923+0.4615i ▽-0.4615-0.3077i
▶︎ array[2][2]

元の行列をかけて、逆行列であることを確認してみます。

>Dim b=[[2,1],[3,i]]
Print b*b^(-1)
▽1.0000 ▽0
▽0 ▽1.0000-0i
▶︎ array[2][2]

最後の要素が 1.0000-0i となっていますが、計算途中の丸め誤差がわずかに入っているためです( < 1×10-13程度)。

 

3.3 連立方程式を解く

McCalの行列計算機能を使って、連立方程式を解くことができます。係数に複素数が含まれる場合でも計算可能です。

例として3元連立方程式を解いてみます。

x+2y+3z=14
2x−y+2z=6
3x−2yーz=−4

は、行列演算としては、

matrix

なので

A = [[1,2,3],[2,-1,2],
[3,-2,-1]]
B = [14,6,-4]

と、行列をまず作成します。

左側から逆行列をかけていますので(x = A-1B = A\B)、ここでは、左除算演算子を使います。行列積の順序は可換でなないことに注意。つまり一般に A*B ≠ B*A。

Print A\B
▽1.0000 ▽2.0000 ▽3.0000
▶︎ array[3]

答え1、2、3(浮動小数点で計算されます)が得られます。

べき乗、あるいは逆行列関数を使って逆行列を作ることも可能です。

Print A^(-1)*B
▽1.0000 ▽2.0000 ▽3.0000
▶︎ array[3]

逆行列関数を使った例のスクリーンショットです。

inverse

 

3.4 固有ベクトル, 固有値

この章は、固有ベクトル、固有値(複素数を含む)を求める関数 #mxEig(A) の説明です。対象となる行列Aは、正方行列で実数係数である必要があります。この関数は、固有ベクトルと固有値を表す二つの行列を同時に返します。

固有値とは

     Av = λv ……… (1)

正方行列Aの固有ベクトルとは、ゼロでないベクトルvについて、 Aによる線形変換A*vが、自身のスカラー倍, λvになるとき (equation 1)、このベクトルを固有ベクトル、 スカラー値λを固有値とよぶ。固有値が複素数の範囲までゆるされるとすると、N次正方行列Aの固有値は、N個存在する。

固有値・固有ベクトルは、理学工学などの色々な分野で使われます。

#mxEig()関数について

McCalの組み込み関数, #mxEig(A)は、N個の固有ベクトルをまとめて、NxNの正方行列として返します。この行列のN個の縦のカラムが固有ベクトルです。固有値は、対角要素に固有値を持つNxNの対角行列を返します。つまり、返り値が二つの行列です。この二つの行列をV, Dとすると:

  [V,D] = #mxEig(A)

式1の定義から、この二つの行列VとDは、次の式をみたします。

     AV = VD ……… (2)

行列Vが正則であれば:

     V-1AV = D ……… (3)

Example 1: 以下の行列Aを例にとり、説明します。

 Print A
   ▽ 1  ▽ 2  ▽ 3
   ▽ 3  ▽ 1  ▽ 2
   ▽ 2  ▽ 3  ▽ 1

この行列の固有値と固有ベクトルを求めます。#mxEig()関数は、FunctionViewerの「行列・線形代数」に入れてあります。

 #mxEig(A)
 ▶︎ array[3][3], array[3][3]

#mxEig()関数は、3x3の大きさの行列を二個返しました。 <Ins>  ボタンを押してインスペクタを起動し、配列の内容を見てみます。

eigenvector

縦の行が一つの固有ベクトルになっています。今回は、複素数の要素を持つ行列になりました。#mxEig()の二番目の返り値である行列を調べてみます。右上の矢印ボタンを押して切り替えます。

eigenvalue

二番目の行列は、固有値を対角線上にならべた行列になっています。たとえば、最後の固有値, -1.5+0.8666i, に対応する固有ベクトルは、二つ上の図で赤枠で囲んだ行です。

それでは、左上隅の戻る矢印ボタンを押してインスペクタから電卓画面に戻り、返り値をそれぞれ変数V, D に格納します。

 ⇒ [V, D]

後置代入演算子と変数リストを使いました。

上の図で赤枠に囲まれた固有ベクトル、固有値を取り出すには、コロン演算子を使ってみましょう。

 Print V[:,2]
 ▽ 0.7317 -0.3624i  ▽ -0.6797 -0.4525i  ▽ -5.2021E-2 +0.8148i
 ▶︎ array[3]
 
 D[2,2]
 ▶︎ -1.5000 + 0.8660i

これを使って、式(1)を試してみます。左辺ー右辺で、各要素がゼロになるはずです。実際は、計算誤差を含んでいます。

 Print A*V[:,2] - D[2,2]*V[:,2]
 ▽ 0 +0i  ▽ 0 0i  ▽ 0 0i
 ▶︎ array[3]

 

個別の固有値について、上記のように計算するわけでなく、式(3)を確かめてみましょう。結果は、Dに等しくなるはずです:

 Print V^(-1)*A*V
   ▽ 6.00000 ▽ 0  ▽ 0
   ▽ 0 ▽ -1.5000 -0.8660i  ▽ 0
   ▽ 0 ▽ 0  ▽ -1.5000 +0.8660i

固有ベクトルについては、Wikiページ(外部リンク)などが参考になります。

 

4 免責事項

バグなどのソフトウェアの瑕疵については全力で除去しておりますが、もし発見された場合、ご一報いただければ幸いです。本ソフトウェアの使用により生じた損害、または第三者からのいかなる請求について、作者はその責任を負えませんので、あらかじめご了承ください。