隙間ブログ

情報系M1のメモ。機械学習、画像処理、考えた事などなど。

二次形式を行列計算を使って簡単に計算

最近Pythonでプログラム書くときに使った小技のめも。ベクトルは縦ベクトルとする。
{\boldsymbol{x_1},\ \boldsymbol{x_2},\ \cdots,\ \boldsymbol{x_n}}という大きさDの縦ベクトルがn個あり、
{\boldsymbol{A}}という大きさD×Dの行列があったとき、
{y_1, \ y_2, \cdots, \ y_n={\boldsymbol{x_1}}^T\boldsymbol{A}\boldsymbol{x_1},\ {\boldsymbol{x_2}}^T\boldsymbol{A}\boldsymbol{x_2},\ \cdots,\ {\boldsymbol{x_n}}^T\boldsymbol{A}\boldsymbol{x_n}}というn個の二次形式をfor文使わずに求めることを考えます。
{\boldsymbol{X}=(\boldsymbol{x_1}\ \boldsymbol{x_2}\ \cdots\ \boldsymbol{x_n})}という
大きさD×Nを作り、これに{\boldsymbol{A}}を左からかけると
{\boldsymbol{A}\boldsymbol{X}=(\boldsymbol{A}\boldsymbol{x_1}\ \boldsymbol{A}\boldsymbol{x_2}\ \cdots\ \boldsymbol{A}\boldsymbol{x_n})}
というD×Nの行列ができ、
これに左から{{\boldsymbol{X}}^T}というN×Dを左からかけると、N×Nという大きさの((D×N)×(N×D)=(N×N))
{{\boldsymbol{X}}^T\boldsymbol{A}\boldsymbol{X}=\\
\left(
\begin{array}{c}
{\boldsymbol{x_1}}^T \\
{\boldsymbol{x_2}}^T \\
\vdots               \\
{\boldsymbol{x_n}}^T 
\end{array}
\right)
\ 
\left(
\begin{array}{c}
\boldsymbol{A}\boldsymbol{x_1}\ \boldsymbol{A}\boldsymbol{x_2}\ \cdots\ \boldsymbol{A}\boldsymbol{x_n}
\end{array}
\right)=
\begin{pmatrix}
{\boldsymbol{x_1}}^T \boldsymbol{A}\boldsymbol{x_1} & {\boldsymbol{x_1}}^T \boldsymbol{A} \boldsymbol{x_2} & \cdots &{\boldsymbol{x_1}}^T \boldsymbol{A} \boldsymbol{x_n}\\
{\boldsymbol{x_2}}^T \boldsymbol{A} \boldsymbol{x_1} & {\boldsymbol{x_2}}^T \boldsymbol{A} \boldsymbol{x_2} & \cdots & {\boldsymbol{x_2}}^T \boldsymbol{A} \boldsymbol{x_n}\\
\vdots & \vdots & \ddots & \vdots\\
{\boldsymbol{x_n}}^T \boldsymbol{A} \boldsymbol{x_1} & {\boldsymbol{x_n}}^T \boldsymbol{A} \boldsymbol{x_2} & \cdots & {\boldsymbol{x_n}}^T \boldsymbol{A} \boldsymbol{x_n}\\
\end{pmatrix}
}
となり、欲しい{y_1, \ y_2, \cdots, \ y_n={\boldsymbol{x_1}}^T\boldsymbol{A}\boldsymbol{x_1},\ {\boldsymbol{x_2}}^T\boldsymbol{A}\boldsymbol{x_2}\, \cdots\, {\boldsymbol{x_n}}^T\boldsymbol{A}\boldsymbol{x_n}}が対角成分に存在していることがわかります。
よってnumpyのnp.diag({{\boldsymbol{X}}^T\boldsymbol{A}\boldsymbol{X}})を使って対角成分を抽出すれば対角成分が横に並んだ大きさNの横ベクトルを得られ、目的達成です。
for文を回さずにn個の入力ベクトルxに対するn個の二次形式yを求めることができました。