[2017/1/25] 表記を修正しました。
特定の基底におけるベクトルの成分と、基底の変換についてまとめました。Julia を使うと、成分表示や基底の変換が簡単に実行できます。
特に断らなければ、以下では、ベクトルは列(縦↓)ベクトルとします。列(縦)ベクトル、行(横→)ベクトルについては、こちらの解説をどうぞ。 →
【プログラマーのための数学】行列
基底, 表示 (表現, 成分)
ベクトル $\boldsymbol{x}$ が、線形独立なベクトルの組 ${\boldsymbol{v}}_1, {\boldsymbol{v}}_2, \cdots, {\boldsymbol{v}}_m $ の線形結合で表されるとします。すなわち、式で書くと
$$\boldsymbol{x} = a_1 {\boldsymbol{v}}_1 + a_2 {\boldsymbol{v}}_2 + \cdots + a_m {\boldsymbol{v}}_m$$
です。このとき、係数 $a_1,a_2, \ldots, a_m$ を、基底 $V= \{ {\boldsymbol{v}}_1, {\boldsymbol{v}}_2, \cdots, {\boldsymbol{v}}_m \}$ におけるベクトル $\boldsymbol{x}$ の 表示 (あるいは 成分 ) といいます。${\boldsymbol{v}}_1, {\boldsymbol{v}}_2, \cdots, {\boldsymbol{v}}_m$ は、基底ベクトル といいます。
表示(成分) $a_1,a_2, \ldots, a_m$ を、列ベクトル
$$\boldsymbol{a}= \begin{bmatrix} a_1 \\ a_2 \\ \cdots \\ a_m \end{bmatrix} $$
にまとめたものを、成分の 列ベクトル表示 といいます。
さて、基底ベクトルの組 $ {\boldsymbol{v}}_1, {\boldsymbol{v}}_2, \cdots, {\boldsymbol{v}}_m$ を横に並べた行列 $\tilde{V}$ を作ります。
$$\tilde{V} = \left[ {\boldsymbol{v}}_1, {\boldsymbol{v}}_2, \cdots, {\boldsymbol{v}}_m \right ] $$
すると、冒頭の式は、行列 $\tilde{V}$ とベクトル $\boldsymbol{a}$ との積で表示できます。
$$ \boldsymbol{x} = \left[ {\boldsymbol{v}}_1, {\boldsymbol{v}}_2, \cdots, {\boldsymbol{v}}_m \right ] \begin{bmatrix} a_1 \\ a_2 \\ \cdots \\ a_m \end{bmatrix} =
\tilde{V} \boldsymbol{a}$$
上式で、左から$\tilde{V}$ の逆行列を作用すれば、成分 $\boldsymbol{a}$ が求まります。 すなわち、
$$ \boldsymbol{a} = \tilde{V}^{-1} \boldsymbol{x} = \left[ {\boldsymbol{v}}_1, {\boldsymbol{v}}_2, \cdots, {\boldsymbol{v}}_m \right ]^{-1} \boldsymbol{x}$$
上式のようなベクトル・行列の算術が、Julia言語では自然に書けます。
例
基底の例として、ベクトルの組 ${\boldsymbol{v}}_1 = \begin{bmatrix} 0 \\ 1 \\ 1 \end{bmatrix}$, ${\boldsymbol{v}}_2 = \begin{bmatrix} 1 \\ 0 \\ 1 \end{bmatrix}$, ${\boldsymbol{v}}_3 = \begin{bmatrix} 1 \\ 1 \\ 0 \end{bmatrix}$ を用います。
Julia では、要素からベクトル・行列を作るのに [ ]
を用います。 [ ]
の中では、セミコロン ;
が、縦ベクトルの要素の区切りです。
julia> v1 = [0;1;1]; v2 = [ 1; 0; 1]; v3 = [1; 1; 0]
3-element Array{Int64,1}:
1
1
0
まず、基底ベクトルが線形独立であるかどうかを確かめます (確認は大事)。基底ベクトルからなる行列の階数 rank
をとって、基底ベクトルの数と等しいなら線形独立です。 小さいなら線形従属です。
julia> rank( [ v1 v2 v3 ] )
3
[ v1 v2 v3 ]
は、縦ベクトル v1, v2, v3
を横に並べた行列です。
[ ]
の中では、空白「
」が、横ベクトルの要素の区切りです。rankは落ちていないですね。
では、ベクトル $\boldsymbol{x} = \begin{bmatrix} 1 \\ 1 \\ 2 \end{bmatrix}$ の、基底 $V= \{ {\boldsymbol{v}}_1, {\boldsymbol{v}}_2, {\boldsymbol{v}}_3 \}$ における表示を求めてみます。
julia> x = [ 1.0 ; 1.0 ; 2.0 ]
3-element Array{Float64,1}:
1.0
1.0
2.0
行列 $M$ について、$M^{-1} x$ を計算するには、Julia 言語では M \ x
と書きます。
julia> a = [ v1 v2 v3 ] \ x
3-element Array{Float64,1}:
1.0
1.0
-0.0
すなわち、基底 $V$ におけるベクトル$\boldsymbol{x}$の表示は $\boldsymbol{a} = \begin{bmatrix} 1 \\ 1 \\ 0 \end{bmatrix}$ です。 検算します。
julia> [ v1 v2 v3 ] * a
3-element Array{Float64,1}:
1.0
1.0
2.0
julia> ans - x
3-element Array{Float64,1}:
0.0
0.0
0.0
よいですね。 ※ Julia言語のコマンドライン (REPL)では、ans
は、最後に計算した結果です。
別のベクトル $\boldsymbol{y} = \begin{bmatrix} 2 \\ 2 \\ 2 \end{bmatrix}$ の基底$V$における表示を求めます。
julia> y = [ 2.0 ; 2.0 ; 2.0 ]
3-element Array{Float64,1}:
2.0
2.0
2.0
ベクトル $\boldsymbol{x}, \boldsymbol{y}$ の表示を、一度に求めてみます。すなわち、$\begin{bmatrix}\boldsymbol{v}_1, \boldsymbol{v}_2, \boldsymbol{v}_3 \end{bmatrix}^{−1} \begin{bmatrix} \boldsymbol{x}, \boldsymbol{y} \end{bmatrix}$ を計算します。
julia> [ v1 v2 v3 ] \ [ x y ]
3x2 Array{Float64,2}:
1.0 1.0
1.0 1.0
-0.0 1.0
よって、基底 $\{ {\boldsymbol{v}}_1, {\boldsymbol{v}}_2, {\boldsymbol{v}}_3 \}$ におけるベクトル $\boldsymbol{y}$の表示は $\begin{bmatrix} 1 \\ 1 \\ 1 \end{bmatrix}$ です。
一度に検算してみます。
julia> [ v1 v2 v3 ] * [ [1.0; 1.0; 0.0 ] [1.0; 1.0; 1.0] ]
3x2 Array{Float64,2}:
1.0 2.0
1.0 2.0
2.0 2.0
julia> ans - [x y]
3x2 Array{Float64,2}:
0.0 0.0
0.0 0.0
0.0 0.0
部分空間
ベクトル $\boldsymbol{x}$ は、基底 $\{ \boldsymbol{v}_1, \boldsymbol{v}_2 \}$ を用いても表示できます。
まずは、基底 $\{ \boldsymbol{v}_1, \boldsymbol{v}_2 \}$の線形独立の確認から
julia> rank( [ v1 v2 ])
2
では、基底 $\{ \boldsymbol{v}_1, \boldsymbol{v}_2 \}$における$\boldsymbol{x}$の表示を求めます。
julia> [ v1 v2 ] \ x
2-element Array{Float64,1}:
1.0
1.0
julia> [ v1 v2 ] * ans
3-element Array{Float64,1}:
1.0
1.0
2.0
すなわち、基底 $\{ \boldsymbol{v}_1, \boldsymbol{v}_2 \}$ に対するベクトル$\boldsymbol{x}$の表示は $\begin{bmatrix} 1 \\ 1 \end{bmatrix}$ です。
ところで、$[ \boldsymbol{v}_1, \boldsymbol{v}_2 ] = \begin{bmatrix} 0 & 1 \\ 1 & 0 \\ 1 & 1 \end{bmatrix}$ は正方行列ではありません (逆行列は存在しません)。 Julia 言語の A \ x
は、逆行列を左から作用する操作よりも広く、連立方程式を解く操作を行うわけです。
さて、ベクトル $\boldsymbol{y}$ は、基底 $\{ \boldsymbol{v}_1, \boldsymbol{v}_2 \}$ の線形結合では表示できません。ですが、Julia 言語の A \ x
は、線形結合で表せない場合でも (例外を吐いたりせず) 何らかの数字を出力します。
julia> [ v1 v2 ] \ y
2-element Array{Float64,1}:
1.33333
1.33333
julia> [ v1 v2 ] * ans
3-element Array{Float64,1}:
1.33333
1.33333
2.66667
やはり、ベクトル $\boldsymbol{y}$ に戻りません (検算が大事です)。
Julia言語マニュアルの標準関数 A \ B
を読むと、 A \ x
は、A
が正方行列ではない場合は、最小二乗ノルムを与える解を出力すると書いてあります。上の場合に即せば、$A (a_1 {\boldsymbol{v}}_1 + a_2 {\boldsymbol{v}}_2 ) - \boldsymbol{x}$ の絶対値 (二乗ノルム)が最小となる数 $ \begin{bmatrix} a_1 \\ a_2 \end{bmatrix}$ が出力されます。ベクトル $\boldsymbol{x}$が、線形結合で表される場合には、これが、基底 ${ \boldsymbol{v}_1, \boldsymbol{v}_2 }$における表示と一致するのです。
基底変換
ベクトル$\boldsymbol{x}$の基底 $V = \{ {\boldsymbol{v}}_1, {\boldsymbol{v}}_2, \cdots, {\boldsymbol{v}}_m \}$ における表示 $\boldsymbol{a}$を、基底 $W = \{ {\boldsymbol{w}}_1, {\boldsymbol{w}}_2, \cdots, {\boldsymbol{w}}_m \}$ における表示 $\boldsymbol{b}$ に変換します。
$$
\begin{align}
\tilde{V} & = \left[ {\boldsymbol{v}}_1, {\boldsymbol{v}}_2, \cdots, {\boldsymbol{v}}_m \right ] \newline
\tilde{W} & = \left[ {\boldsymbol{w}}_1, {\boldsymbol{w}}_2, \cdots, {\boldsymbol{w}}_m \right ] \newline
\boldsymbol{x} & = \tilde{V} \boldsymbol{a}
= \tilde{W} \boldsymbol{b}
\end{align}
$$
末尾の式から
$$\boldsymbol{b} = \tilde{W}^{-1} \tilde{V} \boldsymbol{a}$$
の計算で $ \boldsymbol{b} $ が求まります。
例として、ベクトルの組 ${\boldsymbol{w}}_1 = \begin{bmatrix} 1 \\ 1 \\ -1 \end{bmatrix}$, ${\boldsymbol{w}}_2 = \begin{bmatrix} 1 \\ -1 \\ 1 \end{bmatrix}$, ${\boldsymbol{w}}_3 = \begin{bmatrix} -1 \\ 1 \\ 1 \end{bmatrix}$ を、別の基底ベクトルとします。
julia> w1 = [1;1;-1]; w2 = [ 1; -1; 1]; w3 = [-1; 1; 1]
3-element Array{Int64,1}:
-1
1
1
例によって、線形独立の確認から
julia> rank( [w1 w2 w3 ] )
3
julia> b = [ w1 w2 w3 ] \ ( [ v1 v2 v3 ] * a )
3-element Array{Float64,1}:
1.0
1.5
1.5
julia> [ w1 w2 w3 ] * b
3-element Array{Float64,1}:
1.0
1.0
2.0
julia> ans - x
3-element Array{Float64,1}:
0.0
0.0
0.0
表示 $\boldsymbol{b}$ からベクトル $\boldsymbol{x}$ が得られました。