Skip to content

Instantly share code, notes, and snippets.

@hkawabata
Last active February 20, 2023 02:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hkawabata/533b3f374d8f938316a63ad502a07914 to your computer and use it in GitHub Desktop.
Save hkawabata/533b3f374d8f938316a63ad502a07914 to your computer and use it in GitHub Desktop.
import numpy as np
from matplotlib import pyplot as plt
def scatter_points(V_, ax_, label_):
"""
V_ : n次元列ベクトルを横に並べた行列
"""
d_ = V_.shape[0] # 次元
if d_ == 3:
ax_.scatter(V_[0], V_[1], V_[2], marker='.', s=2.0, label=label_)
elif d_ == 2:
ax_.scatter(V_[0], V_[1], marker='.', s=2.0, label=label_)
def draw_linear_transform(A_, V_):
"""
A_ : n次正方行列
V_ : n次元列ベクトルを横に並べた行列
"""
AV_ = A_.dot(V_)
d_V_ = V_.shape[0]
d_AV_ = AV_.shape[0]
if max(d_V_, d_AV_) == 3 and d_V_ >= 2 and d_AV_ >= 2:
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_zlabel('$Z$')
elif d_V_ == 2 and d_AV_ == 2:
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
else:
raise Exception('Matrix shape or vector shape is not expected.')
ax.set_xlabel('$X$')
ax.set_ylabel('$Y$')
scatter_points(V_, ax, r'$\vec{x}$')
scatter_points(AV_, ax, r'$A\vec{x}$')
plt.legend()
plt.show()
# 変換対象ベクトル(格子点)の生成
XX, YY = np.meshgrid(
range(-20, 20+1),
range(-20, 20+1)
)
V_2d = np.array([XX.flatten(), YY.flatten()])
XX, YY, ZZ = np.meshgrid(
range(-10, 10+1),
range(-10, 10+1),
range(-10, 10+1)
)
V_3d = np.array([XX.flatten(), YY.flatten(), ZZ.flatten()])
As = [
# rank 2 の 2x2 行列
np.array([
[0.5, 1.5],
[1, -1]
]),
# rank 1 の 2x2 行列
np.array([
[1, -0.5],
[-2, 1]
]),
# rank 2 の 3x2 行列
np.array([
[-0.1, 0.9],
[1.0, 1.5],
[1.0, -0.6]
]),
# rank 3 の 3x3 行列
np.array([
[0.5, 1.0, 0],
[-0.6, 0.9, 0.3],
[1.0, 0, -2.0]
]),
# rank 2 の 3x3 行列
np.array([
[-0.5, 0, 1.0],
[-1.0, 1.5, 0.5],
[0, 1.5, -1.5]
]),
# rank 1 の 3x3 行列
np.array([
[-0.5, 0.3, 1.0],
[0.5, -0.3, -1.0],
[1.0, -0.6, -2.0]
])
]
for A in As:
if A.shape[1] == 2:
draw_linear_transform(A, V_2d)
elif A.shape[1] == 3:
draw_linear_transform(A, V_3d)
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# データ作成:直線
N = 100
scale = 100
x_line = np.linspace(-scale*1.2, scale*1.2, N)
y_line = 2.0 * x_line / 3.0
z_line = np.zeros(N)
# データ作成:平面
XX, YY = np.meshgrid(
np.linspace(-scale, scale, N),
np.linspace(-scale, scale, N)
)
ZZ = XX - 2*YY
x_plane = XX.flatten()
y_plane = YY.flatten()
z_plane = x_plane - 2*y_plane
# 描画
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_xlabel('$X$')
ax.set_ylabel('$Y$')
ax.set_zlabel('$Z$')
ax.scatter(x_plane, y_plane, z_plane, s=0.01, c='blue', label=r'eigenspace of $\lambda_2$')
ax.plot(x_line, y_line, z_line, c='orange', label=r'eigenspace of $\lambda_1$')
ax.scatter(0, 0, 0, c='black', marker='o')
#ax.text(0, 0, 0, '$O$')
plt.legend()
plt.show()
# 固有ベクトルやその他のベクトルを行列で線形変換した before/after を描画
import numpy as np
from matplotlib import pyplot as plt
def draw_vector(v_, A_, color_, label_, width_):
"""2x2行列 A_ で2次元列ベクトル v_ を変換して描画"""
v2_ = A_.dot(v_)
plt.quiver(0, 0, v2_[0,0], v2_[1,0],
color=color_, width=width_,
angles = 'xy', scale_units = 'xy', scale=1, alpha=0.3)
plt.quiver(0, 0, v_[0,0], v_[1,0],
color=color_, width=width_, label=label_,
angles = 'xy', scale_units = 'xy', scale=1)
A = np.matrix([[4,1],[-2,1]])
l1, u1 = 2, np.matrix([1, -2]).T
l2, u2 = 3, np.matrix([1, -1]).T
v1 = np.matrix([1, 1]).T
v2 = np.matrix([-2, -1]).T
v3 = np.matrix([-0.5, 2]).T
draw_vector(u1, A, 'red', 'unique', 0.01)
draw_vector(u2, A, 'blue', 'unique', 0.01)
draw_vector(v1, A, 'gray', 'not unique', 0.005)
draw_vector(v2, A, 'green', 'not unique', 0.005)
draw_vector(v3, A, 'purple', 'not unique', 0.005)
plt.xticks(range(-5, 5+1))
plt.yticks(range(-5, 5+1))
plt.legend()
plt.grid()
plt.show()
@hkawabata
Copy link
Author

hkawabata commented Feb 20, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment