拡大縮小行列
ベクトルを引き伸ばす行列
ベクトルの長さを $k$ 倍にする行列は
\[A=\begin{bmatrix}k&0\\0&k\end{bmatrix}\tag{1}\]
で与えられます。実際、行列 $A$ をベクトル $\boldsymbol{r}=\begin{bmatrix}x\\y\end{bmatrix}$ に掛けてみると、
\[\begin{bmatrix}k&0\\0&k\end{bmatrix}\begin{bmatrix}x\\y\end{bmatrix}=\begin{bmatrix}kx\\ky\end{bmatrix}\tag{2}\]
となります。このような行列 $A$ を 拡大縮小行列 といいます ($k\gt 1$ のとき拡大、$k\lt 1$ のとき縮小)。単位行列 $I$ を用いると (1) は
\[A=kI=k\begin{bmatrix}1&0\\0&1\end{bmatrix}\tag{3}\]
と表せます。コードライブラリ にある coordinate() と visual_vector() を実装して以下のコードを実行すると、ベクトル $\begin{bmatrix}2\\1\end{bmatrix}$ の長さを倍にしてみます。
# python_augmented_matrix
# In[1]
import numpy as np
import matplotlib.pyplot as plt
# ここにcoordinate()を実装
# ここにvisual_vector()を実装
# 4×8サイズのFigureを設置
# 2行1列のサブプロット(Axes)を追加してx軸は共有する
fig, ax = plt.subplots(2, 1, sharex = "col", figsize=(4, 8))
# 座標を設定
coordinate(ax[0], [0, 6], [0, 6], xlabel = "")
coordinate(ax[1], [0, 6], [0, 6])
# 拡大縮小行列a
a = 2 * np.eye(2, dtype = np.int)
# ベクトルの始点
loc = np.array([1, 1])
# ベクトルv0
v0 = np.array([2, 1])
# ベクトルv0を拡大縮小行列aで変換
v1 = np.dot(a, v0)
# ベクトルv0,v1を表示
visual_vector(ax[0], loc, v0, color = "red")
visual_vector(ax[1], loc, v1, color = "blue")
plt.show()
領域の拡大縮小
拡大縮小行列 $A=\begin{bmatrix}k&0\\0&k\end{bmatrix}$ をある領域に作用させると、その領域を $k$ 倍に広げる(あるいは縮める)ことになります。Python で $1\times 1$ の正方領域に $A=\begin{bmatrix}2&0\\0&2\end{bmatrix}$ を作用させてみましょう (格子点の生成については、こちらの記事を参照してください)。
# In[2]
# FigureとAxesを作成
fig, ax = plt.subplots(1, 1, figsize=(5, 5))
# 座標を設定
coordinate(ax, [0, 6], [0, 6])
# 拡大縮小行列a
a = 2 * np.eye(2, dtype = np.int)
# 正方形のデータを格子点として作成
x = np.linspace(1, 2, 65)
y = np.linspace(1, 2, 65)
X, Y = np.meshgrid(x, y)
# XとYの次元を下げてベクトルに変換
X = X.reshape(-1)
Y = Y.reshape(-1)
# XとYを縦に連結してベクトルが横に並ぶ行列を作成
s0 = np.vstack((X, Y))
# 領域s0を拡大縮小行列aで変換
s1 = np.dot(a, s0)
# 変換前の領域s0と変換後の領域s1を表示
ax.scatter(s0[0], s0[1], s = 5, color = "red")
ax.scatter(s1[0], s1[1], s = 5, color = "blue")
plt.show()
コンピュータでは画像も配列データなので、画像の拡大・縮小なども配列操作によって実行されます。
無限集合の写像
コンピュータでは領域を有限個の点の集合として近似しますが、数学では有限領域であっても、その中に無限個の点が含まれています (数直線がいくらでも小さく分割できるのと同じ理屈です)。
そして写像とは点と点の 1 対 1 の対応ですから、変換前と変換後、それぞれの領域に含まれる個数は一致します。これはつまり、領域の大きさに関わらず、含まれる点の個数は同じであることを意味しています。
たとえば、$1 \times 1$ の正方領域を $2 \times 2$ の正方領域に写しても、この 2 つの領域に含まれる点の数は同じです (点の数が $4$ 倍になることはありません)。同じ理屈で $1 \times 1$ の正方領域に含まれる点の個数は平面全体に含まれる点の個数と同じです。この事実は直感に反しているので納得しがたいかもしれませんが、無限集合は有限集合と同じような感覚で扱うことはできないのです。
ChatGPTが拡大縮小行列について解説します
[Q] 拡大縮小行列について教えてください。
[ChatGPT] 拡大縮小行列は、線形変換の一種であり、2次元または3次元のベクトルや図形を拡大または縮小するために使用されます。拡大縮小行列は一般的に次のような形式で表されます。
2次元の場合:
|Sx 0 |
|0 Sy |
3次元の場合:
|Sx 0 0|
|0 Sy 0|
|0 0 Sz|
ここで、Sx、Sy、Szはそれぞれx軸、y軸、z軸方向の拡大または縮小の倍率を表します。これらの値が1より小さい場合、拡大縮小が行われ、1より大きい場合は拡大が行われます。例えば、Sx = 2の場合はx方向に2倍の拡大が行われます。また、拡大縮小行列は原点中心または任意の中心周りで適用することもできます。拡大縮小行列は、画像処理、グラフィックス、CAD(コンピュータ支援設計)などの分野で広く使用されます。また、回転や平行移動と組み合わせて複雑な変換を行うこともできます。
[Q] 拡大縮小行列を Python で実装する方法を教えてください。
[ChatGPT] Pythonで拡大縮小行列を実装するには、NumPyライブラリを使用すると便利です。以下に、2次元および3次元の拡大縮小行列を作成するPythonコードの例を示します。
この例では、create_scaling_matrix_2D関数とcreate_scaling_matrix_3D関数を使用して、指定された拡大縮小倍率に基づいた行列を作成します。そして、np.dot関数を使用して、ベクトルを拡大縮小行列に乗算し、変換後のベクトルを計算しています。上記のコードを実行すると、指定した倍率に基づいて2次元ベクトルや3次元ベクトルが拡大縮小された結果が表示されます。