0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

対称クロネッカー積におけるvecからsvecに変換する行列Qの実装について

Last updated at Posted at 2021-05-03

0. はじめに

「21世紀の線形計画」といわれる半正定値計画(SDP)を実装し理解を深めようと思います。多くの教科書では半正定値計画の理論的なところを触れているので、実装例を備忘録の連載という形で書いていきます。21世紀の皆様に少しでもお役に立てれば幸いです。

1. vecからsvecに変換する行列Q

$vec$から$svec$に変換する行列Qの実装でつまづいたので備忘録として残す。

変換行列Qの用途をわかりやすいように、2x2の実対称行列$A$を実例として説明する。
実対称行列なので$a_{21}=a_{12}$である。

A = \left(
    \begin{array}{cc}
      a_{11} & a_{12}  \\
      a_{21} & a_{22} 
    \end{array}
  \right)

ここで、実対称行列$A$を$vec$作用素でベクトル化すると$vec(A)$をえる。

vec(A) := (a_{11},a_{21},a_{12},a_{22})^T

実対称行列の対称的な構造に着目し、変数を減らすことができる$svec$を導入する。例えば、2x2実対称行列において、$vec$の場合変数は4であるが、svecの場合変数が3と減らせることがわかる。

svec(A) := (a_{11},\sqrt{2} a_{21},a_{22})^T

$vec$と$svec$の内積が等しいことを確認するため、vecの内積を下記に示す。

trace(AA^T)=vec(A)^Tvec(A)=a_{11}^2 + a_{21}^2 + a_{12}^2 + a_{22}^2 = a_{11}^2 + 2a_{21}^2 + a_{22}^2 

$svec$の場合でも下記のように$vec$と同じ内積値を得られることがわかる。

svec(A)^Tsvec(A)= a_{11}^2 + 2a_{21}^2 + a_{22}^2 

このように$svec$が次元削減において便利であることがわかったと思う。大規模な実対称行列のサイズであれば、より演算回数が減らすうえで有用であることが予想できる。

便利さがわかれば$vec$から$svec$に変換する変換行列$Q$を生成する関数が欲しくなると思う。
2x2の実対称行列の場合の変換行列$Q$は下記で与えられる。

Qvec(A) = svec(A)
Q^Tsvec(A) = vec(A)
Q = \left(
    \begin{array}{cccc}
      1 & 0 & 0 & 0 \\
      0 & \sqrt{2} & \sqrt{2} & 0 \\
      0 & 0 & 0 & 1
    \end{array}
  \right)

2. 実装

任意の実対称行列における変換行列$Q$の実装例を下記に示す。

import numpy as np

def set_vec2svec_matrix(n):
  Q = np.zeros((np.int(n*(n+1)/2) , np.int(n**2)))

  for k in range(n):
      for l in range(n):
          if k == l:
              i = np.int(n*l -l*(l+1)/2 + k)
              j = np.int(n*l + k)
              Q[i,j] = 1
          elif k > l:
              i = np.int(n*l -l*(l+1)/2 + k )
              j = np.int(n*l + k)
              Q[i,j] = 1/np.sqrt(2)
          elif k < l:
              i = np.int(n*k -k*(k+1)/2 + l)
              j = np.int(n*l + k)
              Q[i,j] = 1/np.sqrt(2) 
  return Q

2x2の実対称行列における変換行列Qにおける実行方法を下記に示す。

$ n = 2
$ Q = set_vec2svec_matrix(n)

#[[1.         0.         0.         0.        ]
# [0.         0.70710678 0.70710678 0.        ]
# [0.         0.         0.         1.        ]]

参照

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?