技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

数学回続き

white-azalea.hatenablog.jp

white-azalea.hatenablog.jp

この辺の続き。

二つのベクトル A, B において、B に対して A 方向から垂直に光が当たったと仮定する。
この時、影となった部分のベクトルを「射影」という。

この射影の長さは、垂直の三角形の関係から計算できるので、内積角が分かっているなら


a = \vec{OA} , b=\vec{OB} とし、その射影 \vec{OH} の長さは、 \\
\| a \| cos \theta

また、内積 を利用して射影をベクトルとして処理する場合


\vec{OH} = \| a \| cos \theta * \frac{b}{\| b \|} \\
= \| a \| \frac {a^Tb}{\|a\|\|b\|} * \frac{b}{\| b \|} \\
= \frac{a^Tb}{\|b\|^2}b

で、これが何の役に立つか…って「影」って言ってるよね(汗
ゲームでおなじみの影の処理で普通に使われております。

行列計算のブロック化

例えば次の様な行列 A, B について、 AB を求めたいとしたとき


A = \begin{pmatrix}
  1 & 1 & 1 & 2 \\
    & 1 & 1 & 1 \\
    &   & 1 & 1 \\
    &   & 1 & 1
\end{pmatrix},
B = \begin{pmatrix}
  2 & 1 & 1 & 1 \\
    & 1 & 1 & 1 \\
    &   & 2 & 1 \\
    &   & 1 & 1
\end{pmatrix}

このような行列のドット積を考えるとき


A_{11} = \begin{pmatrix}
  1 & 1 \\
    & 1
\end{pmatrix},
A_{12} = \begin{pmatrix}
  1 & 2 \\
  1 & 1
\end{pmatrix} \\
A_{21} = \begin{pmatrix}
    &   \\
    &  
\end{pmatrix},
A_{22} = \begin{pmatrix}
  1 & 1 \\
  1 & 1
\end{pmatrix} \\

同様に


B_{11} = \begin{pmatrix}
  2 & 1 \\
    & 1
\end{pmatrix},
B_{12} = \begin{pmatrix}
  1 & 1 \\
  1 & 1
\end{pmatrix} \\
B_{21} = \begin{pmatrix}
    &   \\
    &  
\end{pmatrix},
B_{22} = \begin{pmatrix}
  2 & 1 \\
  1 & 1
\end{pmatrix}

と分割し、  AB を考えると


AB = \begin{pmatrix}
A_{11}B_{11} + A_{12}B{21} & A_{11}B_{12} + A_{12}B{22} \\
A_{21}B_{11} + A_{22}B{21} & A_{21}B_{12} + A_{22}B{22}
\end{pmatrix}

の式に展開できる。
これを順に計算していく。

左上をまず計算すると


A_{11}B_{11} + A_{12}B{21} = \begin{pmatrix}
  1 & 1 \\
    & 1
\end{pmatrix}
\begin{pmatrix}
  2 & 1 \\
    & 1
\end{pmatrix} + \begin{pmatrix}
  1 & 2 \\
  1 & 1
\end{pmatrix}
\begin{pmatrix}
    &   \\
    &  
\end{pmatrix} \\
= \begin{pmatrix}
  2 & 2 \\
  0 & 1
\end{pmatrix}

こんなノリで残りを計算して


AB = \begin{pmatrix}
  2 & 2 & 6 & 5 \\
  0 & 1 & 4 & 3 \\
  0 & 0 & 3 & 2 \\
  0 & 0 & 3 & 2
\end{pmatrix}

検算してみると

import numpy as np

a = np.array([
    [1,1,1,2],
    [0,1,1,1],
    [0,0,1,1],
    [0,0,1,1]
])
b = np.array([
    [2,1,1,1],
    [0,1,1,1],
    [0,0,2,1],
    [0,0,1,1]
])
print(a.dot(b))
[[2 2 6 5]
 [0 1 4 3]
 [0 0 3 2]
 [0 0 3 2]]

と、正しく計算された。