線形代数
MATRIX |
[機能] 線形代数の基本的な各種計算を行います。
[書式] MATRIX "dv1=
eigen(dv2)"
[説明]
線形代数の各種計算を行います。
記述方法は matrix "変数名 = 線形代数計算式"
となります。
式の右辺は基本的にMATRIX専用の各種関数名と括弧内のデータ元配列変数名になりますが
四則計算の場合には "配列変数名1 式
配列変数名2"
の書式になります。
変数名は数値配列変数を(括弧)を付けずに指定したものとなります。
行列式とランクの時は返り値は配列でなく数値になるので左辺は通常の数値変数名を指定します。
使用する配列変数は事前にプログラムの冒頭で宣言しておく必要があります。
代入される配列のサイズが求められたものと異なる場合は自動的にリサイズされます。
(配列変数とMATRIX命令実行のスコープが異なる場合はリサイズができないためエラーになります)
*入力値や出力値が複素数のものについては現段階では対応しておりません。
行列データは配列変数で与えることになります。(配列変数を行列と見立てます)
列の数をx、行の数をyとするならば、dim dv1(y,x) と宣言します。
Basicの配列変数では
dim dv1(2) と宣言すると
0~2の3個の変数が宣言されてしまいます。
これは希望のサイズより1つ大きなサイズとなってしまうため
option
base -1 (詳しくはマニュアル:option base
を御覧ください)
この命令を記述することで0~1までの2個を確保するようにします。
これは一般的なC言語やJava言語と同じ個数の確保になります。
線形代数を取り扱う時はプログラムの冒頭で必ず
option
base -1 を記述してください。
記述しなければ正常な計算結果が得られません
線形代数計算でのエラーについて
線形代数の計算上で計算不能等のエラーが起きた場合はプログラムの中断は行われず
err関数にエラーコードを返すのみとなります。err関数の状態で計算の成否を確認して下さい。
MATRIX命令実行時の最初にerr関数の内容は0にリセットされます。
線形代数関連のエラー
error
69:"線形代数のエラーです、余因子が0または計算不能です"
error
70:"線形代数の配列のサイズが合いません"
線形代数の四則計算
[例]四則計算の場合
10 option base -1
20 dim dv1(2,2),dv2(2,2),dv3(2,2)
30 dv2(0,0)=4:dv2(0,1)=-2:dv2(1,0)=1:dv2(1,1)=1
40 dv3(0,0)=1:dv3(0,1)=2:dv3(1,0)=3:dv3(1,1)=4
50 matrix "dv1=dv2+dv3"
60 for y=0 to 1 : for x=0 to 1
70 print dv1(y,x);
80 next : print : next
以下の説明では40行までは既に定義しているものとして
50行の matrix
の文だけ変更した用例で説明します。(MATRIXの次の行が結果です)
加算、減算:計算の2つの配列のサイズがそれぞれ同一である必要があります。
乗算:左側の配列の列の数(x)と右側の配列の行の数(y)が一致している必要があります。
除算:2つの配列が同じサイズの正方行列である必要があります。
■加算
matrix "dv1=dv2+dv3"
5 0
4
5
■減算
matrix "dv1=dv2-dv3"
3 -4
-2
-3
■乗算
matrix "dv1=dv2*dv3"
-2 0
4
6
■除算
matrix "dv1=dv2/dv3"
-7 5
5.5
-3.5
線形代数に割り算はありませんが
割る側の行列の逆行列を左側から掛けた値を返しています。
MATRIX命令内の専用関数
[例]固有値の場合
10 option base -1
20 dim dv1(2,2),dv2(2,2)
30 dv2(0,0)=4:dv2(0,1)=-2:dv2(1,0)=1:dv2(1,1)=1
40 matrix "dv1=eigen(dv2)"
50 for y=0 to 1 : for x=0 to 1
60 print dv1(y,x);
70 next : print : next
以下の説明では30行までは既に定義しているものとして
40行の matrix
の文だけ変更した用例で説明します。(MATRIXの次の行が結果です)
■DET 与えられた行列の行列式を求めます。
matrix
"var=det(dv2)"
6
左辺は配列でなく通常の数値変数を指定します。
データを与える配列(例のdv2)は正方行列である必要があります。
■INV 与えられた行列の逆行列を求めます。
matrix
"dv1=inv(dv2)"
0.1666 0.333
-0.1666
0.666
代入する配列(例のdv1)はデータを与える配列(例のdv2)と同じサイズの正方行列である必要があります。
与えられた行列の行列式が0の場合は逆行列は存在しないので
err関数=69となって計算は行われません。(中断は行われません)
その他計算中に逆行列を使用するもの(除算、行列連立方程式)も
行列式が0になる場合はerr関数=
69となります。
■EQUAT 連立方程式の解を行列で求めます。
連立方程式の例
x+2y=4
3x+5y=9
用意するデータ(2x3)
1
2 4
3 5 9
EQUAT関数で行列の連立方程式の解を求めるプログラム
10 option base-1
20 dim dv1(2,1),dv2(2,3)
30 dv2(0,0)=1:dv2(0,1)=2:dv2(0,2)=4
40 dv2(1,0)=3:dv2(1,1)=5:dv2(1,2)=9
50 matrix "dv1=equat(dv2)"
60 for y=0 to 1
70 print dv1(y,0);
80 next
出力される解
-2
3
(x=-2,y=3)
*行列のランクが行数より少ない場合は解が求められないことがあります。
式の右辺が全て0の場合。
x-3y=0
2x-6y=0
配列でのデータ
1
-3 0
2 -6
0
出力される各文字間の相互の比率
9
3
右辺が全て0の場合は解が不能か不定になり解を求めることはできません。
しかし不定の場合、各文字間の相互の比率を求めることができます。
なのでこの場合は解ではなく各文字間の相互の比率を整数で出力して返します。
この例ではxに9を、yに3を代入して検証すると右辺と同じ0になり結果が正しいことがわかります。
この比率の場合において計算が不能の場合は err関数=
69となり計算は行われません。
使用配列のサイズについて
方程式のデータを与える配列(例のdv2)は正方行列に列の数が横に1つだけ大きなものを用意します。
一番右の列に方程式の右辺の数値が入ることになります。
解を代入する配列(例のdv1)は、列の数(x)は1で
行の数(y)はデータを与える配列の列と同じサイズに設定しておきます。
縦1列に解が並ぶ感じになります。
■EIGEN 固有値を求めます。
matrix "dv1=eigen(dv2)"
3
0
0
2
固有値は例のように配列内で対角状に配置されて返されます。
複素数には対応していませんので固有値が複素数の場合は正常でない値が返されます。
代入する配列(例のdv1)はデータを与える配列(例のdv2)と同じサイズの正方行列である必要があります。
■EVEC 固有ベクトルを求めます。
matrix "dv1=evec(dv2)"
2
1
1
1
0番目の固有値の固有ベクトルは0列目に、1番目の固有値の固有ベクトルは1列目に…という縦の並びで返されます。
代入する配列(例のdv1)はデータを与える配列(例のdv2)と同じサイズの正方行列である必要があります。
■TRANS 与えられた行列の転置行列を返します。
matrix
"dv1=trans(dv2)"
4 1
-2
1
代入する配列(例のdv1)はデータを与える配列(例のdv2)と同じサイズである必要があります。
■RANK 行列のランクをを求めます。
matrix
"var=rank(dv2)"
2
左辺は配列でなく通常の数値変数を指定します。
■UNIT 単位行列を作成して返します。
matrix "dv1=unit(2)"
1
0
0 1
正方のサイズを関数内の数値で指定します。
■INTCV 配列内のデータを整数化します。
書式:intcv(配列名,加工行指定,検査最大値,判別桁数)
例:matrix
"dv1=intcv(dv2,-1,100,0.00001)"
与えられた配列内の各値が整った整数比の形になるか調べて
可能ならば各値を整数の比率にデータに変換してその配列を返します。
整数にできなかった場合はそのまま元の値の配列を返します。(この場合
err関数=69)
整数化する範囲は配列全体と特定指定行のどちらかを指定することができます。
[人によって作られた問題などで解が整った整数になるものを整数化する]時などに使用します。
左辺:結果を代入する配列(dv1)
関数内パラメーター
配列名:整数化を試みる配列(dv2)
加工行指定:(指定は0~から)どの列を整数化するか指定します。-1を指定した場合は配列内全てが対象。
検査最大値:整数の中で基準となる最小の値が実際整数のどの数にあたるか調べていきます。
その調査の上限となる値を設定します。調査が上限まで到達して整数化の目処がたたなければ
整数化は不可と判断されます。err関数=69が返されます。
この値が大きい程整数化の可能性は高まりますが処理の負荷は大きくなります。
判別桁数:小数の桁数が多い程整数化の判定基準が厳しくなります。少ない程大雑把なものになります。
値の設定がよくわからない時は例のように
intcv(配列変数名,-1,100,0.00001)
の値を使用して下さい。
代入する配列(例のdv1)はデータを与える配列(例のdv2)と同じサイズである必要があります。
■SETTING
これは計算ではなく設定を行う関数です。
matrix
"var=setting(ret,0)"
線形代数関数の各種設定を行います。
関数の第一パラメーターに設定の種類を書きます。(この文字は""で囲う必要はありません)
[ret]
固有ベクトルの返し値を小数で返すか、整数で返すか設定します。
第二パラメーター
0:返し値を正規化された小数で返します。
1:返し値を整数で返します。(デフォルト)
左辺は意味を持たない仮の変数です。配列でなく通常の数値変数を指定して下さい。
・固有ベクトルを求める計算で収束までの反復回数、判断桁数を決める設定。
[digit]
小数が整数へ収束しているのではないかと判断するための桁数の設定。
例えば
setting(digit,3) [3はデフォルト値]なら 固有ベクトル値の 2.000567は
小数点以下で 0が3つ続いているので整数の
2に収束していると判断されます。
数が大きい程判定が厳しくなります。(下記のrep回数も大きな数が必要になる)
[rep]
QR分解で固有値を求める時に反復する回数。デフォルトで
setting(digit,3200)
回数が多い程正確な値が得られます。
---------------------------
サンプル "linear.bas"
の使い方
---------------------------
実行するとコマンド選択画面になります。
番号を入力します。
1.input 2.save 3.load 4.calc
まずは 1.input でデータを入力します
行列の列と行の数を入力していきます。
size x? (列の数の入力)
size
y? (行の数の入力)
例として2x2のサイズを入力してみましょう。
(方程式データにする時は列の数を1つ大きくします)
次にデータを入力します。
4 -2
1
1
この行列データを入力してみましょう。
右側から列の数がカウントされていきます。
0,0 ?
4
0,1 ? -2
1,0 ? 1
1,1 ?
1
入力したデータをセーブします。(行列のサイズはメモしておきましょう)
2.save
を選びます。
セーブ番号を入力します。1番にセーブしてみます。
No.1
[Enter]でセーブされました。
それでは実際に計算結果を見てみましょう。
4.calc
を選びます。
行列データ
ランク (Rank)
行列式 (det)
掛け算
(mult:行列の2乗)
の順に表示されます。
さらにデータを表示させるためにキーをタップしていきます。
逆行列
(inv)
固有値 (eigen)
固有ベクトル (evec)
のデータが表示されていきます。
最後にロードの手順を説明します。
3.load
を選びます。
ロード番号を入力します。先程の1番をロードしてみます。
No.1
行列のサイズを入力する必要があります。
先程メモしておいたサイズを入力します。
size x? 2(列のサイズの入力)
size
y? 2(行のサイズの入力)
これでロードされました。
先程の手順で計算の 4.calc を選ぶことで
各種計算結果を表示させることができます。