ベクトルとスカラー

ベクトルとスカラー

【線型代数01】スカラー

 ベクトルという新しい概念を導入するにあたって、ベクトルと区別するために普段使っている実数を スカラー とよぶことにします(場合によっては複素数もスカラーと考えることもできますが、当面はスカラーは実数であると考えて差支えありません)。下の図のような数直線を考えて、原点から任意のスカラーまで矢印を引いてみると、スカラーの符号によって矢印の方向は 2 種類あります。
 
Python3 scalar line 2
 
 スカラー同士の加算(足し算)は、この矢印をつなぎ合わせて求めることができます。たとえば、$-5$ に $+3$ を加える場合、下の図のように矢印をつないで $-2$ を得ることができます。
 
Python 数直線 scalar line

【線型代数02】ベクトル

 数直線上 (1次元) で定義されていた演算を $n$ 次元空間の演算に拡張するために ベクトル (vector) を導入します。2次元ベクトルはスカラーのペアとして定義されます:
 
\[\boldsymbol{v}=\begin{bmatrix}v_1\\v_2\end{bmatrix}\tag{1}\]
 ベクトルは太字で $\boldsymbol{v}$ と書くか、あるいは文字の上に矢印を添えて $\vec{v}$ のように表します。ベクトルに含まれる個々のスカラー $v_1,\ v_2$ をベクトルの成分といいます。(1) を横書きで $(v_1,v_2)$ と書くこともあります(高校数学ではこの書き方が一般的です)。$xy$ 平面に図示するときは、任意に選んだ始点から $x$ 方向に $v_1$, $y$ 方向に $v_2$ だけ進んだ所を終点とし、始点と終点を結んだ矢印として表現します。
 
平面ベクトル 2D-vector
 
 始点の選び方は自由なので、上の図に描かれている三本のベクトルはすべて同じベクトル $\boldsymbol{v}$ とみなします。特に始点を原点 $(0,0)$ にとるときは、ベクトルの成分は $(x,y)$ 座標に一致するので、これを 位置ベクトル (position vector) とよびます (下図)。
 
位置ベクトル (position vector)

ベクトルの和と差

 ベクトルの和は成分同士の足し算として定義されます。
 
\[\begin{bmatrix}v_1\\v_2\end{bmatrix}+\begin{bmatrix}w_1\\w_2\end{bmatrix}=\begin{bmatrix}v_1+w_1\\v_2+w_2\end{bmatrix}\tag{2}\]
 たとえば、ベクトル $\begin{bmatrix}3\\2\end{bmatrix}$ と $\begin{bmatrix}-1\\3\end{bmatrix}$ を加えると
 
\[\begin{bmatrix}3\\2\end{bmatrix}+\begin{bmatrix}-1\\3\end{bmatrix}=\begin{bmatrix}2\\5\end{bmatrix}\tag{3}\]
となりますが、これは下図にあるように、2 つの矢印をつないで新しい矢印をつくることを意味しています。
 
平面ベクトルの足し算 plane vector addition
 
 和を定義したので、自動的に差をつくるルールも決まります。
 式 (3) を少し変形すると
 
\[\begin{bmatrix}2\\5\end{bmatrix}-\begin{bmatrix}3\\2\end{bmatrix}=\begin{bmatrix}-1\\3\end{bmatrix}\tag{4}\]
となります。つまり、ベクトルの差は成分ごとの差をとってつくります:
 
\[\begin{bmatrix}v_1\\v_2\end{bmatrix}-\begin{bmatrix}w_1\\w_2\end{bmatrix}=\begin{bmatrix}v_1-w_1\\v_2-w_2\end{bmatrix}\tag{5}\]
 上の図で見ると、幾何学的には引くほうのベクトルの終点から、引かれるベクトルの終点まで伸ばした矢印として表されます。

ベクトルとスカラーの演算

 ベクトル $\boldsymbol{v}$ とスカラー $k$ の演算は積のみが定義されていて、$k\boldsymbol{v}$ はベクトル $\boldsymbol{v}$ のすべての成分を $k$ 倍することを意味します。
 
\[k\begin{bmatrix}v_1\\v_2\end{bmatrix}=\begin{bmatrix}kv_1\\kv_2\end{bmatrix}\tag{6}\]
 幾何学的には矢印の長さを $k$ 倍にします(下図)。
 
ベクトルとスカラーの積 vector-scalar product
 
 負のスカラーをベクトルに掛けると向きを反転させます。
 特に $-1$ を掛けたときは、長さは同じで反対方向を向くベクトルとなります。
 
負のスカラーを掛けてベクトルの向きを反転 minus vector

n次元ベクトル

 以上の議論は一般の $n$ 次元ベクトルにもそのまま拡張できます。
 $n$ 次元ベクトルは $n$ 個のスカラーで構成されます:
 
\[\boldsymbol{v}=\begin{bmatrix}v_1\\v_2\\ \vdots \\v_n\end{bmatrix}\]
 和と差、スカラー倍は
 
\[\begin{bmatrix}v_1\\v_2\\ \vdots \\v_n\end{bmatrix}\pm\begin{bmatrix}w_1\\w_2\\ \vdots \\w_n\end{bmatrix}=\begin{bmatrix}v_1\pm w_1\\v_2\pm w_2\\ \vdots \\v_n\pm w_n\end{bmatrix},\quad k\begin{bmatrix}v_1\\v_2\\ \vdots \\v_n\end{bmatrix}=\begin{bmatrix}kv_1\\kv_2\\ \vdots \\kv_n\end{bmatrix}\]
によって定義されます。

【線型代数03】NumPyの一次元配列演算

 SciPy および NumPy の公式ドキュメントでは、1 次元配列 (1-D array) のことを ベクトル(vector) と表現しています。実際、1 次元配列を受け取ってベクトル演算を実行するために、あらゆる種類の関数やメソッドが用意されています。しかし、演算子の使い方については、いくつかの点で注意が必要です。
 ベクトルの加算・減算は、成分ごとの加算・減算として定義されています。
 この操作は配列の演算規則と同じなので、そのまま適用できます。

# 1d_ndarray_calculation

# In[1]

import numpy as np

# ベクトルを定義
v = np.array([10, 20, 30])
w = np.array([2, 4, 6])

print("v + w : {}".format(v + w))
print("w - v : {}".format(w - v))

# v + w : [12 24 36]
# w - v : [8 16 24]

 ベクトルの積は内積と外積の 2 種類が定義されています。ただし、NumPy の * 演算子による配列積は要素同士を掛け算する直積で、これは内積・外積のいずれとも異なる演算です(内積と外積はメソッドもしくは関数として用意されています)。

# In[2]

# 配列積
print(v * w)

# [ 20  80 180]

 ベクトル同士の除算は定義されていませんが、/ 演算子で配列同士の除算を実行すると成分ごとに除算して返します。

# In[3]

# 配列除算
print(v/w)
# [5. 5. 5.]

 ベクトル $\boldsymbol{v}$ とスカラー $k$ の積は、ベクトルを構成するすべての成分(要素)を $k$ 倍する操作として定義されています。この操作はスカラーと 1 次元配列でも同じです。

# In[4]

# ベクトルを定義
v = np.array([1, 2, 3])

# ベクトルvにスカラー10を掛ける
print(10 * v)

# [10 20 30]

 ベクトルとスカラーの間で加算・減算は定義されていませんが、配列 v にスカラー k を加えると、配列のすべての要素に k を加えます。

# In[5]

# vにスカラー1を加える
print(v + 1)

# [2 3 4]

 これは配列のブロードキャスト機能による演算結果です。ベクトルとスカラーの足し算を行なっているのではなく、すべての要素が 1 であるベクトルを作って、ベクトル同士の足し算を行なっています。

【線形代数Topic01】テンソル演算

 厳密には、ベクトル1 階のテンソル として定義されます。テンソルとはスカラー、ベクトル、行列をすべて含む汎用概念です。NumPy の配列はテンソルに近い構造で設計されていて、関数やメソッドの中にはテンソル演算として定義されているものがいくつかあります。
 
 おそらく無用な混乱を避けるためだと思われますが、公式ドキュメントではテンソルという用語はあまり使われていません。そのため、ベクトルの内積を計算すると説明されている関数に行列 (2次元配列) を渡すと、内積とも行列積とも異なる不可解な演算結果を返したりするので、困惑することがしばしばあります。
 
 テンソルは高度な概念ですが、使いこなせばとても効率的なコードを書くことができます。機械学習用ライブラリとして有名な TensorFlow も、その名が示すように Tensor (テンソル) 演算をベースに設計されています。