前回はnetworkxで漢字を使ってグラフを作りました。うまくできましたので、実際に計算をしてみたいと思います。
使うライブラリはopt_einsumで、漢字を使って行列計算できます。なぜ漢字を使うかというと、添え字がアルファベット26文字では足りないからです。
おさらいです。計算は添え字を使ってベクトルや行列計算をします。
import opt_einsum as oe
import numpy as np
eq = 'ijk,jkl'
x, y = np.random.rand(2, 3, 4), np.random.rand(3, 4, 5)
arr = [x,y]
z = oe.contract(eq, *arr)
print(z.shape)
print(z)
(2, 5)
[[2.1239399 2.608542 1.84850682 1.63165589 1.84456378]
[2.3728687 2.44788838 2.51473996 2.12868777 2.63054486]]
漢字を準備します。
kanji = ["一","七","万","三","上","下","中","九","二","五","人","今","休","何","先","入","八","六","円","出","分","前","北","十","千","午","半","南","友","右","名","四","国","土","外","大","天","女","子","学","小","山","川","左","年","後","日","時","書","月","木","本","来","東","校","母","毎","気","水","火","父","生","男","白","百","聞","行","西","見","話","語","読","車","金","長","間","雨","電","食","高","不","世","主","事","京","仕","代","以","会","住","体","作","使","借","元","兄","公","写","冬","切","別","力","勉","動","医","去","口","古","台","同","味","品","員","問","図","地","堂","場"]
前回作ったグラフを使います。
l2 = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 14], [14, 15], [15, 0], [5, 8], [7, 12], [0, 3], [2, 14], [7, 9], [7, 11], [0, 14], [6, 13], [13, 15], [8, 12], [7, 10], [10, 13], [6, 8], [2, 7], [7, 14], [1, 14], [11, 15], [1, 9], [9, 13]]
まずは量子ビットを準備します。
#量子ビット数
N = 16
#初期量子状態
psi = [1,0]
arr_tensor = []
arr_arm = []
#kanji
n_kanji = 0
for i in range(N):
arr_arm.append(kanji[i])
arr_tensor.append(psi)
いよいよここからが本番ですね。量子ゲートをどんどんつなぎ合わせていきます。前編で苦労したのは腕の管理ですが、今回は時間発展で前から順番に量子ビットの状態を都度管理しながらやってみたいと思います。
arr_state = []
for i in range(N):
arr_state.append(arr_arm[i])
n_kanji += 1
arr_state
['一',
'七',
'万',
'三',
'上',
'下',
'中',
'九',
'二',
'五',
'人',
'今',
'休',
'何',
'先',
'入']
print(n_kanji)
16
次にゲートをかけていきますが、stateの情報を参照・更新しながら進めていきます。アダマールゲートを適用します。
H = np.array([[1,1],[1,-1]])/np.sqrt(2)
for i in range(N):
arr_tensor.append(H)
arr_arm.append(arr_state[i] + kanji[n_kanji])
arr_state[i] = kanji[n_kanji]
n_kanji += 1
arr_arm
['一',
'七',
'万',
'三',
'上',
'下',
'中',
'九',
'二',
'五',
'人',
'今',
'休',
'何',
'先',
'入',
'一八',
'七六',
'万円',
'三出',
'上分',
'下前',
'中北',
'九十',
'二千',
'五午',
'人半',
'今南',
'休友',
'何右',
'先名',
'入四']
arr_state
['八',
'六',
'円',
'出',
'分',
'前',
'北',
'十',
'千',
'午',
'半',
'南',
'友',
'右',
'名',
'四']
z = oe.contract(','.join(arr_arm), *arr_tensor)
print(z.shape)
print(z.reshape(2**N))
(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2)
[0.00390625 0.00390625 0.00390625 ... 0.00390625 0.00390625 0.00390625]
ここまでは何とか計算ができていそうです。次にZZをかけます。なんか普通に量子状態に漢字が並んでるのが異様です。。。
theta = np.random.rand()*np.pi*2
ZZ = np.array([[np.exp(-1*1j*theta/2),0,0,0],[0,np.exp(-1*1j*theta/2),0,0],[0,0,np.exp(1j*theta/2),0],[0,0,0,np.exp(-1*1j*theta/2)]]).reshape(2,2,2,2)
for item in l2:
in1 = item[0]
in2 = item[1]
arr_tensor.append(ZZ)
arr_arm.append(arr_state[in1] + arr_state[in2] + kanji[n_kanji] + kanji[n_kanji+1])
arr_state[in1] = kanji[n_kanji]
arr_state[in2] = kanji[n_kanji+1]
n_kanji += 2
arr_arm
['一',
'七',
'万',
'三',
'上',
'下',
'中',
'九',
'二',
'五',
'人',
'今',
'休',
'何',
'先',
'入',
'一八',
'七六',
'万円',
'三出',
'上分',
'下前',
'中北',
'九十',
'二千',
'五午',
'人半',
'今南',
'休友',
'何右',
'先名',
'入四',
'八六国土',
'土円外大',
'大出天女',
'女分子学',
'学前小山',
'山北川左',
'左十年後',
'後千日時',
'時午書月',
'月半木本',
'本南来東',
'東友校母',
'母右毎気',
'気名水火',
'火四父生',
'生国男白',
'川書百聞',
'日毎行西',
'白子見話',
'天父語読',
'行木車金',
'車校長間',
'見読雨電',
'年水食高',
'高男不世',
'聞西主事',
'長来京仕',
'仕不代以',
'食主会住',
'語京体作',
'作電使借',
'外借元兄',
'間世公写',
'元金冬切',
'切以別力']
arr_state
['雨',
'冬',
'体',
'話',
'小',
'百',
'会',
'使',
'住',
'別',
'代',
'公',
'事',
'力',
'兄',
'写']
最後にRXをいれてみます
theta2 = np.random.rand()*np.pi*2
RX = np.array([[np.cos(theta2/2),-1j*np.sin(theta2/2)],[-1j*np.sin(theta2/2),np.cos(theta2/2)]])
for i in range(N):
arr_tensor.append(RX)
arr_arm.append(arr_state[i] + kanji[n_kanji])
arr_state[i] = kanji[n_kanji]
n_kanji += 1
arr_arm
['一',
'七',
'万',
'三',
'上',
'下',
'中',
'九',
'二',
'五',
'人',
'今',
'休',
'何',
'先',
'入',
'一八',
'七六',
'万円',
'三出',
'上分',
'下前',
'中北',
'九十',
'二千',
'五午',
'人半',
'今南',
'休友',
'何右',
'先名',
'入四',
'八六国土',
'土円外大',
'大出天女',
'女分子学',
'学前小山',
'山北川左',
'左十年後',
'後千日時',
'時午書月',
'月半木本',
'本南来東',
'東友校母',
'母右毎気',
'気名水火',
'火四父生',
'生国男白',
'川書百聞',
'日毎行西',
'白子見話',
'天父語読',
'行木車金',
'車校長間',
'見読雨電',
'年水食高',
'高男不世',
'聞西主事',
'長来京仕',
'仕不代以',
'食主会住',
'語京体作',
'作電使借',
'外借元兄',
'間世公写',
'元金冬切',
'切以別力',
'雨勉',
'冬動',
'体医',
'話去',
'小口',
'百古',
'会台',
'使同',
'住味',
'別品',
'代員',
'公問',
'事図',
'力地',
'兄堂',
'写場']
arr_state
['勉',
'動',
'医',
'去',
'口',
'古',
'台',
'同',
'味',
'品',
'員',
'問',
'図',
'地',
'堂',
'場']
もう何が何だかわかりませんが、計算してみます。
z = oe.contract(','.join(arr_arm), *arr_tensor)
print(z.shape)
print(z.reshape(2**N))
(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2)
[ 0.0008775 -0.00326995j -0.00194918-0.00289222j -0.00191659-0.00285363j
... 0.00229058+0.00254962j -0.00280193+0.0020605j
0.00093102-0.00331639j]
なんと、本当に計算できてしまいました。。。漢字でQAOAでした。以上です。