numpy einsum使いたいのですが、どうやら内部でアルファベット26文字、大文字入れて最大で52文字までしか対応していないようなので、opt_einsumを使ってみたいと思います。
参考:https://stackoverflow.com/questions/37794245/can-i-use-more-than-26-letters-in-numpy-einsum
opt_einsumはnp einsumを補完するように作られているようなので、これを使って量子回路を作れそうです。
!pip install opt_einsum
Requirement already satisfied: opt_einsum in /opt/conda/lib/python3.8/site-packages (3.3.0)
Requirement already satisfied: numpy>=1.7 in /opt/conda/lib/python3.8/site-packages (from opt_einsum) (1.20.3)
さっそくやってみます。
import opt_einsum as oe
import numpy as np
eq = 'ijk,jkl->li'
x, y = np.random.rand(2, 3, 4), np.random.rand(3, 4, 5)
z = oe.contract(eq, x, y)
print(z.shape)
print(z)
(5, 2)
[[2.93348565 4.03278847]
[2.47684638 3.56888907]
[2.72089004 3.13084908]
[2.16161143 3.28362895]
[2.23121202 3.25787689]]
さっそくopt_einsumの特徴です!26文字のアルファベットに限りません!
eq = "αβγ,βγδ->δα"
oe.contract(eq, x, y).shape
(5, 2)
素晴らしい。通し番号で管理もできます。
oe.get_symbol(805)
'α'
oe.get_symbol(30000)
'疼'
もうなんか漢字でいいんですね。。。
eq = "疼βγ,βγδ->δ疼"
oe.contract(eq, x, y).shape
(5, 2)
計算できました。。。せっかくなんで、漢字でやっちゃいます。
H+CXのもつれ回路を作ってみましょう。
psi1 = np.array([1,0])
psi2 = np.array([1,0])
H = np.array([[1,1],[1,-1]])/np.sqrt(2)
CX = np.array([[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]]).reshape(2,2,2,2)
psi = oe.contract('湊,郎,湊雄,雄郎一様', psi1,psi2,H,CX)
psi.reshape(4)
array([0.70710678, 0. , 0. , 0.70710678])
もうこれで大規模量子回路もばっちりです!