初回は量子データについて確認をしました。
2回目は実機やcuQuantumの利用についてと、テンソルネットワークと深層学習・量子計算を行ったり来たりしました。
3回目は少し量子回路側によってPQCでの機械学習の手順をみました。
4回目はテンソル分解の一部で、cuTensorNetworkに現在搭載されているQR分解と特異値分解を見てみたいと思います。
実は3回目の量子計算のうち、ハミルトニアンの期待値はテンソルネットワークで求めています。その際にはテンソルは近似せずに縮約順序のみが最適化されて解かれていましたが、テンソル分解を活用することで、TTの結合次元を調整したり、近似を用いて情報量を圧縮できます(多分)。
今回はとくにNVIDIAのcuTensorNetに導入されているQR分解とSVDを見ます。
QR分解
実正方行列Aは直交行列Qと上三角行列Rに分解できるということです。
A=QR
とりあえずPythonでやってみます。例題はwikipediaから持ってきました。
こちらのAをQとRに分解します。
array([[ 12, -51, 4],
[ 6, 167, -68],
[ -4, 24, -41]])
いくつか方法があるようですが、今回はグラムシュミット直交化法を使って実装してみます。
Aを列ごとに切り出してみました。
import numpy as np
a1 = [12,6,-4]
a2 = [-51,167,24]
a3 = [4,-68,-41]
a1を起点として、a2とa3を順番に直交化していきます。ベクトルの内積をうまく使うと、ベクトルを組み合わせて直交化できます。
a2に関しては、a2からa1と逆方向に長さを調整したベクトルを引くことで対応できます。
v2 = a2 - np.dot(np.dot(a2, a1), a1)/np.dot(a1,a1)
v2
array([-69., 158., 30.])
そして、a3ですね。a3はa1と先ほど求めたv2を利用します。これもa1とv2について調整します。
v3 = a3 - np.dot(np.dot(a3, a1), a1)/np.dot(a1,a1) - np.dot(np.dot(a3, v2), v2)/np.dot(v2,v2)
v3
array([-11.6, 1.2, -33. ])
これでできました。これらは正規化されていないので、正規化をすればQがもとまります。
u1 = a1/np.linalg.norm(a1)
u2 = v2/np.linalg.norm(v2)
u3 = v3/np.linalg.norm(v3)
#列ベクトルとして結合するための準備
u1c = np.array([[i] for i in u1])
u2c = np.array([[i] for i in u2])
u3c = np.array([[i] for i in u3])
# concatenate()関数を使って、3つの列ベクトルを繋げる
Q = np.concatenate((u1c, u2c, u3c), axis=1)
Q
これでQがもとまりました。
array([[ 0.85714286, -0.39428571, -0.33142857],
[ 0.42857143, 0.90285714, 0.03428571],
[-0.28571429, 0.17142857, -0.94285714]])
次にQRのRを求めたいですが、
R = Q.T@A
R
array([[ 1.40000000e+01, 2.10000000e+01, -1.40000000e+01],
[-6.66133815e-16, 1.75000000e+02, -7.00000000e+01],
[ 0.00000000e+00, 1.42108547e-14, 3.50000000e+01]])
できました!
特異値分解(SVD)
ある行列AをUΓV^Tと分解することができる。
Γは対角行列で、要素を特異値と呼んでます。
このように分解することで、対角行列のサイズを切り出して大きな行列を近似することができます。
テンソルネットワークではSVDのうち、どれだけ近似するかなどを決めることができ、MPSのような行列積状態の結合次元を低ランク近似できます。