LoginSignup
1
2

More than 5 years have passed since last update.

[Julia] 特定の基底におけるベクトルの表示を求める + 基底変換

Last updated at Posted at 2016-05-10

[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}$ が得られました。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2