0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

線形代数学と工学

Last updated at Posted at 2024-10-07

主なトピックと工学への応用例

  1. 行列とベクトル
    • 行列とベクトルの基本演算、行列の積、逆行列、行列式など。
    • 応用例:電気回路の解析、機械の動作のモデリング、画像処理におけるフィルタリング。

import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import gaussian_filter
from skimage import data

# サンプル画像の読み込み (カメラマン画像)
image = data.camera()

# ガウシアンフィルタ適用
filtered_image = gaussian_filter(image, sigma=3)

# 元画像とフィルタリング後の画像を並べて表示
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
ax[0].imshow(image, cmap='gray')
ax[0].set_title("Original Image")
ax[0].axis('off')

ax[1].imshow(filtered_image, cmap='gray')
ax[1].set_title("Gaussian Filtered Image")
ax[1].axis('off')

plt.show()


import numpy as np
import matplotlib.pyplot as plt

def gaussian_kernel(size: int, sigma: float) -> np.ndarray:
    """ガウシアンフィルタのカーネル行列を作成する関数。
    
    Args:
        size (int): カーネルのサイズ(奇数であることが望ましい)。
        sigma (float): ガウス関数の標準偏差。

    Returns:
        np.ndarray: ガウシアンカーネル行列。
    """
    # カーネルの中心を基準に座標系を設定
    ax = np.linspace(-(size // 2), size // 2, size)
    xx, yy = np.meshgrid(ax, ax)

    # ガウス関数を使用して各座標の値を計算
    kernel = np.exp(-0.5 * (np.square(xx) + np.square(yy)) / np.square(sigma))

    # 正規化(カーネル行列の値の総和を1にする)
    return kernel / np.sum(kernel)

# カーネル行列を作成
kernel_size = 5  # カーネルサイズ
sigma_value = 1.0  # 標準偏差

# ガウシアンカーネルの行列を作成
gaussian_kernel_matrix = gaussian_kernel(kernel_size, sigma_value)

# カーネル行列を表示
print("Gaussian Kernel Matrix:")
print(gaussian_kernel_matrix)

# カーネル行列の可視化
plt.imshow(gaussian_kernel_matrix, interpolation='nearest', cmap='viridis')
plt.colorbar()
plt.title(f"Gaussian Kernel (size={kernel_size}, sigma={sigma_value})")
plt.show()


  1. 線形方程式系
    • 連立一次方程式の解法(ガウス消去法、クラメルの公式など)。
    • 応用例:構造工学における力の平衡解析、交通流解析、電力供給網の解析。
import numpy as np
import matplotlib.pyplot as plt

# 節点 (ノード) の位置 [x, y]
nodes = np.array([[0, 0], [2, 0], [1, 1.5]])

# 要素(部材)の接続(始点と終点のノード番号)
elements = np.array([[0, 1], [1, 2], [2, 0]])

# 各要素の剛性行列を設定(簡単のため、すべて同じ値に設定)
element_stiffness = 1.0

# グローバル剛性行列を作成
K = np.zeros((6, 6))  # 2D平面なので各ノードは2つの自由度を持つ (3ノード x 2自由度)

# 各要素の剛性行列をグローバル剛性行列に組み込む
for element in elements:
    node1, node2 = element
    x1, y1 = nodes[node1]
    x2, y2 = nodes[node2]
    length = np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
    c = (x2 - x1) / length
    s = (y2 - y1) / length
    k_local = element_stiffness * np.array([[ c**2,  c*s, -c**2, -c*s],
                                            [ c*s,  s**2, -c*s, -s**2],
                                            [-c**2, -c*s,  c**2,  c*s],
                                            [-c*s, -s**2,  c*s,  s**2]])

    # グローバル剛性行列への組み込み
    dof = [2*node1, 2*node1+1, 2*node2, 2*node2+1]
    for i in range(4):
        for j in range(4):
            K[dof[i], dof[j]] += k_local[i, j]

# 外力ベクトル(ノードごとの外力) [Fx, Fy] (例として、節点2に外力を加える)
F = np.array([0, 0, 0, 0, 0, -10])

# 支点条件(拘束条件)を設定 (節点0と節点1のx, y方向を固定)
fixed_dof = [0, 1, 2, 3]  # 拘束された自由度

# 剛性行列と外力ベクトルの削減
K_reduced = np.delete(np.delete(K, fixed_dof, axis=0), fixed_dof, axis=1)
F_reduced = np.delete(F, fixed_dof)

# 変位の計算
U_reduced = np.linalg.solve(K_reduced, F_reduced)

# 拘束条件を考慮した全変位ベクトルを組み立て
U = np.zeros(K.shape[0])
U[np.setdiff1d(np.arange(K.shape[0]), fixed_dof)] = U_reduced

# 変位の表示
print("Nodal Displacements (x, y):")
for i in range(len(U)//2):
    print(f"Node {i}: {U[2*i]:.4f}, {U[2*i+1]:.4f}")


# 交通流解析のための係数行列と外部交通流量のベクトルを設定
A = np.array([[ 1, -1,  0,  0],
              [ 0,  1, -1,  0],
              [ 0,  0,  1, -1],
              [ 1,  0,  0, -1]])

# 各リンクの交通流量(外部流入量、正の値は流入、負の値は流出)
b = np.array([100, 0, 0, -100])

# リンク内の交通流量を求める
x = np.linalg.solve(A, b)

# 各リンクの交通流量を表示
print("Traffic Flow in Each Link:")
for i, flow in enumerate(x):
    print(f"Link {i+1}: {flow} vehicles/hour")

# リンク間の交通流量を図示
plt.figure(figsize=(8, 4))
plt.bar(range(len(x)), x)
plt.xlabel("Link")
plt.ylabel("Traffic Flow (vehicles/hour)")
plt.title("Traffic Flow in Each Link")
plt.show()


  1. 固有値・固有ベクトル
    • 固有値問題の定式化とその解法。
    • 応用例:振動系の解析(モード解析)、動力学系の安定性解析、画像認識における主成分分析(PCA)。
import numpy as np
import matplotlib.pyplot as plt

# 剛性行列 K と 質量行列 M の定義(例:2自由度系)
K = np.array([[4, -2],
              [-2, 2]])  # 剛性行列 (Stiffness matrix)
M = np.array([[2, 0],
              [0, 1]])  # 質量行列 (Mass matrix)

# 一般化固有値問題を解く (K*u = ω^2 * M*u)
eigvals, eigvecs = np.linalg.eig(np.linalg.inv(M) @ K)

# 固有振動数の取得
natural_frequencies = np.sqrt(eigvals)

# 固有ベクトルの正規化
eigvecs = eigvecs / np.linalg.norm(eigvecs, axis=0)

# 結果の表示
print("固有振動数 (Natural Frequencies):", natural_frequencies)
print("振動モード (Mode Shapes):\n", eigvecs)

# モードのプロット設定
modes = eigvecs.T

# プロット
fig, ax = plt.subplots(1, 2, figsize=(12, 5))

for i, mode in enumerate(modes):
    ax[i].plot([0, 1], [0, mode[0]], marker='o', label=f'Mass 1')
    ax[i].plot([0, 1], [0, mode[1]], marker='o', label=f'Mass 2')
    ax[i].axhline(0, color='black', linewidth=0.5)
    ax[i].set_title(f'Mode {i+1}: Frequency = {natural_frequencies[i]:.2f}')
    ax[i].set_xlabel('Degree of Freedom')
    ax[i].set_ylabel('Amplitude')
    ax[i].legend()
    ax[i].grid(True)

plt.tight_layout()
plt.show()


import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import load_digits

# データの読み込み(例: 手書き数字データ)
digits = load_digits()
X = digits.data

# データの平均をゼロにする
X_centered = X - np.mean(X, axis=0)

# PCA を適用
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_centered)

# 固有値と固有ベクトルの取得
eigenvalues = pca.explained_variance_
eigenvectors = pca.components_

# 結果のプロット
plt.figure(figsize=(8, 6))
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=digits.target, cmap='viridis', edgecolor='k', s=50)
plt.colorbar()
plt.title("PCA of Digits Dataset")
plt.xlabel("Principal Component 1")
plt.ylabel("Principal Component 2")

# 固有ベクトルを矢印でプロット
for i, v in enumerate(eigenvectors):
    plt.arrow(0, 0, v[0]*5, v[1]*5, head_width=0.3, head_length=0.3, linewidth=2, color='red')
    plt.text(v[0]*5, v[1]*5, f"Eigenvector {i+1}", color='red')

plt.grid()
plt.show()



import numpy as np
import matplotlib.pyplot as plt

# 状態行列 A を定義(例: 2次元系)
A = np.array([[0, 1],
              [-2, -3]])

# 固有値と固有ベクトルの計算
eigenvalues, eigenvectors = np.linalg.eig(A)

# 固有値の表示
print(f"Eigenvalues: {eigenvalues}")

# 固有ベクトルの表示
print(f"Eigenvectors:\n{eigenvectors}")

# 固有値とベクトルのプロット
plt.figure(figsize=(8, 8))

# x, y 軸の設定
plt.axhline(0, color='gray', linewidth=0.5)
plt.axvline(0, color='gray', linewidth=0.5)

# 固有ベクトルのプロット
origin = np.array([[0, 0], [0, 0]])  # 原点
plt.quiver(*origin, eigenvectors[0, :], eigenvectors[1, :], color=['r', 'b'], scale=5)

# 安定性の判定を可視化
for eig in eigenvalues:
    plt.scatter(np.real(eig), np.imag(eig), color='green', s=100, label=f'Eigenvalue: {eig:.2f}')
    
# グラフの設定
plt.title('Stability Analysis: Eigenvalues and Eigenvectors')
plt.xlabel('Real Part')
plt.ylabel('Imaginary Part')
plt.grid()
plt.axvline(0, color='black', linestyle='--')
plt.axhline(0, color='black', linestyle='--')

# 凡例を表示
plt.legend(loc='best')
plt.show()




  1. ベクトル空間と基底
    • ベクトル空間、部分空間、基底と次元の概念。
    • 応用例:信号処理におけるフーリエ変換、圧縮センシング、ロボティクスにおける姿勢制御。
import numpy as np
import matplotlib.pyplot as plt

# ロボットアームのパラメータ設定
length = 1.0  # ロボットアームの長さ(メートル)
theta = np.pi / 4  # 初期角度(45度)

# 目標角度
target_angle = np.pi / 6  # 目標角度(30度)

# 制御パラメータ
Kp = 2.0  # 比例制御ゲイン(Pゲイン)

# 時間設定
dt = 0.01  # 時間刻み(秒)
time = np.arange(0, 5, dt)  # 0秒から5秒までの時間配列

# 角度の履歴を保存するリスト
theta_history = []

# 姿勢制御のシミュレーション
for t in time:
    # 現在の角度誤差
    error = target_angle - theta

    # 比例制御(P制御)による角度変化量
    delta_theta = Kp * error

    # 角度を更新
    theta += delta_theta * dt

    # 角度の履歴を保存
    theta_history.append(theta)

# シミュレーション結果をプロット
plt.figure(figsize=(12, 6))

# 角度の時間変化をプロット
plt.subplot(1, 2, 1)
plt.plot(time, np.degrees(theta_history), label='Current Angle')
plt.axhline(np.degrees(target_angle), color='r', linestyle='--', label='Target Angle')
plt.title("Angle Control Over Time")
plt.xlabel("Time [s]")
plt.ylabel("Angle [degrees]")
plt.legend()
plt.grid()

# 最終姿勢のプロット
plt.subplot(1, 2, 2)
x = [0, length * np.cos(theta_history[-1])]  # アームのx座標
y = [0, length * np.sin(theta_history[-1])]  # アームのy座標
plt.plot(x, y, marker='o')
plt.xlim(-length, length)
plt.ylim(-length, length)
plt.title("Final Robot Arm Position")
plt.xlabel("X position [m]")
plt.ylabel("Y position [m]")
plt.axhline(0, color='k', linestyle='--')
plt.axvline(0, color='k', linestyle='--')
plt.grid()

# グラフを表示
plt.tight_layout()
plt.show()



import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import linprog

# スパース信号の生成
n = 100  # 元信号の次元
m = 30   # 観測値の次元
k = 5    # スパース信号の非ゼロ要素数

# 元信号 x の生成(ランダムに k 個の非ゼロ要素を持つ)
x_true = np.zeros(n)
x_true[np.random.choice(n, k, replace=False)] = np.random.randn(k)

# 観測行列 A の生成(ランダムな正規分布行列)
A = np.random.randn(m, n)

# 観測値 y の生成
y = A.dot(x_true)

# 最小 L1 ノルムを解くための線形計画問題の設定
c = np.ones(2 * n)  # コスト関数 (L1 ノルム)
A_eq = np.hstack([A, -A])
b_eq = y

# 線形計画法で解を求める
result = linprog(c, A_eq=A_eq, b_eq=b_eq, bounds=(0, None), method='highs')

# 求めた解の信号
x_recovered = result.x[:n] - result.x[n:]

# プロット
plt.figure(figsize=(12, 6))

# 元信号
plt.subplot(1, 2, 1)
plt.stem(x_true, use_line_collection=True)
plt.title('Original Sparse Signal')
plt.xlabel('Index')
plt.ylabel('Amplitude')

# 復元信号
plt.subplot(1, 2, 2)
plt.stem(x_recovered, use_line_collection=True)
plt.title('Recovered Signal from Measurements')
plt.xlabel('Index')
plt.ylabel('Amplitude')

plt.tight_layout()
plt.show()




  1. 線形写像と変換

    • 線形写像の定義、核と像、行列表示。
    • 応用例:ロボットアームの位置制御、画像のアフィン変換や投影変換。
  2. 直交性と内積空間

    • ベクトルの直交性、内積、グラム・シュミットの正規直交化法。
    • 応用例:信号の直交分解(フーリエ級数展開)、機械学習のサポートベクトルマシン(SVM)。


  1. 特異値分解 (SVD) と行列分解

    • 特異値分解、QR分解、LU分解の定義と計算方法。
    • 応用例:データ圧縮、レコメンダシステム、画像復元。
  2. 数値的手法とアルゴリズム

    • 数値解法、反復法(共役勾配法など)、条件数と数値安定性の概念。
    • 応用例:大規模システムの数値解析、有限要素法(FEM)による構造解析。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?