ベクトルと行列
リストはベクトルと行列の表現として用いることができます。特に、数値からなるリストでは、多くの算術演算ができます。さらに、幾何学要素の座標は数値のリストとして読み出されます。たとえば、
A
が点のラベルであるとすると
A.xy
は2つの数
x
と
y
を点の座標として返します。同様に、
A.homog
は3つの数のリスト:点の同次座標を返します。いくつかの算術演算は、これらの座標ベクトルを直接計算することができます。
ベクトルと行列の定義
どのようなリストも、オブジェクトのベクトルとみなすことができますが、数のベクトルには特に興味があります。そのようなベクトルは"数ベクトル" と呼ばれます。あるリストが数ベクトルかどうかは
isnumbervector(<expr>)
演算子によって確かめられます。
もし、リストの要素がまたリストであり、しかもそれらがすべて同じ長さであれば、そのようなリストは
行列と呼ばれます。あるリストが行列であるかどうかは、
ismatrix(<expr>)
. 演算子によって確かめられます。さらに、行列の個々の要素がすべて数であれば、この行列は数行列と呼ばれます。ある行列が数行列かどうかは
isnumbermatrix(<expr>)
演算子によって確かめられます。行列の要素は同じ長さのベクトルとも考えられ、このようなベクトルは行列の行ベクトルです。したがって、行列が
n 個の、長さ
mの行ベクトルからなるならば、
n ×
m 行列です。
和と積
数のリストに対する四則演算は
算術演算子 の節で説明してあります。経験則として、このレベルの計算はCindyScript 上で数学的に合理的になされます。たとえば、
A
と
B
が数のリストであれば、
(A+B)/2
は2つのベクトルの中点を計算します。
リストが同じ形を持つときは、加法と減法ができます。これは、リストが同じ長さで、いくつかの要素がやはり同じようなリストであれば、和・差に対応する要素は同じ形になるということです。
リストのかけ算は、数学的に意味があれば許されます。次の表は、かけ算が許される場合についてまとめてあります。
要素 1 | 要素 2 | 結果 | 意味
|
数 | 数 | 数 | 通常のかけ算
|
数 | 長さ r のベクトル | 長さ r のベクトル | ベクトルの実数倍
|
長さ r のベクトル | 数 | 長さ r のベクトル | ベクトルの実数倍
|
長さ r のベクトル | 長さ r のベクトル | 数 | ベクトルの内積
|
n × r 行列 | 長さ r のベクトル | 長さ n のベクトル | 行列×列ベクトル
|
長さ n のベクトル | n × r 行列 | 長さ r のベクトル | 行ベクトル × 行列
|
n × r 行列 | r× m 行列 | n × m 行列 | 行列の積
|
積、和、最大と最小
総和演算子: sum(<list>)
説明: この演算子は要素の総和を求めます。要素は数か、それ自身がリスト(またはベクトル、行列)か、文字列です。
例:
式: | 結果:
|
sum(1..10) | 55
|
sum([4,6,2,6]) | 18
|
sum([[3, 5], [2, 5], [5, 6]]) | [10, 16]
|
sum(["h","e","ll","o"] | "hello"
|
たとえば、次のコードで示されるように、sum 演算子は平均を計算する関数を定義するのに使えます。
average(x) := sum(x)/length(x)
この関数は数のリストと同様に、ベクトルや行列の平均も計算します。
総和演算子: sum(<list>,<expr>)
説明: この演算子はsum演算子と同様ですが、各要素に
<expr>
を実行し、その結果の総和を求めます。実行変数は例によって
#
です。
例:
次の式で、100以下の自然数の平方の和を求めることができます。
式: | 結果:
|
sum(1..100,#2) | 338350
|
すこし神秘的な結果があります。
式: | 結果:
|
sum(1..10,#2) | 385
|
sum(1..100,#2) | 338350
|
sum(1..1000,#2) | 333833500
|
sum(1..10000,#2) | 333383335000
|
総和演算子: sum(<list>,<var>,<expr>)
説明: この演算子は実行変数が
<var>
である以外は先ほどの演算子と同じです。
積演算子: product(<list>)
説明: この演算子は要素をすべて掛け合わせます。要素は数であることが前提です。
例:
この演算子を使って、たとえば、次のコードのように、階乗を計算する関数を定義することができます。
積演算子: product(<list>,<expr>)
説明: この演算子は product 演算子と同様ですが、各要素に
<expr>
を実行し、その結果をすべて掛け合わせます。実行変数は例によって
#
です。
積演算子: product(<list>,<var>,<expr>)
説明: この演算子は実行変数が
<var>
である以外は先ほどの演算子と同じです。
最大値演算子: max(<list>)
説明: この演算子は要素の最大値を求めます。
例:
式: | 結果:
|
max([4,2,6,3,5]) | 6
|
最大値演算子: max(<list>,<expr>)
この演算子は
max(<list>)
と同様ですが、
<expr>
をリストのすべての要素に実行した結果の最大値を与えます。実行変数は例によって
#
です。
最大値演算子: max(<list>,<var>,<expr>)
説明: この演算子は実行変数が
<var>
である以外は先ほどの演算子と同じです。
最小値演算子: min(<list>)
説明: この演算子は要素の最小値を求めます。
例:
式: | 結果:
|
min([4,2,6,3,5]) | 2
|
最小値演算子: min(<list>,<expr>)
この演算子は
min(<list>)
と同様ですが、
<expr>
をリストのすべての要素に実行した結果の最大値を与えます。実行変数は例によって
#
です。
最小値演算子: min(<list>,<var>,<expr>)
説明: この演算子は実行変数が
<var>
である以外は先ほどの演算子と同じです。
ベクトルと行列の演算
この節の初めの方で述べたように、ベクトルと行列には和と積の他にもいくつかの演算があります。
行列の次数: matrixrowcolum(<matrix>)
説明: 引数が行列であれば、この演算子は行と列の数を、2つの数の要素からなるリストとして返します。
例:
式: | 結果:
|
matrixrowcolumn([[1,2],[3,2],[1,3],[5,4]]) | [4,2]
|
転置行列: transpose(<matrix>)
説明: 引数が行列であれば、この演算子は転置行列を返します。転置行列では行と列が入れ替わります。
例:
式: | 結果:
|
transpose([[1,2],[3,2],[1,3],[5,4]]) | [[1,3,1,5],[2,2,3,4]]
|
transpose([[1],[3],[1],[5]]) | [[1,3,1,5]]
|
transpose([[1,3,1,5]]) | [[1],[3],[1],[5]]
|
行列の行抽出: row(<matrix>,<int>)
説明: 引数が行列であれば、この演算子は
<int>
番目の行をベクトルとして返します。
例:
式: | 結果:
|
row([[1,2],[3,2],[1,3],[5,4]],2) | [3,2]
|
行列の列抽出: column(<matrix>,<int>)
説明: この演算子は、引数が行列であれば index
<int>
番目の列をベクトルとして返します。
例:
式: | 結果:
|
column([[1,2],[3,2],[1,3],[5,4]],2) | [2,2,3,4]
|
小行列: submatrix(<matrix>,<int1>,<int2>)
説明: この演算子は、第1引数が行列であれば、第
<int1>
列と 第
<int2>
行を削除した小行列を返します。
例:
式: | 結果:
|
submatrix([[1,2,4],[3,2,3],[1,3,6],[5,4,7]],2,3) | [[1,4],[3,3],[5,7]]
|
ベクトルから行列への変換: rowmatrix(<vector>)
説明: この演算子は、第1引数がベクトルであれば、このベクトルを1行とする行列を返します。
例:
式: | 結果:
|
rowmatrix([1,2,3,4]) | [[1,2,3,4]]
|
ベクトルから行列への変換: columnmatrix(<vector>)
説明: この演算子は、第1引数がベクトルであれば、このベクトルを1列とする行列を返します。
例:
式: | 結果:
|
columnmatrix([1,2,3,4]) | [[1],[2],[3],[4]]
|
零ベクトルの生成: zerovector(<int>)
説明: 長さが
<int>
の零ベクトルを作ります。
零行列の生成: zeromatrix(<int1>,<int2>)
説明: <int1>
行
<int2>
列の零行列を作ります。
線形代数
リストはベクトルまたは行列としても使われますので、いくつかの算術演算は線形代数としてリストに適用できます。
正方行列の行列式: det(<matrix>)
説明: この演算子は、正方行列(行と列の長さが同じである行列)の行列式を計算します。幾何学的な目的のために、行列式はとても役に立つことを銘記してください。たとえば、3点の同次座標(homogenous coordinate)からできる 3 × 3 行列の行列式が0のときに限り、その3点は共線(collinear)になります。行列式の符号は、3点の相対的な方向に関する情報を持っています。
幾何学演算子 の節に、関数
area(<vec1>,<vec2>,<vec3>)
と
det(<vec1>,<vec2>,<vec3>)
の説明があります。いずれも行列式を変形したもので、特に幾何学で有用であり、一般的な行列式よりもやや性能のよい関数です。
ベクトルの大きさ: |<vec>|
説明: ベクトルを2本の縦線
|…|
で挟むと、ベクトルの大きさを表します。この演算子は実数や複素数にも適用できて、その絶対値を返します。
2つのベクトルの距離: |<vec1>,<vec2>|
説明: 同じ長さの2つのベクトルを2本の縦線
|…|
で挟むと、ベクトル間の距離を計算します。
ベクトルの距離: dist(<vec1>,<vec2>)
説明: この演算子は、2つのベクトル間の距離を計算し、数として返します。この演算子も幾何学では非常に有用です。
エルミート内積: hermiteanproduct(<vec1>,<vec2>)
説明: この演算子は、2つのベクトルのエルミート内積を返します。それは、内積 <vec1>*<vec2>と似ていますが、2番目のベクトルは掛けられる前に、共役複素数にされます。特に、
hermiteanproduct(a,a)
は常に非負です。
例:
次のコードは、内積とエルミート内積の違いを示します。
a=[2+3*i,1-i];
println(hermiteanproduct(a,a));
println(a*a);
結果は次の通り。
正方行列の逆行列: inverse(<matrix>)
説明: この演算子は、正方行列の逆行列を計算します。もし、行列が正方行列でないか、逆行列を持たない場合は、未定義のオブジェクトを返します。逆行列は、1次方程式
Ax=b を解くときに役に立ちます。しかし、
A を変形するより、
linearsolve
演算子を使う方がよいでしょう。
余因子行列: adj(<matrix>)
説明: この演算子は、正方行列の余因子行列を計算します。逆行列が存在する行列においては、余因子行列は逆行列に行列式を掛けたものです。 逆行列と異なり、余因子行列はいつでも存在します。
固有値: eigenvalues(<matrix>)
説明: この演算子は、正方行列の固有値を計算します。結果は値のリストとして返されます。n次の正方行列からはn個の固有値を返します。実数の行列であっても、固有値は複素数の範囲で求めるのが普通です。
例:
m1=[[1,1,0],[0,1,0],[0,0,.5]];
println(eigenvalues(m1));
m2=[[1,1,0],[-1,1,0],[0,0,.5]];
println(eigenvalues(m2));
結果は次の通り:
[1,1,0.5]
[1 + i*1,1 - i*1,0.5]
固有ベクトル: eigenvectors(<matrix>)
説明: この演算子は、正方行列の固有ベクトルの基底を計算します。結果としてベクトルのリストを返します。 このリストの順序は、
eigenvalues
演算子における固有ベクトルの順序と同じです。
警告: もし、行列が対角化可能でない場合は、この結果は意味がありません。
1次方程式の解: linearsolve(<matrix>,<vector>)
または: linearsolve(<matrix>,<matrix>)
説明: 演算子
linearsolve(A,b)
は、方程式
Ax=b の解
x を計算します。 行列
A は正方行列で逆行列を持たなければなりません。
b は
n 次のベクトルか、
n 行の行列です。
A が逆行列を持たないか、次数が合わない場合は未定義値を返します。
例:
m=[[1,1,0],[0,1,0],[0,1,1]];
x=linearsolve(m,[2,3,4]);
println(x);
println(m*x);
結果は次の通りです。:
高度な幾何学操作
3次元の凸多面体を作る: convexhull3d(<list of vectors>)
説明: この関数は、3次元ベクトルのリストを与えると凸多面体を作ります。戻り値は2つのリストからなるのペアです。第1の要素は凸多面体の頂点、第2の要素は面です。それぞれの面は第1要素の頂点によって与えられます。
例: 次の点のリストは、立方体の頂点と中心を示すリストです。
[[1,1,1],[1,1,-1],[1,-1,1],[1,-1,-1],[-1,1,1],[-1,1,-1],[-1,-1,1],[-1,-1,-1],[0,0,0]]
このリストに convexhull3d 関数を適用すると、次の出力を得ます。
[
[[1,1,1],[1,1,-1],[1,-1,1],[1,-1,-1],[-1,1,1],[-1,1,-1],[-1,-1,1],[-1,-1,-1]],
[[6,5,1,2],[3,1,5,7],[3,4,2,1],[8,7,5,6],[8,6,2,4],[8,4,3,7]]
]
convexhull関数が、内部の点が削除された凸多面体をうまく取り扱うことができることを示しています。
次の図は
convexhull3d(...)
関数を用いて作りました。これは4次元多面体(600 セル) を3次元空間に表示したものです。
注意: 上図は CindyScript を用いて描いています。