Pythonによるベクトルの合計の計算

ベクトルの定義と和の計算

リストによる定義と計算

Pythonでベクトルの計算をするときは、NumpyやSympyモジュールを使うことが一般的で実用的ではありませんが、計算の流れを知るためリストによる表現からはじめます。ここでは、2つのベクトルv_a=(1, 2, 3)、v_b=(4, 5, 6)を定義して、2つのベクトルの和を求めます。それでは、まずリストを定義します。

# ベクトルの定義
v_a = [1, 2, 3]
v_b = [4, 5, 6]

ベクトルの和は、要素同士の合計なので、はじめに合計を計算するためのベクトルv_s1を空のリストとして定義し、for文で各要素の合計を計算した結果をappendメソッドでリストに追加していきます。

# リストによるベクトルの和 ~ 最も単純な方法
v_s1 = []
for i in range(len(v_a)):
    v_s1.append(v_a[i]+v_b[i])
v_s1

結果は[5, 7, 9]となり、うまく計算することができました。しかし何ともさえない方法なので、zip関数を使って、2つのリストから同時に要素を取り出す方法を試してみます。

# ベクトルの和 ~ PythonらしくZipを使う方法
v_s2 = []
for x, y in zip(v_a, v_b):
    v_s2.append(x+y)
v_s2

結果は、同じです。少しPythonらしくなりましたが、さらにリスト内包表記を使って計算します。

# リスト内包表記によるベクトルの和
[x + y for x,y in zip(v_a,v_b)]

1行で計算できるのでとても便利ですが、リスト内包表記は2つのリストを扱うとわかりにくくなるのが難点です。同様にlambda式でも計算することができます。

# lambda式によるベクトルの和
list(map(lambda x,y:x+y,v_a,v_b))

結果はいずれも同じです。リストを使った計算はPythonのプログラミングの練習にはなりますが手間がかかるので、Numpyを使うのが一般的です。

Numpyによる定義と計算

Numpyモジュールの配列にはndarrayとmatrixの2つの形式があり、標記の仕方が異なります。まず、一般的なndarrayからです。ndarrayにはベクトル演算という機能があり、同じサイズの配列の算術演算では、同位要素(同じ場所の要素)ごとに計算されます。 ndarray はN-dimensional array の略となっており、N次元配列という意味合いがあります。

# Numpyのインポートと、ndarrayによるベクトルの定義
import numpy as np
na_a = np.array([1, 2, 3])
na_b = np.array([4, 5, 6])
na_a + na_b

結果は、array([5, 7, 9])となります。次に、matrixによる方法です。ベクトルの定義が数値の配列なのに('1 2 3')と表現するところに注意が必要です。

# Numpyのmatrixによるベクトルの定義
nm_a = np.matrix('1 2 3')
nm_b = np.matrix('4 5 6')
nm_a + nm_b

結果はmatrix([[5, 7, 9]])となり、結果hmatrixの形式で帰されます。Numpyは数値計算用のモジュールで、ベクトル計算も簡単になりますが、これだけならExcelの方が手っ取り早いように思われます。Pythonのすごさはここから先になります。

Sympyによる定義と計算

SympyはPython library for symbolic mathematicsといわれるように、代数を扱うことができます。はじめに、Jupyrt NotebookでSympyをインポートするときには、併せてsympy.init_printing()を追加します。このことにより、セルに数字がきれいに(Latexにより)表示されます。次にsympy.Matrixによりベクトルを定義し、合計します。Pythonは変数を明示的に定義しなくてもよい仕様になっていますが、Sympyでは、s_a、s_bのようにsympy.symbolsとして定義する必要があります。

# Sympyのインポートと、Matrixによるベクトルの定義
import sympy
sympy.init_printing()
s_a, s_b = sympy.symbols('s_a s_b')
s_a = sympy.Matrix([1, 2, 3])
s_b = sympy.Matrix([4, 5, 6])
s_a + s_b

結果は次の通り縦のベクトルで帰されます。

Sympyによるベクトルの数値計算
Sympyによるベクトルの数値計算

これだけだと、わざわざ変数を定義するだけ手間がかかるだけですが、Sympyのすごさは、次のような代数計算ができることです。

#sympyの代数計算によるベクトルの和
a_x, a_y ,a_z, b_x, b_y,b_z = sympy.symbols('a_x,a_y,a_z,b_x,b_y,b_z')
sv_a = sympy.Matrix([a_x, a_y,a_z])
sv_b = sympy.Matrix([b_x, b_y,b_z])
sv_s= sv_a+sv_b
sv_s

ここでは、sv_sで2つのベクトルの和を計算しており、その中身は変数で格納されています。

Sympyによるベクトルの代数計算
Sympyによるベクトルの代数計算

次に、変数が格納されているベクトルにsubsメソッドで数値をしてすると、前例のように計算することができます。

#sympyの代数計算に数値を代入
sv_s.subs([(a_x, 1), (a_y, 2), (a_z, 3), (b_x, 4), (b_y, 5), (b_z, 6)])

結果は同じように縦のベクトルで帰されます。