線形代数

1. 学習内容



2. ストーリー

ボブは1000個の線形方程式の連立方程式を解く必要があります。彼はガウス消去法のループを記述しましたが、処理時間は30秒で、実装にはバグがありました。一方、アリスはnp.linalg.solve(A, b)を使用し、処理時間は0.01秒で、正確な結果を得ました。 「NumPyでの線形代数は単に高速なだけでなく、MATLABやRでも使用されているのと同じライブラリであるBLAS/LAPACKを呼び出します。これらは数十年にわたり実戦でその実力が証明されています。」



3. 主要な概念

(1) 行列の乗算

PYTHON
import numpy as np

A = np.array([[1, 2],
              [3, 4]])
B = np.array([[5, 6],
              [7, 8]])

# Three equivalent ways:
print(A @ B)            # [[19 22]
                        #  [43 50]]
print(np.dot(A, B))     # same
print(np.matmul(A, B))  # same
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

(2) 逆行列と行列式

PYTHON
import numpy as np

A = np.array([[1, 2],
              [3, 4]])

det = np.linalg.det(A)      # -2.000
inv = np.linalg.inv(A)      # [[-2.   1. ]
                             #  [ 1.5 -0.5]]
print(A @ inv)              # [[1. 0.]
                             #  [0. 1.]]  (identity)
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

(3) 連立一次方程式の解法

PYTHON
# Solve Ax = b
A = np.array([[3, 1],
              [1, 2]])
b = np.array([9, 8])

x = np.linalg.solve(A, b)
print(x)  # [2. 3.]
print(A @ x)  # [9. 8.]  — verify
TEXT
> Output: Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

(1) ▶ サンプル:行列の乗算(難易度 ⭐)

PYTHON
import numpy as np

A = np.array([[1, 2, 3],
              [4, 5, 6]])
B = np.array([[7, 8],
              [9, 10],
              [11, 12]])

# Matrix multiply: (2x3) @ (3x2) = (2x2)
C = A @ B
print("A @ B:\n", C)

# Dot product of vectors
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
print("dot(x, y):", np.dot(x, y))

出力:

TEXT
A @ B:
 [[ 58  64]
 [139 154]]
dot(x, y): 32

(2) ▶ サンプル:連立一次方程式の解法(難易度 ⭐⭐)

PYTHON
import numpy as np

# Solve: 3x + y = 9, x + 2y = 8
A = np.array([[3, 1],
              [1, 2]])
b = np.array([9, 8])

x = np.linalg.solve(A, b)
print("Solution:", x)

# Verify
print("A @ x =", A @ x)
print("b     =", b)

出力:

TEXT
解答:[2. 3.]
A @ x = [9. 8.]
b     = [9. 8.]

(3) ▶ サンプル:固有値と固有ベクトル(難易度 ⭐⭐)

PYTHON
import numpy as np

A = np.array([[4, -2],
              [1,  1]])

eigenvalues, eigenvectors = np.linalg.eig(A)
print("Eigenvalues:", eigenvalues)

# Verify: A @ v = λ * v
v = eigenvectors[:, 0]
lam = eigenvalues[0]
lhs = A @ v
rhs = lam * v
print("A @ v:", lhs)
print("λ * v:", rhs)
print("Match:", np.allclose(lhs, rhs))

出力:

TEXT
固有値:[3, 2]
A @ v: [0.89442719 0.4472136 ]
λ * v: [0.89442719 0.4472136 ]
一致:True

Q @np.dotnp.matmul の違いは何ですか?
A 2次元配列の場合、これらは同一です。 高次元の場合、@np.matmulはブロードキャスティング(積層行列乗算)を使用するのに対し、np.dotは各要素の最終軸に対して和積を使用します。
Q solveinv は、それぞれどのような場合に使用すべきですか?
A 常に solve を使用してください。処理速度が速く、数値的な安定性も高いからです。 inv(A) @ bの計算は、solve(A, b)に比べて処理速度が遅く、精度も劣ります。
Q A が単体行列の場合はどうなりますか?
A np.linalg.solveLinAlgError: Singular matrix を呼び出します。過決定・欠決定系の最小二乗解を求めるには、np.linalg.lstsq を使用してください。

❓ よくある質問

Q 最も重要なポイントは何か?
A NumPyの演算はベクトル化されているため、パフォーマンスを向上させるにはPythonのループは避けるべきだ。
Q さらに詳しく知りたい場合はどうすればよいですか?
A 詳細なリファレンスや高度なトピックについては、numpy.org の NumPy 公式ドキュメントをご覧ください。
Q これはNumPy 2.xでも動作しますか?
A はい。すべての例はNumPy 2.xと互換性があります。一部の古いAPI(np.random.seedなど)は引き続きサポートされていますが、最新の代替APIの使用をお勧めします。

📖 まとめ



📝 練習問題

  1. 初心者向け(難易度 ⭐):ランダムな整数からなる 3×3 の行列を 2 つ作成する。それらの積、行列式、および逆行列を計算する。A @ inv(A) ≈ 単位行列であることを確認する。

  2. 中級(難易度 ⭐⭐)np.linalg.solve を使って、連立方程式 3x + y = 9, x + 2y = 8 を解きなさい。答えが正しいか確認しなさい。

  3. 上級(難易度 ⭐⭐⭐):5×5のランダムな行列を生成し、その固有値と固有ベクトルを計算する。各固有値・固有ベクトルの組について、A @ v = λ * v となることを確認する。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%