PythonのNumpyを使った連立方程式の解法

Numpyライブラリは、行列のクロスやドット積、サインやコサイン値の求め方、フーリエ変換、図形操作など、さまざまな数学/科学的な操作を行うことができる。Numpyとは、「Numerical Python」の略語表記です。

今回は、PythonのNumpyライブラリを使って連立一次方程式を解く方法を紹介します。

連立一次方程式とは?

ウィキペディアでは、連立一次方程式を次のように定義しています。

数学において、連立一次方程式(れんりついちじゅうほうていしき)とは、同じ変数群を含む2つ以上の連立方程式を集めたものである。

連立一次方程式を解く最終的な目的は、未知変数の値を求めることである。以下は、2つの未知変数 xy を持つ連立一次方程式の例である。

式1:

4x  + 3y = 20
-5x + 9y = 26


上の連立方程式を解くには、変数 xy の値を求めなければならない。このような連立方程式を解くには、変数の消去法、クレイマーの法則、行数削減法、行列解法など、複数の方法があります。今回は、行列解法を取り上げます。

行列解法では、解くべき連立一次方程式を行列 AX = B の形で表現します。例えば、式1を行列の形で表すと以下のようになる。

A = [[ 4   3]
     [-5   9]]


X = [[x]
     [y]]


B = [[20]
     [26]]


式 1 の変数 xy の値を求めるには、行列 X の値を求める必要がある。そのためには、以下のように行列 A の逆行列と行列 B の内積をとればよい。

X = inverse(A).B


行列の逆行列の求め方に慣れていない方は、このリンクを見て、手動で行列の逆行列を求める方法を理解しましょう。行列のドットプロダクトを理解するには、こちらの記事をご覧ください。

Numpyで連立一次方程式を解く

前節から、連立一次方程式を解くには、行列の反転と行列の内積の2つの演算を行う必要があることがわかった。PythonのNumpyライブラリはこの2つの演算をサポートしています。Numpyライブラリをまだインストールしていない場合は、以下の pip コマンドでインストールすることができます。

$ pip install numpy


それでは、Numpyライブラリを用いて連立一次方程式を解く方法を見てみましょう。

inv()メソッドとdot()メソッドの使い分け

まず、前節で定義した行列 A の逆行列を求めます。

まず、Pythonで行列 A を作成しよう。行列を作成するには、Numpyモジュールの array メソッドを使用します。行列はリストのリストと考えることができ、それぞれのリストが1つの行を表している。

以下のスクリプトでは、 m_list という名前のリストを作成し、さらに [4,3][-5,9] という2つのリストを格納しています。これらのリストは、行列 A の 2 つの行を表します。Numpyで行列 A を作成するには、以下のように m_listarray メソッドに渡します。

import numpy as np


m_list = [[4, 3], [-5, 9]]
A = np.array(m_list)


行列の逆行列を求めるには、行列をNumpyモジュールの linalg.inv() メソッドに渡します。

inv_A = np.linalg.inv(A)


print(inv_A)


次のステップは、行列 A の逆行列と行列 B の内積を求めることです。ここで重要なことは、行列の内積は、行列の次元が等しい場合、つまり、左の行列の列数が右の行列の行数と一致する場合にのみ可能であるということです。

Numpyライブラリで内積を求めるには、linalg.dot()関数を使用します。次のスクリプトは、行列 A の逆行列と式1の解である行列 B との間の内積を求めます。

B = np.array([20, 26])
X = np.linalg.inv(A).dot(B)


print(X)


出力

[2. 4.]


ここで、24は式1の未知数 xy のそれぞれの値である。確認として、式 4x + 3y の未知数 x の代わりに 2 を、未知数 y の代わりに 4 を差し込むと、結果が 20 になることがわかります。

次に、次のような3つの連立一次方程式を解いてみましょう。

4x + 3y + 2z = 25
-2x + 2y + 3z = -10
3x -5y + 2z = -4


上の方程式は、Numpyライブラリを用いて次のように解くことができる。

式2:

A = np.array([[4, 3, 2], [-2, 2, 3], [3, -5, 2]])
B = np.array([25, -10, -4])
X = np.linalg.inv(A).dot(B)


print(X)


上のスクリプトでは linalg.inv()linalg.dot() メソッドが連結されています。変数 X には式 2 の解が格納され、以下のように表示されます。

[ 5.  3. -2.]


未知数である x, y, z の値はそれぞれ 5, 3, -2 です。これらの値を式 2 に代入して、その正しさを確認することができる。

solve() メソッドを使用する

前の2つの例では、連立方程式の解を求めるために linalg.inv()linalg.dot() メソッドを使用しました。しかし、Numpyライブラリには linalg.solve() メソッドが含まれており、このメソッドを用いて連立方程式の解を直接求めることができる。

A = np.array([[4, 3, 2], [-2, 2, 3], [3, -5, 2]])
B = np.array([25, -10, -4])
X2 = np.linalg.solve(A,B)


print(X2)


出力

[ 5.  3. -2.]


出力は前と同じであることがわかるだろう。

実例紹介

連立一次方程式がどのように現実の問題を解くのに使われるかを見てみよう。

ある果物屋が,1日にマンゴー20個とオレンジ10個を売って,合計350ドルになったとする.翌日、彼はマンゴー17個とオレンジ22個を売って$500になった。両日とも果物の値段が変わらなかったとしたら、マンゴー1個とオレンジ1個の値段はいくらか?

この問題は,2つの連立方程式で簡単に解くことができる.

マンゴー1個の値段をx、オレンジ1個の値段をyとします。上の問題は、次のように変換できます。

20x + 10y = 350
17x + 22y = 500


上の連立方程式の解は次のとおりである。

A = np.array([[20, 10], [17, 22]])
B = np.array([350, 500])
X = np.linalg.solve(A,B)


print(X)


そして,出力はこうである.

[10. 15.]


出力は、マンゴー1個の価格は$10、オレンジ1個の価格は$15であることを示している。

結論

PythonのNumpyライブラリを使って連立一次方程式を解く方法を説明しました。連立一次方程式を解くには、 linalg.inv()linalg.dot() メソッドを連鎖的に使用するか、単純に solve() メソッドを使用することができます。solve()` メソッドを使用するのが望ましい方法です。

タイトルとURLをコピーしました