import numpy as np
import scipy.linalg as la
import matplotlib.pyplot as plt
# ガウス消去法による線形方程式の解法
def gaussian_elimination(A, b):
"""
ガウス消去法を用いて線形方程式 Ax = b を解く。
A: 係数行列
b: 右辺ベクトル
"""
A = np.array(A, dtype=float)
b = np.array(b, dtype=float)
n = len(b)
# 前進消去
for i in range(n):
# 対角要素を1にする
A[i] = A[i] / A[i, i]
b[i] = b[i] / A[i, i]
for j in range(i + 1, n):
factor = A[j, i]
A[j, i:] -= factor * A[i, i:]
b[j] -= factor * b[i]
# 後退代入
x = np.zeros(n)
for i in reversed(range(n)):
x[i] = b[i] - np.dot(A[i, i + 1:], x[i + 1:])
return x
# LU分解
def lu_decomposition(A):
"""
LU分解を行う。
A: 係数行列
"""
P, L, U = la.lu(A)
return L, U, P
def solve_with_lu(L, U, P, b):
"""
LU分解を用いて線形方程式 Ax = b を解く。
L: 下三角行列
U: 上三角行列
P: ピボット行列
b: 右辺ベクトル
"""
Pb = np.dot(P, b)
y = np.linalg.solve(L, Pb)
x = np.linalg.solve(U, y)
return x
# 例: 線形方程式の系を解く
A = np.array([[2, -1, 1], [1, 3, 2], [1, 1, 2]])
b = np.array([2, 5, 3])
# ガウス消去法による解
x_gaussian = gaussian_elimination(A.copy(), b.copy())
# LU分解
L, U, P = lu_decomposition(A)
# LU分解による解
x_lu = solve_with_lu(L, U, P, b)
# 結果の出力
print("ガウス消去法による解:", x_gaussian)
print("LU分解による解:", x_lu)
# 結果を比較するためのプロット
fig, ax = plt.subplots(1, 2, figsize=(14, 6))
# ガウス消去法の結果をプロット
ax[0].bar(range(len(x_gaussian)), x_gaussian, color='blue', alpha=0.7)
ax[0].set_title('Gaussian Elimination Results')
ax[0].set_xlabel('Variable Index')
ax[0].set_ylabel('Value')
# LU分解の結果をプロット
ax[1].bar(range(len(x_lu)), x_lu, color='green', alpha=0.7)
ax[1].set_title('LU Decomposition Results')
ax[1].set_xlabel('Variable Index')
ax[1].set_ylabel('Value')
plt.tight_layout()
plt.show()
import numpy as np
import matplotlib.pyplot as plt
# ベクトル空間と部分空間の定義
def basis_and_dimension(vectors):
"""
与えられたベクトルのリストから基底と次元を計算する。
vectors: ベクトルのリスト (numpy配列)
"""
matrix = np.array(vectors).T
rank = np.linalg.matrix_rank(matrix)
U, S, Vt = np.linalg.svd(matrix, full_matrices=False)
basis = Vt[:rank]
return basis.T, rank
# 線形変換の定義と行列による表現
def linear_transformation(matrix, vectors):
"""
線形変換を行う。
matrix: 変換行列
vectors: 入力ベクトルのリスト (numpy配列)
"""
return [np.dot(matrix, v) for v in vectors]
# 固有値と固有ベクトルの計算
def eigen_decomposition(matrix):
"""
行列の固有値と固有ベクトルを計算する。
matrix: 対角化する行列
"""
eigenvalues, eigenvectors = np.linalg.eig(matrix)
return eigenvalues, eigenvectors
# 行列の対角化
def diagonalize_matrix(matrix):
"""
行列を対角化する。
matrix: 対角化する行列
"""
eigenvalues, eigenvectors = eigen_decomposition(matrix)
D = np.diag(eigenvalues)
P = eigenvectors
P_inv = np.linalg.inv(P)
A_diagonalized = P @ D @ P_inv
return A_diagonalized
# 例: ベクトル空間
vectors = [[1, 0], [0, 1], [1, 1]]
basis, dimension = basis_and_dimension(vectors)
# 例: 線形変換
transformation_matrix = np.array([[2, 0], [0, 3]])
transformed_vectors = linear_transformation(transformation_matrix, vectors)
# 例: 固有値と固有ベクトル
matrix = np.array([[4, 1], [2, 3]])
eigenvalues, eigenvectors = eigen_decomposition(matrix)
A_diagonalized = diagonalize_matrix(matrix)
# 結果の出力
print("基底:\n", basis)
print("次元:", dimension)
print("変換後のベクトル:\n", transformed_vectors)
print("固有値:", eigenvalues)
print("固有ベクトル:\n", eigenvectors)
print("対角化された行列:\n", A_diagonalized)
# 結果のプロット
fig, ax = plt.subplots(1, 2, figsize=(14, 6))
# 基底ベクトルのプロット
ax[0].quiver(0, 0, basis[0, 0], basis[1, 0], angles='xy', scale_units='xy', scale=1, color='r', label='Basis Vector 1')
ax[0].quiver(0, 0, basis[0, 1], basis[1, 1], angles='xy', scale_units='xy', scale=1, color='b', label='Basis Vector 2')
ax[0].set_xlim(-2, 2)
ax[0].set_ylim(-2, 2)
ax[0].set_title('Basis Vectors')
ax[0].set_xlabel('x')
ax[0].set_ylabel('y')
ax[0].legend()
ax[0].grid()
# 固有ベクトルのプロット
ax[1].quiver(0, 0, eigenvectors[0, 0], eigenvectors[1, 0], angles='xy', scale_units='xy', scale=1, color='g', label='Eigenvector 1')
ax[1].quiver(0, 0, eigenvectors[0, 1], eigenvectors[1, 1], angles='xy', scale_units='xy', scale=1, color='m', label='Eigenvector 2')
ax[1].set_xlim(-2, 2)
ax[1].set_ylim(-2, 2)
ax[1].set_title('Eigenvectors')
ax[1].set_xlabel('x')
ax[1].set_ylabel('y')
ax[1].legend()
ax[1].grid()
plt.tight_layout()
plt.show()
import numpy as np
import scipy.linalg as la
import matplotlib.pyplot as plt
# 固有値と固有ベクトルの計算
def eigen_decomposition(matrix):
"""
行列の固有値と固有ベクトルを計算する。
matrix: 対角化する行列
"""
eigenvalues, eigenvectors = np.linalg.eig(matrix)
return eigenvalues, eigenvectors
# 行列の対角化
def diagonalize_matrix(matrix):
"""
行列を対角化する。
matrix: 対角化する行列
"""
eigenvalues, eigenvectors = eigen_decomposition(matrix)
D = np.diag(eigenvalues)
P = eigenvectors
P_inv = np.linalg.inv(P)
A_diagonalized = P @ D @ P_inv
return A_diagonalized
# ジョルダン標準形の計算
def jordan_normal_form(matrix):
"""
行列のジョルダン標準形を計算する。
matrix: ジョルダン標準形を求める行列
"""
J, P = la.jordan(matrix)
return J, P
# 例: 固有値と固有ベクトルの計算
matrix = np.array([[1, 2], [3, 4]])
eigenvalues, eigenvectors = eigen_decomposition(matrix)
A_diagonalized = diagonalize_matrix(matrix)
# 例: ジョルダン標準形の計算
jordan_matrix, jordan_transform = jordan_normal_form(matrix)
# 結果の出力
print("固有値:", eigenvalues)
print("固有ベクトル:\n", eigenvectors)
print("対角化された行列:\n", A_diagonalized)
print("ジョルダン標準形:\n", jordan_matrix)
print("ジョルダン変換行列:\n", jordan_transform)
# 結果のプロット(固有ベクトルのプロット)
fig, ax = plt.subplots(figsize=(7, 7))
# 固有ベクトルのプロット
ax.quiver(0, 0, eigenvectors[0, 0], eigenvectors[1, 0], angles='xy', scale_units='xy', scale=1, color='g', label='Eigenvector 1')
ax.quiver(0, 0, eigenvectors[0, 1], eigenvectors[1, 1], angles='xy', scale_units='xy', scale=1, color='b', label='Eigenvector 2')
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
ax.set_title('Eigenvectors')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()
ax.grid()
plt.show()
import numpy as np
import scipy.linalg as la
import matplotlib.pyplot as plt
# 4.1 LU分解
def lu_decomposition(matrix):
"""
LU分解を計算する。
matrix: 分解する行列
"""
P, L, U = la.lu(matrix)
return P, L, U
# 4.2 QR分解
def qr_decomposition(matrix):
"""
QR分解を計算する。
matrix: 分解する行列
"""
Q, R = np.linalg.qr(matrix)
return Q, R
def least_squares_solution(A, b):
"""
最小二乗法による解を計算する。
A: 行列
b: ベクトル
"""
Q, R = qr_decomposition(A)
y = Q.T @ b
x = np.linalg.solve(R, y)
return x
# 4.3 特異値分解 (SVD)
def svd_decomposition(matrix):
"""
特異値分解を計算する。
matrix: 分解する行列
"""
U, S, Vt = np.linalg.svd(matrix, full_matrices=False)
return U, S, Vt
def data_compression(matrix, k):
"""
特異値分解を用いたデータ圧縮を行う。
matrix: 圧縮する行列
k: 次元数
"""
U, S, Vt = svd_decomposition(matrix)
S_k = np.diag(S[:k])
U_k = U[:, :k]
Vt_k = Vt[:k, :]
compressed_matrix = U_k @ S_k @ Vt_k
return compressed_matrix
# 例: LU分解
matrix = np.array([[4, 2], [3, 1]])
P, L, U = lu_decomposition(matrix)
# 例: QR分解と最小二乗法
A = np.array([[1, 2], [3, 4], [5, 6]])
b = np.array([7, 8, 9])
x_ls = least_squares_solution(A, b)
# 例: 特異値分解とデータ圧縮
data_matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
k = 2
compressed_data_matrix = data_compression(data_matrix, k)
# 結果の出力
print("LU分解:")
print("P:\n", P)
print("L:\n", L)
print("U:\n", U)
print("\nQR分解:")
print("Q:\n", qr_decomposition(A)[0])
print("R:\n", qr_decomposition(A)[1])
print("\n最小二乗法の解:")
print("x:\n", x_ls)
print("\n特異値分解:")
U_svd, S_svd, Vt_svd = svd_decomposition(data_matrix)
print("U:\n", U_svd)
print("S:\n", S_svd)
print("Vt:\n", Vt_svd)
print("\nデータ圧縮:")
print("圧縮された行列:\n", compressed_data_matrix)
# 結果のプロット(SVDの特異値)
plt.figure(figsize=(8, 6))
plt.plot(S_svd, 'o-', label='Singular Values')
plt.xlabel('Index')
plt.ylabel('Singular Value')
plt.title('Singular Values from SVD')
plt.legend()
plt.grid()
plt.show()
import numpy as np
from scipy.optimize import linprog
import matplotlib.pyplot as plt
# 5.1 最適化の基礎
# 線形最適化問題の定式化
# 目的関数: c^T * x の最小化
# 制約条件: A * x <= b
# 目的関数の係数
c = np.array([-1, -2]) # 例: 最大化問題のため、係数は負にする
# 制約条件の係数行列
A = np.array([[2, 1], [1, 2]])
# 制約条件の右辺
b = np.array([20, 30])
# 制約条件の等式/不等式の種類(全て不等式)
# '<=', '>=', '=' で指定
# ここでは全て '<=' です
constraints = 'ineq'
# 線形計画問題の解法
result = linprog(c, A_ub=A, b_ub=b, method='simplex')
# 結果の表示
print("最適化結果:")
print("最適解:", result.x)
print("最適値:", result.fun)
print("ステータス:", result.message)
# 制約条件と目的関数のプロット
# 可視化用のデータ生成
x = np.linspace(0, 10, 400)
y1 = (20 - 2 * x) / 1
y2 = (30 - 1 * x) / 2
plt.figure(figsize=(8, 6))
plt.plot(x, y1, label=r'$2x_1 + x_2 \leq 20$')
plt.plot(x, y2, label=r'$x_1 + 2x_2 \leq 30$')
plt.fill_between(x, np.minimum(y1, y2), 0, alpha=0.2, color='gray', label='Feasible Region')
plt.scatter(result.x[0], result.x[1], color='red', label='Optimal Solution')
plt.xlabel(r'$x_1$')
plt.ylabel(r'$x_2$')
plt.title('Linear Programming Feasible Region and Optimal Solution')
plt.legend()
plt.grid()
plt.show()
import numpy as np
from scipy.optimize import linprog
import matplotlib.pyplot as plt
# 5.2 線形計画法
# シンプレックス法
# 双対性理論
# プライマリ問題の定義
c = np.array([-1, -2]) # 目的関数係数(最大化のため負に設定)
A = np.array([[2, 1], [1, 2]])
b = np.array([20, 30])
# 双対問題の定義
c_dual = np.array([20, 30]) # 双対の目的関数係数
A_dual = np.array([[2, 1], [1, 2]])
b_dual = np.array([-1, -2]) # 双対の制約条件の右辺(プライマリの係数)
# プライマリ問題を解く
result_primal = linprog(c, A_ub=A, b_ub=b, method='simplex')
print("プライマリ問題の最適解:")
print("最適解:", result_primal.x)
print("最適値:", result_primal.fun)
# 双対問題を解く
result_dual = linprog(c_dual, A_ub=-A_dual, b_ub=-b_dual, method='simplex')
print("双対問題の最適解:")
print("最適解:", result_dual.x)
print("最適値:", result_dual.fun)
# プライマリ問題と双対問題の可視化
x = np.linspace(0, 10, 400)
y1 = (20 - 2 * x) / 1
y2 = (30 - 1 * x) / 2
plt.figure(figsize=(12, 8))
plt.subplot(1, 2, 1)
plt.plot(x, y1, label=r'$2x_1 + x_2 \leq 20$')
plt.plot(x, y2, label=r'$x_1 + 2x_2 \leq 30$')
plt.fill_between(x, np.minimum(y1, y2), 0, alpha=0.2, color='gray', label='Feasible Region')
plt.scatter(result_primal.x[0], result_primal.x[1], color='red', label='Primal Optimal Solution')
plt.xlabel(r'$x_1$')
plt.ylabel(r'$x_2$')
plt.title('Primal Problem')
plt.legend()
plt.grid()
plt.subplot(1, 2, 2)
plt.plot(x, -(-20 + 2 * x) / 1, label=r'$2x_1 + x_2 \geq -20$')
plt.plot(x, -(-30 + 1 * x) / 2, label=r'$x_1 + 2x_2 \geq -30$')
plt.fill_between(x, np.maximum(-(-20 + 2 * x) / 1, -(-30 + 1 * x) / 2), 0, alpha=0.2, color='lightblue', label='Feasible Region')
plt.scatter(result_dual.x[0], result_dual.x[1], color='green', label='Dual Optimal Solution')
plt.xlabel(r'$y_1$')
plt.ylabel(r'$y_2$')
plt.title('Dual Problem')
plt.legend()
plt.grid()
plt.tight_layout()
plt.show()
import numpy as np
import scipy.linalg as la
import matplotlib.pyplot as plt
# 数値解法の精度と行列計算の効率化
# 行列Aとベクトルb
A = np.array([[4, 1], [3, 2]])
b = np.array([1, 2])
# ガウス消去法で解を求める
x_gauss = np.linalg.solve(A, b)
print("Gaussian Elimination Solution:", x_gauss)
# LU分解
P, L, U = la.lu(A)
x_lu = la.solve(U, la.solve(L, np.dot(P.T, b)))
print("LU Decomposition Solution:", x_lu)
# QR分解
Q, R = np.linalg.qr(A)
x_qr = np.linalg.solve(R, np.dot(Q.T, b))
print("QR Decomposition Solution:", x_qr)
# 精度比較
def compute_residual(A, x, b):
return np.linalg.norm(np.dot(A, x) - b)
residual_gauss = compute_residual(A, x_gauss, b)
residual_lu = compute_residual(A, x_lu, b)
residual_qr = compute_residual(A, x_qr, b)
print("Residual (Gaussian Elimination):", residual_gauss)
print("Residual (LU Decomposition):", residual_lu)
print("Residual (QR Decomposition):", residual_qr)
# 行列計算の効率化のプロット
matrix_sizes = np.arange(10, 510, 50)
lu_times = []
qr_times = []
for size in matrix_sizes:
A_large = np.random.rand(size, size)
b_large = np.random.rand(size)
# LU分解の計算時間
start_time = np.time()
la.lu(A_large)
lu_times.append(np.time() - start_time)
# QR分解の計算時間
start_time = np.time()
np.linalg.qr(A_large)
qr_times.append(np.time() - start_time)
plt.figure(figsize=(12, 6))
plt.plot(matrix_sizes, lu_times, label='LU Decomposition Time', marker='o')
plt.plot(matrix_sizes, qr_times, label='QR Decomposition Time', marker='o')
plt.xlabel('Matrix Size')
plt.ylabel('Time (seconds)')
plt.title('Performance of Matrix Decompositions')
plt.legend()
plt.grid()
plt.show()
import numpy as np
import matplotlib.pyplot as plt
# 線形変換の定義
def linear_transformation(A, x):
return np.dot(A, x)
# 行列の定義
A = np.array([[2, 0], [0, 3]])
B = np.array([[1, 2], [3, 4]])
# ベクトルの定義
x = np.array([1, 2])
# 線形変換
T_x = linear_transformation(A, x)
S_x = linear_transformation(B, x)
# 合成変換
T_S_x = linear_transformation(A, S_x)
# 逆変換
A_inv = np.linalg.inv(A)
B_inv = np.linalg.inv(B)
T_inv_x = linear_transformation(A_inv, x)
S_inv_x = linear_transformation(B_inv, x)
# プロット設定
plt.figure(figsize=(12, 8))
# ベクトルのプロット
plt.subplot(2, 2, 1)
plt.quiver(0, 0, x[0], x[1], angles='xy', scale_units='xy', scale=1, color='r')
plt.title('Original Vector')
plt.xlim(-1, 10)
plt.ylim(-1, 10)
plt.grid()
# 線形変換後のベクトル
plt.subplot(2, 2, 2)
plt.quiver(0, 0, T_x[0], T_x[1], angles='xy', scale_units='xy', scale=1, color='b', label='A(x)')
plt.quiver(0, 0, S_x[0], S_x[1], angles='xy', scale_units='xy', scale=1, color='g', label='B(x)')
plt.title('Transformed Vectors')
plt.xlim(-1, 10)
plt.ylim(-1, 10)
plt.legend()
plt.grid()
# 合成変換後のベクトル
plt.subplot(2, 2, 3)
plt.quiver(0, 0, T_S_x[0], T_S_x[1], angles='xy', scale_units='xy', scale=1, color='m', label='T(S(x))')
plt.title('Composite Transformation')
plt.xlim(-1, 10)
plt.ylim(-1, 10)
plt.legend()
plt.grid()
# 逆変換後のベクトル
plt.subplot(2, 2, 4)
plt.quiver(0, 0, T_inv_x[0], T_inv_x[1], angles='xy', scale_units='xy', scale=1, color='c', label='A^(-1)(x)')
plt.quiver(0, 0, S_inv_x[0], S_inv_x[1], angles='xy', scale_units='xy', scale=1, color='y', label='B^(-1)(x)')
plt.title('Inverse Transformations')
plt.xlim(-1, 10)
plt.ylim(-1, 10)
plt.legend()
plt.grid()
plt.tight_layout()
plt.show()
import numpy as np
import scipy.linalg as linalg
import matplotlib.pyplot as plt
# サンプル行列の定義
A = np.array([[4, 2], [3, 6]])
B = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# LU分解
P, L, U = linalg.lu(A)
# QR分解
Q, R = linalg.qr(B)
# 特異値分解 (SVD)
U_svd, S, Vt = linalg.svd(B)
# プロット設定
fig, axs = plt.subplots(2, 2, figsize=(12, 10))
# LU分解の表示
axs[0, 0].imshow(L, cmap='viridis', interpolation='none')
axs[0, 0].set_title('L Matrix (LU Decomposition)')
axs[0, 0].grid(False)
axs[0, 1].imshow(U, cmap='viridis', interpolation='none')
axs[0, 1].set_title('U Matrix (LU Decomposition)')
axs[0, 1].grid(False)
# QR分解の表示
axs[1, 0].imshow(Q, cmap='viridis', interpolation='none')
axs[1, 0].set_title('Q Matrix (QR Decomposition)')
axs[1, 0].grid(False)
axs[1, 1].imshow(R, cmap='viridis', interpolation='none')
axs[1, 1].set_title('R Matrix (QR Decomposition)')
axs[1, 1].grid(False)
plt.tight_layout()
plt.show()
# 特異値分解の表示
fig, axs = plt.subplots(1, 2, figsize=(12, 5))
axs[0].imshow(U_svd, cmap='viridis', interpolation='none')
axs[0].set_title('U Matrix (SVD)')
axs[0].grid(False)
axs[1].imshow(Vt, cmap='viridis', interpolation='none')
axs[1].set_title('V^T Matrix (SVD)')
axs[1].grid(False)
plt.tight_layout()
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
# サンプルデータの生成
np.random.seed(0)
X = np.random.rand(100, 5) # 100サンプル、5次元のデータ
# データの標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# PCAの実行
pca = PCA(n_components=2) # 2次元に削減
X_pca = pca.fit_transform(X_scaled)
# 元のデータとPCA後のデータのプロット
fig, axs = plt.subplots(1, 2, figsize=(12, 5))
# 元のデータの散布図
axs[0].scatter(X_scaled[:, 0], X_scaled[:, 1], alpha=0.7)
axs[0].set_title('Original Data (Scaled)')
axs[0].set_xlabel('Feature 1')
axs[0].set_ylabel('Feature 2')
# PCA後のデータの散布図
axs[1].scatter(X_pca[:, 0], X_pca[:, 1], alpha=0.7)
axs[1].set_title('PCA Reduced Data')
axs[1].set_xlabel('Principal Component 1')
axs[1].set_ylabel('Principal Component 2')
plt.tight_layout()
plt.show()
# PCAの主成分と寄与率の表示
print("Principal Components:")
print(pca.components_)
print("\nExplained Variance Ratio:")
print(pca.explained_variance_ratio_)
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report
from sklearn.svm import SVC
# データセットの読み込み
data = load_iris()
X = data.data
y = data.target
feature_names = data.feature_names
# データの標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# PCAの実行
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)
# LDAの実行
lda = LDA(n_components=2)
X_lda = lda.fit_transform(X_scaled, y)
# データの分割
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.3, random_state=42)
# PCA後のデータでモデル訓練と評価
clf_pca = SVC(kernel='linear')
clf_pca.fit(X_train, y_train)
y_pred_pca = clf_pca.predict(X_test)
# LDA後のデータでモデル訓練と評価
clf_lda = SVC(kernel='linear')
clf_lda.fit(X_train, y_train)
y_pred_lda = clf_lda.predict(X_test)
# PCAとLDAのプロット
fig, axs = plt.subplots(1, 2, figsize=(14, 6))
# PCAのプロット
scatter_pca = axs[0].scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap='viridis')
axs[0].set_title('PCA Reduced Data')
axs[0].set_xlabel('Principal Component 1')
axs[0].set_ylabel('Principal Component 2')
legend1 = axs[0].legend(*scatter_pca.legend_elements(), title="Classes")
axs[0].add_artist(legend1)
# LDAのプロット
scatter_lda = axs[1].scatter(X_lda[:, 0], X_lda[:, 1], c=y, cmap='viridis')
axs[1].set_title('LDA Reduced Data')
axs[1].set_xlabel('LD 1')
axs[1].set_ylabel('LD 2')
legend2 = axs[1].legend(*scatter_lda.legend_elements(), title="Classes")
axs[1].add_artist(legend2)
plt.tight_layout()
plt.show()
# モデル評価
print("PCA + SVM Classification Report:")
print(classification_report(y_test, y_pred_pca))
print("\nLDA + SVM Classification Report:")
print(classification_report(y_test, y_pred_lda))
import numpy as np
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
# サンプルデータの生成
np.random.seed(0)
data = np.random.rand(100, 5) # 100サンプル、5次元のデータ
# PCAの実行
pca = PCA(n_components=2) # 2次元に削減
transformed_data = pca.fit_transform(data)
# 固有値と固有ベクトルの取得
explained_variance = pca.explained_variance_ratio_
components = pca.components_
# プロット
plt.figure(figsize=(8, 6))
plt.scatter(transformed_data[:, 0], transformed_data[:, 1], alpha=0.7)
plt.title('PCA Result')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.grid(True)
plt.show()
# 固有値と固有ベクトルの表示
print("Explained Variance Ratio (Eigenvalues):", explained_variance)
print("Principal Components (Eigenvectors):\n", components)
import numpy as np
import matplotlib.pyplot as plt
# Example adjacency matrix of a gene network (undirected graph)
adj_matrix = np.array([
[0, 1, 0, 1],
[1, 0, 1, 0],
[0, 1, 0, 1],
[1, 0, 1, 0]
])
# Calculate eigenvalues and eigenvectors
eigenvalues, eigenvectors = np.linalg.eig(adj_matrix)
# Plot eigenvalues
plt.figure(figsize=(8, 6))
plt.scatter(range(len(eigenvalues)), eigenvalues, color='blue', marker='o')
plt.title('Eigenvalues of the Gene Network Adjacency Matrix')
plt.xlabel('Index')
plt.ylabel('Eigenvalue')
plt.grid(True)
plt.show()
# Display eigenvalues and eigenvectors
print("Eigenvalues:\n", eigenvalues)
print("Eigenvectors:\n", eigenvectors)
import numpy as np
import matplotlib.pyplot as plt
# Example Jacobian matrix of an enzyme reaction kinetics model
jacobian_matrix = np.array([
[-0.1, 0.05],
[0.02, -0.07]
])
# Calculate eigenvalues and eigenvectors
eigenvalues, eigenvectors = np.linalg.eig(jacobian_matrix)
# Plot eigenvalues
plt.figure(figsize=(8, 6))
plt.scatter(range(len(eigenvalues)), eigenvalues, color='red', marker='o')
plt.title('Eigenvalues of the Jacobian Matrix for Enzyme Reaction')
plt.xlabel('Index')
plt.ylabel('Eigenvalue')
plt.grid(True)
plt.show()
# Display eigenvalues and eigenvectors
print("Eigenvalues:\n", eigenvalues)
print("Eigenvectors:\n", eigenvectors)
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
# データの生成(例として2次元データを生成)
np.random.seed(0)
X = np.random.randn(100, 2)
# データの標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# PCAの実施
pca = PCA(n_components=1)
X_pca = pca.fit_transform(X_scaled)
# 結果のプロット
plt.figure(figsize=(8, 6))
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], label='Original Data')
plt.scatter(X_pca, np.zeros_like(X_pca), label='PCA Reduced Data', color='red')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('PCA Dimension Reduction')
plt.legend()
plt.grid(True)
plt.show()
print('Explained variance ratio:', pca.explained_variance_ratio_)
print('Principal Components:\n', pca.components_)
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
# 線形システムの定義
def system(x, t):
A = np.array([[-1, 2], [-2, -1]])
return A @ x
# リアプノフ関数の定義
def lyapunov_function(x):
return x.T @ P @ x
# リアプノフ関数の時間変化
def lyapunov_derivative(x):
return x.T @ (A.T @ P + P @ A) @ x
# システムとリアプノフ関数の設定
A = np.array([[-1, 2], [-2, -1]])
P = np.linalg.solve(A.T @ A, np.eye(2)) # P を適切に選択
x0 = np.array([1, 0]) # 初期状態
# 時間の設定
t = np.linspace(0, 10, 100)
# システムの解の計算
x = odeint(system, x0, t)
# リアプノフ関数の値の計算
lyapunov_values = np.array([lyapunov_function(xi) for xi in x])
# プロット
plt.figure(figsize=(10, 6))
plt.plot(t, lyapunov_values, label='Lyapunov Function V(x)')
plt.xlabel('Time')
plt.ylabel('Lyapunov Function Value')
plt.title('Lyapunov Function Over Time')
plt.legend()
plt.grid(True)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
# シミュレーションパラメータ
num_particles = 100
num_steps = 1000
dt = 0.01
# 初期位置と速度
positions = np.random.rand(num_particles, 3)
velocities = np.random.randn(num_particles, 3)
# 力の計算(シンプルな例)
def compute_forces(positions):
forces = np.zeros_like(positions)
for i in range(num_particles):
for j in range(i + 1, num_particles):
r = positions[j] - positions[i]
r_norm = np.linalg.norm(r)
if r_norm > 0:
force = r / r_norm ** 3
forces[i] += force
forces[j] -= force
return forces
# シミュレーションループ
trajectory = []
for step in range(num_steps):
forces = compute_forces(positions)
velocities += forces * dt
positions += velocities * dt
trajectory.append(positions.copy())
# 結果のプロット
trajectory = np.array(trajectory)
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
for i in range(num_particles):
ax.plot(trajectory[:, i, 0], trajectory[:, i, 1], trajectory[:, i, 2])
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.title('Molecular Dynamics Simulation')
plt.show()
import numpy as np
def partial_pivoting_gaussian_elimination(A, b):
n = len(b)
# 拡大係数行列の作成
Ab = np.hstack([A, b.reshape(-1, 1)])
for i in range(n):
# ピボット選択
max_row = np.argmax(np.abs(Ab[i:n, i])) + i
if i != max_row:
# 行の交換
Ab[[i, max_row]] = Ab[[max_row, i]]
# ガウス消去法
for j in range(i + 1, n):
ratio = Ab[j, i] / Ab[i, i]
Ab[j, i:] -= ratio * Ab[i, i:]
# 後退代入法
x = np.zeros(n)
for i in range(n - 1, -1, -1):
x[i] = (Ab[i, -1] - np.dot(Ab[i, i + 1:n], x[i + 1:n])) / Ab[i, i]
return x
# 例
A = np.array([[2, -1, 1], [3, 3, 9], [3, 3, 5]], dtype=float)
b = np.array([1, 0, 4], dtype=float)
x = partial_pivoting_gaussian_elimination(A, b)
print("Solution x:", x)
import numpy as np
import matplotlib.pyplot as plt
# データの生成
np.random.seed(0)
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
# 行列 A とベクトル b の作成
A = np.hstack([np.ones((100, 1)), X]) # バイアス項の追加
b = y
# 正規方程式の計算
AtA = A.T @ A
Atb = A.T @ b
x = np.linalg.solve(AtA, Atb)
# 予測値の計算
y_pred = A @ x
# プロット
plt.scatter(X, y, label='Data points')
plt.plot(X, y_pred, color='red', label='Regression line')
plt.xlabel('X')
plt.ylabel('y')
plt.legend()
plt.title('Linear Regression using Normal Equations')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error
# データの生成
np.random.seed(0)
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
# バイアス項の追加
X_b = np.c_[np.ones((100, 1)), X]
# 正規方程式の計算
theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)
# 予測値の計算
X_new = np.array([[0], [2]])
X_new_b = np.c_[np.ones((2, 1)), X_new]
y_predict = X_new_b.dot(theta_best)
# プロット
plt.plot(X_new, y_predict, "r-", label="Prediction")
plt.plot(X, y, "b.", label="Data points")
plt.xlabel("X")
plt.ylabel("y")
plt.legend()
plt.title("Linear Regression using Normal Equations")
plt.show()
# モデルの評価
y_pred = X_b.dot(theta_best)
mse = mean_squared_error(y, y_pred)
print("Mean Squared Error:", mse)
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import precision_score, recall_score, f1_score, accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
# データの生成
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42)
# トレーニングとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# ロジスティック回帰モデルのトレーニング
model = LogisticRegression()
model.fit(X_train, y_train)
# 予測
y_pred = model.predict(X_test)
# 評価指標の計算
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)
# 評価指標を辞書に格納
metrics = {
'Accuracy': accuracy,
'Precision': precision,
'Recall': recall,
'F1 Score': f1
}
# プロット
plt.figure(figsize=(8, 6))
plt.bar(metrics.keys(), metrics.values(), color=['blue', 'green', 'red', 'purple'])
plt.ylim(0, 1)
plt.title('Model Evaluation Metrics')
plt.ylabel('Score')
plt.xlabel('Metrics')
plt.grid(axis='y')
# 各バーにスコアを表示
for i, (metric, score) in enumerate(metrics.items()):
plt.text(i, score + 0.02, f'{score:.2f}', ha='center')
plt.show()
# 必要なライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
# データの生成
np.random.seed(0)
mean = [0, 0]
cov = [[3, 1], [1, 2]] # 分散共分散行列
X = np.random.multivariate_normal(mean, cov, 100)
# データのプロット
plt.scatter(X[:, 0], X[:, 1], alpha=0.5)
plt.title('Original Data')
plt.xlabel('X1')
plt.ylabel('X2')
plt.axis('equal')
plt.show()
# 分散共分散行列の計算
cov_matrix = np.cov(X.T)
print("Covariance Matrix:\n", cov_matrix)
# 固有値と固有ベクトルの計算
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)
print("Eigenvalues:\n", eigenvalues)
print("Eigenvectors:\n", eigenvectors)
# PCAの適用
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
# 主成分軸をプロット
plt.scatter(X[:, 0], X[:, 1], alpha=0.5, label='Original Data')
for length, vector in zip(eigenvalues, eigenvectors.T):
v = vector * 3 * np.sqrt(length)
plt.quiver(*mean, *v, angles='xy', scale_units='xy', scale=1, color='r', alpha=0.8)
plt.title('Principal Components')
plt.xlabel('X1')
plt.ylabel('X2')
plt.axis('equal')
plt.legend()
plt.show()
# PCA後のデータプロット
plt.scatter(X_pca[:, 0], X_pca[:, 1], alpha=0.5)
plt.title('Data after PCA')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.axis('equal')
plt.show()
# 必要なライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import TruncatedSVD
from sklearn.preprocessing import StandardScaler
# データの生成
np.random.seed(0)
data = np.random.randn(100, 50) # 100サンプル、50特徴
# 標準化
scaler = StandardScaler()
data_standardized = scaler.fit_transform(data)
# 特異値分解の適用
svd = TruncatedSVD(n_components=10)
data_svd = svd.fit_transform(data_standardized)
# 特異値の取得
singular_values = svd.singular_values_
print("Singular Values:\n", singular_values)
# 元のデータの可視化
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.title("Original Data")
plt.imshow(data, aspect='auto', cmap='viridis')
plt.colorbar()
plt.xlabel("Features")
plt.ylabel("Samples")
# SVD後のデータの可視化
plt.subplot(1, 2, 2)
plt.title("Data after SVD")
plt.imshow(data_svd, aspect='auto', cmap='viridis')
plt.colorbar()
plt.xlabel("Reduced Features")
plt.ylabel("Samples")
plt.tight_layout()
plt.show()
# 深層学習における特異値の役割の例
def initialize_weights(shape):
return np.random.randn(*shape) * np.sqrt(2 / sum(shape))
# 勾配消失・爆発の例
layer_sizes = [50, 100, 200, 100, 50]
weights = [initialize_weights((layer_sizes[i], layer_sizes[i+1])) for i in range(len(layer_sizes) - 1)]
# 重みの積の特異値の計算
product_matrix = weights[0]
for W in weights[1:]:
product_matrix = np.dot(product_matrix, W)
_, singular_values, _ = np.linalg.svd(product_matrix)
print("Singular Values of the Weight Product Matrix:\n", singular_values)
# 特異値のプロット
plt.figure(figsize=(8, 6))
plt.plot(singular_values, 'o-')
plt.title("Singular Values of the Weight Product Matrix")
plt.xlabel("Index")
plt.ylabel("Singular Value")
plt.yscale('log')
plt.show()
# 必要なライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import multivariate_normal
import torch
import torch.nn as nn
import torch.optim as optim
# Chapter 18: Regression Analysis and Pseudoinverse
print("Chapter 18: Regression Analysis and Pseudoinverse")
# データの生成
np.random.seed(0)
X = 2 * np.random.rand(100, 2)
y = 4 + 3 * X[:, 0] + 5 * X[:, 1] + np.random.randn(100)
# 拡張行列
X_b = np.c_[np.ones((100, 1)), X]
# 擬似逆行列を用いた回帰分析
theta_best = np.linalg.pinv(X_b).dot(y)
print("Estimated coefficients:", theta_best)
# 結果のプロット
plt.figure(figsize=(8, 6))
plt.scatter(X[:, 0], y, label='Data points')
plt.plot(X[:, 0], X_b.dot(theta_best), color='red', label='Regression line')
plt.xlabel("X1")
plt.ylabel("y")
plt.title("Regression Analysis with Pseudoinverse")
plt.legend()
plt.show()
# Chapter 19: Multivariate Normal Distribution and Its Integration
print("Chapter 19: Multivariate Normal Distribution and Its Integration")
# 多変量正規分布の定義
mean = np.array([0, 0])
cov = np.array([[1, 0.8], [0.8, 1]])
rv = multivariate_normal(mean, cov)
# 分布のサンプル生成とプロット
X = np.random.multivariate_normal(mean, cov, 500)
plt.figure(figsize=(8, 6))
plt.scatter(X[:, 0], X[:, 1], alpha=0.5, label='Samples')
plt.title("Multivariate Normal Distribution")
plt.xlabel("X1")
plt.ylabel("X2")
plt.axis('equal')
plt.legend()
plt.show()
# Chapter 20: Generative Models and Variational Free Energy
print("Chapter 20: Generative Models and Variational Free Energy")
# 簡単な生成モデルの実装 (Variational Autoencoder)
class VAE(nn.Module):
def __init__(self, input_dim, hidden_dim, latent_dim):
super(VAE, self).__init__()
self.encoder = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, latent_dim * 2) # mean and log-variance
)
self.decoder = nn.Sequential(
nn.Linear(latent_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, input_dim),
nn.Sigmoid()
)
def reparameterize(self, mu, logvar):
std = torch.exp(0.5 * logvar)
eps = torch.randn_like(std)
return mu + eps * std
def forward(self, x):
h = self.encoder(x)
mu, logvar = h.chunk(2, dim=-1)
z = self.reparameterize(mu, logvar)
return self.decoder(z), mu, logvar
def loss_function(recon_x, x, mu, logvar):
BCE = nn.functional.binary_cross_entropy(recon_x, x, reduction='sum')
KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())
return BCE + KLD
# データの生成
torch.manual_seed(0)
data = torch.randn(1000, 20)
# モデルの初期化とトレーニング
vae = VAE(input_dim=20, hidden_dim=50, latent_dim=10)
optimizer = optim.Adam(vae.parameters(), lr=1e-3)
num_epochs = 50
for epoch in range(num_epochs):
vae.train()
optimizer.zero_grad()
recon_data, mu, logvar = vae(data)
loss = loss_function(recon_data, data, mu, logvar)
loss.backward()
optimizer.step()
if (epoch + 1) % 10 == 0:
print(f'Epoch {epoch+1}, Loss: {loss.item():.4f}')
print("Training complete!")
# 生成結果の表示
vae.eval()
with torch.no_grad():
sample = torch.randn(64, 10)
generated_data = vae.decoder(sample).numpy()
plt.figure(figsize=(8, 6))
plt.imshow(generated_data, aspect='auto', cmap='viridis')
plt.colorbar()
plt.title("Generated Data (VAE)")
plt.xlabel("Features")
plt.ylabel("Samples")
plt.show()
# 必要なライブラリのインポート
import numpy as np
# 4.1.1 正方行列の生成
print("4.1.1 Square Matrices")
A = np.array([[1, 2], [3, 4]])
print("Square Matrix A:\n", A)
# 4.1.2 対称行列の生成
print("\n4.1.2 Symmetric Matrices")
B = np.array([[1, 2], [2, 1]])
print("Symmetric Matrix B:\n", B)
# 4.1.3 半正定値行列と正定値行列の生成
print("\n4.1.3 Positive Semidefinite and Positive Definite Matrices")
C = np.array([[2, -1], [-1, 2]])
D = np.array([[2, 1], [1, 2]])
print("Positive Semidefinite Matrix C:\n", C)
print("Positive Definite Matrix D:\n", D)
# 半正定値行列の検証
def is_positive_semidefinite(matrix):
eigenvalues = np.linalg.eigvals(matrix)
return np.all(eigenvalues >= 0)
# 正定値行列の検証
def is_positive_definite(matrix):
eigenvalues = np.linalg.eigvals(matrix)
return np.all(eigenvalues > 0)
print("Is C positive semidefinite?", is_positive_semidefinite(C))
print("Is D positive definite?", is_positive_definite(D))
# 4.2 行列全体からなるユークリッド空間
print("\n4.2 Euclidean Space Comprising Entire Matrices")
# 4.2.1 内積とノルムの計算
print("\n4.2.1 Inner Product and Norm")
E = np.array([[1, 2], [2, 1]])
F = np.array([[3, 4], [4, 3]])
inner_product = np.trace(np.dot(E.T, F))
norm_E = np.linalg.norm(E, 'fro')
norm_F = np.linalg.norm(F, 'fro')
print("Inner Product of E and F:", inner_product)
print("Frobenius Norm of E:", norm_E)
print("Frobenius Norm of F:", norm_F)
# 4.2.2 行列点列の収束性の検証
print("\n4.2.2 Convergence of Matrix Sequences")
def matrix_sequence_convergence(sequence, tol=1e-5):
for i in range(1, len(sequence)):
if np.linalg.norm(sequence[i] - sequence[i-1], 'fro') > tol:
return False
return True
# 行列点列の生成と収束性の検証
sequence = [np.eye(2) / (i + 1) for i in range(10)]
print("Matrix sequence converges:", matrix_sequence_convergence(sequence))
# 例としての機械学習への応用
# データの生成と正定値カーネル行列の計算 (RBFカーネル)
from sklearn.metrics.pairwise import rbf_kernel
X = np.random.randn(100, 2)
gamma = 0.1
K = rbf_kernel(X, gamma=gamma)
print("\nGenerated RBF Kernel Matrix K is positive definite:", is_positive_definite(K))
# 必要なライブラリのインポート
import numpy as np
import scipy.linalg as la
# 6.1 固有値問題 (Eigenvalue Problem)
print("6.1 Eigenvalue Problem")
A = np.array([[4, -2], [1, 1]])
eigenvalues, eigenvectors = np.linalg.eig(A)
print("Matrix A:\n", A)
print("Eigenvalues of A:", eigenvalues)
print("Eigenvectors of A:\n", eigenvectors)
# 6.2 エルミート行列の固有値問題 (Eigenvalue Problem of Hermitian Matrices)
print("\n6.2 Eigenvalue Problem of Hermitian Matrices")
# エルミート行列の生成
H = np.array([[2, 1+1j], [1-1j, 3]])
eigenvalues_H, eigenvectors_H = np.linalg.eigh(H) # Hermitianの場合、eighを使用
print("Hermitian Matrix H:\n", H)
print("Eigenvalues of H:", eigenvalues_H)
print("Eigenvectors of H:\n", eigenvectors_H)
# 6.3 一般化固有値問題 (Generalized Eigenvalue Problem)
print("\n6.3 Generalized Eigenvalue Problem")
# 一般化固有値問題の行列を生成
A = np.array([[1, 2], [3, 4]])
B = np.array([[2, 0], [0, 1]])
eigenvalues_generalized, eigenvectors_generalized = la.eig(A, B)
print("Matrix A:\n", A)
print("Matrix B:\n", B)
print("Generalized Eigenvalues of A and B:", eigenvalues_generalized)
print("Generalized Eigenvectors of A and B:\n", eigenvectors_generalized)
# 固有値分解の可視化
import matplotlib.pyplot as plt
# 固有値のプロット
plt.figure(figsize=(12, 6))
# 固有値問題
plt.subplot(1, 3, 1)
plt.scatter(np.real(eigenvalues), np.imag(eigenvalues), color='red')
plt.title("Eigenvalues of A")
plt.xlabel("Real part")
plt.ylabel("Imaginary part")
plt.grid(True)
# エルミート行列の固有値問題
plt.subplot(1, 3, 2)
plt.scatter(np.real(eigenvalues_H), np.imag(eigenvalues_H), color='blue')
plt.title("Eigenvalues of Hermitian Matrix H")
plt.xlabel("Real part")
plt.ylabel("Imaginary part")
plt.grid(True)
# 一般化固有値問題
plt.subplot(1, 3, 3)
plt.scatter(np.real(eigenvalues_generalized), np.imag(eigenvalues_generalized), color='green')
plt.title("Generalized Eigenvalues of A and B")
plt.xlabel("Real part")
plt.ylabel("Imaginary part")
plt.grid(True)
plt.tight_layout()
plt.show()
import numpy as np
import scipy.linalg as la
import matplotlib.pyplot as plt
# Tepliz行列の生成関数
def generate_tepliz_matrix(c, r):
return la.toeplitz(c, r)
# 例としてのTepliz行列の生成
c = np.array([1, 2, 3, 4])
r = np.array([1, -1, -2, -3])
tepliz_matrix = generate_tepliz_matrix(c, r)
print("Tepliz Matrix:\n", tepliz_matrix)
# 工学応用: 線形システムの解法
# Ax = b を解く
A = tepliz_matrix
b = np.array([1, 2, 3, 4])
# 解法1: 直接解く
x_direct = np.linalg.solve(A, b)
print("\nSolution using np.linalg.solve:\n", x_direct)
# 解法2: ルーチン法 (SciPyを使用)
x_routine = la.solve_toeplitz((c, r), b)
print("\nSolution using la.solve_toeplitz:\n", x_routine)
# 結果のプロット
plt.figure(figsize=(10, 6))
plt.plot(x_direct, 'o-', label='Direct Solution')
plt.plot(x_routine, 's-', label='Routine Solution')
plt.xlabel('Index')
plt.ylabel('Value')
plt.title('Solution of Linear System Using Tepliz Matrix')
plt.legend()
plt.grid(True)
plt.show()