电路基础#
概述#
在这篇笔记中,我们将了解 TensorCircuit 中核心对象的基本操作-tc.Circuit
,它支持无噪声仿真和基于蒙特卡洛轨迹的噪声仿真。更重要的是,几乎所有对 Circuit 对象的操作都是可微分的和可即时编译的,这是成功高效地进行变分量子算法模拟的关键。 [WIP note]
设置#
[1]:
from functools import partial
import inspect
import sys
import numpy as np
import tensorflow as tf
import tensorcircuit as tc
“Hello World" 样例#
[2]:
def get_circuit(n):
c = tc.Circuit(n) # 用 n 个量子比特初始化一个电路对象
for i in range(n):
c.H(i) # 在每个量子比特上使用 Hadamard 门
c.cnot(0, 1) # 在第 0 个量子比特上应用带有控制量子比特的 cnot 门
c.CNOT(n - 1, n - 2) # 大写的 API 也可以正常使用
return c
[3]:
# 打印不含参数的有可能的门
print(tc.Circuit.sgates)
['i', 'x', 'y', 'z', 'h', 't', 's', 'td', 'sd', 'wroot', 'cnot', 'cz', 'swap', 'cy', 'iswap', 'ox', 'oy', 'oz', 'toffoli', 'fredkin']
[4]:
# 这些门定义的相应矩阵
for g in tc.Circuit.sgates:
gf = getattr(tc.gates, g)
print(g)
print(tc.gates.matrix_for_gate(gf()))
i
[[1.+0.j 0.+0.j]
[0.+0.j 1.+0.j]]
x
[[0.+0.j 1.+0.j]
[1.+0.j 0.+0.j]]
y
[[0.+0.j 0.-1.j]
[0.+1.j 0.+0.j]]
z
[[ 1.+0.j 0.+0.j]
[ 0.+0.j -1.+0.j]]
h
[[ 0.70710677+0.j 0.70710677+0.j]
[ 0.70710677+0.j -0.70710677+0.j]]
t
[[1. +0.j 0. +0.j ]
[0. +0.j 0.70710677+0.70710677j]]
s
[[1.+0.j 0.+0.j]
[0.+0.j 0.+1.j]]
td
[[1. +0.j 0. +0.j ]
[0. +0.j 0.70710677-0.70710677j]]
sd
[[1.+0.j 0.+0.j]
[0.+0.j 0.-1.j]]
wroot
[[ 0.70710677+0.j -0.5 -0.5j]
[ 0.5 -0.5j 0.70710677+0.j ]]
cnot
[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 1.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 1.+0.j]
[0.+0.j 0.+0.j 1.+0.j 0.+0.j]]
cz
[[ 1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[ 0.+0.j 1.+0.j 0.+0.j 0.+0.j]
[ 0.+0.j 0.+0.j 1.+0.j 0.+0.j]
[ 0.+0.j 0.+0.j 0.+0.j -1.+0.j]]
swap
[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 1.+0.j 0.+0.j]
[0.+0.j 1.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 1.+0.j]]
cy
[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 1.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 0.-1.j]
[0.+0.j 0.+0.j 0.+1.j 0.+0.j]]
iswap
[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+1.j 0.+0.j]
[0.+0.j 0.+1.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 1.+0.j]]
ox
[[0.+0.j 1.+0.j 0.+0.j 0.+0.j]
[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 1.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 1.+0.j]]
oy
[[0.+0.j 0.-1.j 0.+0.j 0.+0.j]
[0.+1.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 1.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 1.+0.j]]
oz
[[ 1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[ 0.+0.j -1.+0.j 0.+0.j 0.+0.j]
[ 0.+0.j 0.+0.j 1.+0.j 0.+0.j]
[ 0.+0.j 0.+0.j 0.+0.j 1.+0.j]]
toffoli
[[1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j]
[0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j]]
fredkin
[[1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j 0.+0.j 0.+0.j]
[0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j]]
[5]:
c = get_circuit(3)
ir = c.to_qir() # 电路的中间表示
ir
[5]:
[{'gatef': h,
'gate': Gate(
name: 'h',
tensor:
array([[ 0.70710677+0.j, 0.70710677+0.j],
[ 0.70710677+0.j, -0.70710677+0.j]], dtype=complex64),
edges: [
Edge('cnot'[2] -> 'h'[0] ),
Edge('h'[1] -> 'qb-1'[0] )
]),
'index': (0,),
'name': 'h',
'split': None,
'mpo': False},
{'gatef': h,
'gate': Gate(
name: 'h',
tensor:
array([[ 0.70710677+0.j, 0.70710677+0.j],
[ 0.70710677+0.j, -0.70710677+0.j]], dtype=complex64),
edges: [
Edge('cnot'[3] -> 'h'[0] ),
Edge('h'[1] -> 'qb-2'[0] )
]),
'index': (1,),
'name': 'h',
'split': None,
'mpo': False},
{'gatef': h,
'gate': Gate(
name: 'h',
tensor:
array([[ 0.70710677+0.j, 0.70710677+0.j],
[ 0.70710677+0.j, -0.70710677+0.j]], dtype=complex64),
edges: [
Edge('cnot'[2] -> 'h'[0] ),
Edge('h'[1] -> 'qb-3'[0] )
]),
'index': (2,),
'name': 'h',
'split': None,
'mpo': False},
{'gatef': cnot,
'gate': Gate(
name: 'cnot',
tensor:
array([[[[1.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j]],
[[0.+0.j, 1.+0.j],
[0.+0.j, 0.+0.j]]],
[[[0.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j]],
[[0.+0.j, 0.+0.j],
[1.+0.j, 0.+0.j]]]], dtype=complex64),
edges: [
Edge(Dangling Edge)[0],
Edge('cnot'[3] -> 'cnot'[1] ),
Edge('cnot'[2] -> 'h'[0] ),
Edge('cnot'[3] -> 'h'[0] )
]),
'index': (0, 1),
'name': 'cnot',
'split': None,
'mpo': False},
{'gatef': cnot,
'gate': Gate(
name: 'cnot',
tensor:
array([[[[1.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j]],
[[0.+0.j, 1.+0.j],
[0.+0.j, 0.+0.j]]],
[[[0.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j]],
[[0.+0.j, 0.+0.j],
[1.+0.j, 0.+0.j]]]], dtype=complex64),
edges: [
Edge(Dangling Edge)[0],
Edge(Dangling Edge)[1],
Edge('cnot'[2] -> 'h'[0] ),
Edge('cnot'[3] -> 'cnot'[1] )
]),
'index': (2, 1),
'name': 'cnot',
'split': None,
'mpo': False}]
[6]:
ir[0]["gatef"]().tensor, ir[-1]["gate"].tensor # 每个门的实际幺正矩阵
[6]:
(array([[ 0.70710677+0.j, 0.70710677+0.j],
[ 0.70710677+0.j, -0.70710677+0.j]], dtype=complex64),
array([[[[1.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j]],
[[0.+0.j, 1.+0.j],
[0.+0.j, 0.+0.j]]],
[[[0.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j]],
[[0.+0.j, 0.+0.j],
[1.+0.j, 0.+0.j]]]], dtype=complex64))
[7]:
# 计算电路的最终输出量子态
c.state()
[7]:
array([0.35355335+0.j, 0.35355335+0.j, 0.35355335+0.j, 0.35355335+0.j,
0.35355335+0.j, 0.35355335+0.j, 0.35355335+0.j, 0.35355335+0.j],
dtype=complex64)
[8]:
# 计算一些期望值,比如 <X1>
x1 = c.expectation([tc.gates.x(), [1]])
# 或 <Z1Z2>
z1z2 = c.expectation([tc.gates.z(), [1]], [tc.gates.z(), [2]])
print(x1, z1z2)
(0.9999998+0j) 0j
[9]:
# 做一些随机取样
for _ in range(10):
print(c.perfect_sampling())
(array([1., 1., 1.], dtype=float32), 0.1250001713634208)
(array([0., 0., 1.], dtype=float32), 0.12499997764825821)
(array([0., 1., 1.], dtype=float32), 0.12499997764825821)
(array([1., 1., 0.], dtype=float32), 0.1249999776482098)
(array([1., 1., 0.], dtype=float32), 0.1249999776482098)
(array([1., 0., 1.], dtype=float32), 0.12499997019766829)
(array([0., 1., 0.], dtype=float32), 0.12499997764825821)
(array([1., 1., 0.], dtype=float32), 0.1249999776482098)
(array([0., 0., 0.], dtype=float32), 0.12499997764825821)
(array([0., 1., 1.], dtype=float32), 0.12499997764825821)
[10]:
# 我们可以轻松地从 NumPy 切换模拟后端!
with tc.runtime_backend("tensorflow") as K:
c = get_circuit(3)
print(c.state())
with tc.runtime_backend("jax") as K:
c = get_circuit(3)
print(c.state())
with tc.runtime_backend("pytorch") as K:
# pytorch 后端无法保证最佳性能和完整功能
c = get_circuit(3)
print(c.state())
tf.Tensor(
[0.35355335+0.j 0.35355335+0.j 0.35355335+0.j 0.35355335+0.j
0.35355335+0.j 0.35355335+0.j 0.35355335+0.j 0.35355335+0.j], shape=(8,), dtype=complex64)
WARNING:absl:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)
[0.35355335+0.j 0.35355335+0.j 0.35355335+0.j 0.35355335+0.j
0.35355335+0.j 0.35355335+0.j 0.35355335+0.j 0.35355335+0.j]
tensor([0.3536+0.j, 0.3536+0.j, 0.3536+0.j, 0.3536+0.j, 0.3536+0.j, 0.3536+0.j, 0.3536+0.j,
0.3536+0.j])
参数化量子电路(PQC)#
[11]:
# 接受参数的量子电路门
print(tc.Circuit.vgates)
['r', 'cr', 'rx', 'ry', 'rz', 'crx', 'cry', 'crz', 'orx', 'ory', 'orz', 'any', 'exp', 'exp1']
[12]:
# 查看每种类型的变量门的关键字参数(类型为浮点数)
for g in tc.Circuit.vgates:
print(g, inspect.signature(getattr(tc.gates, g).f))
r (theta: float = 0, alpha: float = 0, phi: float = 0) -> tensorcircuit.gates.Gate
cr (theta: float = 0, alpha: float = 0, phi: float = 0) -> tensorcircuit.gates.Gate
rx (theta: float = 0) -> tensorcircuit.gates.Gate
ry (theta: float = 0) -> tensorcircuit.gates.Gate
rz (theta: float = 0) -> tensorcircuit.gates.Gate
crx (*args: Any, **kws: Any) -> Any
cry (*args: Any, **kws: Any) -> Any
crz (*args: Any, **kws: Any) -> Any
orx (*args: Any, **kws: Any) -> Any
ory (*args: Any, **kws: Any) -> Any
orz (*args: Any, **kws: Any) -> Any
any (unitary: Any, name: str = 'any') -> tensorcircuit.gates.Gate
exp (unitary: Any, theta: float, name: str = 'none') -> tensorcircuit.gates.Gate
exp1 (unitary: Any, theta: float, name: str = 'none') -> tensorcircuit.gates.Gate
[13]:
def get_circuit(n, params):
c = tc.Circuit(n) # 用 n 个量子比特初始化一个电路对象
for i in range(n):
c.rx(i, theta=params[i]) # 应用 rx 门
c.cnot(0, 1)
return c
[14]:
K = tc.set_backend("tensorflow")
[15]:
n = 3
params = K.ones([n])
c = get_circuit(n, params)
print(c.state())
tf.Tensor(
[ 0.6758712 +0.j 0. -0.36923012j 0. -0.36923015j
-0.20171136-0.j -0.20171136+0.j 0. +0.11019541j
0. -0.36923015j -0.20171136-0.j ], shape=(8,), dtype=complex64)
[16]:
ir = c.to_qir()
ir
[16]:
[{'gatef': rx,
'index': (0,),
'name': 'rx',
'split': None,
'mpo': False,
'parameters': {'theta': <tf.Tensor: shape=(), dtype=complex64, numpy=(1+0j)>},
'gate': Gate(
name: '__unnamed_node__',
tensor:
<tf.Tensor: shape=(2, 2), dtype=complex64, numpy=
array([[0.87758255+0.j , 0. -0.47942555j],
[0. -0.47942555j, 0.87758255+0.j ]], dtype=complex64)>,
edges: [
Edge('cnot'[2] -> '__unnamed_node__'[0] ),
Edge('__unnamed_node__'[1] -> 'qb-1'[0] )
])},
{'gatef': rx,
'index': (1,),
'name': 'rx',
'split': None,
'mpo': False,
'parameters': {'theta': <tf.Tensor: shape=(), dtype=complex64, numpy=(1+0j)>},
'gate': Gate(
name: '__unnamed_node__',
tensor:
<tf.Tensor: shape=(2, 2), dtype=complex64, numpy=
array([[0.87758255+0.j , 0. -0.47942555j],
[0. -0.47942555j, 0.87758255+0.j ]], dtype=complex64)>,
edges: [
Edge('cnot'[3] -> '__unnamed_node__'[0] ),
Edge('__unnamed_node__'[1] -> 'qb-2'[0] )
])},
{'gatef': rx,
'index': (2,),
'name': 'rx',
'split': None,
'mpo': False,
'parameters': {'theta': <tf.Tensor: shape=(), dtype=complex64, numpy=(1+0j)>},
'gate': Gate(
name: '__unnamed_node__',
tensor:
<tf.Tensor: shape=(2, 2), dtype=complex64, numpy=
array([[0.87758255+0.j , 0. -0.47942555j],
[0. -0.47942555j, 0.87758255+0.j ]], dtype=complex64)>,
edges: [
Edge(Dangling Edge)[0],
Edge('__unnamed_node__'[1] -> 'qb-3'[0] )
])},
{'gatef': cnot,
'gate': Gate(
name: 'cnot',
tensor:
<tf.Tensor: shape=(2, 2, 2, 2), dtype=complex64, numpy=
array([[[[1.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j]],
[[0.+0.j, 1.+0.j],
[0.+0.j, 0.+0.j]]],
[[[0.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j]],
[[0.+0.j, 0.+0.j],
[1.+0.j, 0.+0.j]]]], dtype=complex64)>,
edges: [
Edge(Dangling Edge)[0],
Edge(Dangling Edge)[1],
Edge('cnot'[2] -> '__unnamed_node__'[0] ),
Edge('cnot'[3] -> '__unnamed_node__'[0] )
]),
'index': (0, 1),
'name': 'cnot',
'split': None,
'mpo': False}]
[17]:
# 查看量子门对应的矩阵
ir[0]["gatef"](**ir[0]["parameters"]).tensor
[17]:
<tf.Tensor: shape=(2, 2), dtype=complex64, numpy=
array([[0.87758255+0.j , 0. -0.47942555j],
[0. -0.47942555j, 0.87758255+0.j ]], dtype=complex64)>
[18]:
# 让我们组成一个可微分的量子函数
def energy(params):
c = get_circuit(n, params)
return K.real(c.expectation([tc.gates.z(), [1]]))
energy_vag = K.value_and_grad(energy)
print(energy_vag(params))
# 一旦我们有了梯度,我们就可以运行基于梯度的下降的变分优化
(<tf.Tensor: shape=(), dtype=float32, numpy=0.2919265>, <tf.Tensor: shape=(3,), dtype=complex64, numpy=
array([-4.5464873e-01+0.j, -4.5464873e-01+0.j, 2.2351742e-08+0.j],
dtype=complex64)>)
[19]:
# 并且使其可即时编译以加速
energy_vag_jit = K.jit(K.value_and_grad(energy))
print(energy_vag_jit(params))
# 第一次运行可即时编译的函数会很慢,但是后面的测量会超级快
(<tf.Tensor: shape=(), dtype=float32, numpy=0.2919265>, <tf.Tensor: shape=(3,), dtype=complex64, numpy=
array([-4.5464873e-01+0.j, -4.5464873e-01+0.j, 2.2351742e-08+0.j],
dtype=complex64)>)
电路的高级用法#
输入状态#
我们可以从默认的 |0^n> 替换输入状态
[20]:
input_state = K.ones([2**n])
input_state /= K.norm(input_state)
c = tc.Circuit(n, inputs=input_state)
c.H(0)
c.state()
[20]:
<tf.Tensor: shape=(8,), dtype=complex64, numpy=
array([0.49999997+0.j, 0.49999997+0.j, 0.49999997+0.j, 0.49999997+0.j,
0. +0.j, 0. +0.j, 0. +0.j, 0. +0.j],
dtype=complex64)>
蒙特卡罗方法噪声模拟#
tc.Circuit
支持使用蒙特卡罗方法进行噪声模拟,并且它也是可即时编译的! 此外,tc.DMCircuit
支持使用全密度矩阵方法进行噪声模拟。
[21]:
c = tc.Circuit(n)
for i in range(n):
c.H(i)
for i in range(n - 1):
c.cnot(i, i + 1)
c.depolarizing(i, px=0.1, py=0.1, pz=0.1)
c.apply_general_kraus(tc.channels.phasedampingchannel(gamma=0.2), i + 1)
print(c.expectation([tc.gates.y(), [1]]))
tf.Tensor(0j, shape=(), dtype=complex64)
应用任意幺正门#
只需直接使用 any
API 通过提供相应的幺正矩阵
[22]:
c = tc.Circuit(n)
c.any(0, 1, unitary=K.ones([4, 4]) / K.norm(K.ones([4, 4])))
c.state()
[22]:
<tf.Tensor: shape=(8,), dtype=complex64, numpy=
array([0.25+0.j, 0. +0.j, 0.25+0.j, 0. +0.j, 0.25+0.j, 0. +0.j,
0.25+0.j, 0. +0.j], dtype=complex64)>
指数门#
如果我们想将门模拟为 \(e^{i\theta G}\) ,其中 \(G^2=1\) 是一个矩阵,我们有一个快速有效的门实现,例如 exp1
[23]:
c = tc.Circuit(n)
for i in range(n):
c.H(i)
for i in range(n - 1):
c.exp1(i, i + 1, theta=K.ones([]), unitary=tc.gates._zz_matrix)
c.state()
[23]:
<tf.Tensor: shape=(8,), dtype=complex64, numpy=
array([-0.14713009-3.2148516e-01j, 0.35355335+1.4901161e-08j,
-0.14713009+3.2148516e-01j, 0.35355335-1.4901161e-08j,
0.35355335-1.4901161e-08j, -0.14713009+3.2148516e-01j,
0.35355335+1.4901161e-08j, -0.14713009-3.2148516e-01j],
dtype=complex64)>
在上面的例子中 \(G=Z\otimes Z\)
[24]:
print(tc.gates._zz_matrix)
[[ 1. 0. 0. 0.]
[ 0. -1. 0. -0.]
[ 0. 0. -1. -0.]
[ 0. -0. -0. 1.]]
下面列出了门模块中的常用矩阵
[25]:
for name in dir(tc.gates):
if name.endswith("_matrix"):
print(name, ":\n", getattr(tc.gates, name))
_cnot_matrix :
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 0. 1.]
[0. 0. 1. 0.]]
_cy_matrix :
[[ 1.+0.j 0.+0.j 0.+0.j 0.+0.j]
[ 0.+0.j 1.+0.j 0.+0.j 0.+0.j]
[ 0.+0.j 0.+0.j 0.+0.j -0.-1.j]
[ 0.+0.j 0.+0.j 0.+1.j 0.+0.j]]
_cz_matrix :
[[ 1. 0. 0. 0.]
[ 0. 1. 0. 0.]
[ 0. 0. 1. 0.]
[ 0. 0. 0. -1.]]
_fredkin_matrix :
[[1. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 1. 0.]
[0. 0. 0. 0. 0. 1. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1.]]
_h_matrix :
[[ 0.70710678 0.70710678]
[ 0.70710678 -0.70710678]]
_i_matrix :
[[1. 0.]
[0. 1.]]
_ii_matrix :
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]
_s_matrix :
[[1.+0.j 0.+0.j]
[0.+0.j 0.+1.j]]
_swap_matrix :
[[1. 0. 0. 0.]
[0. 0. 1. 0.]
[0. 1. 0. 0.]
[0. 0. 0. 1.]]
_t_matrix :
[[1. +0.j 0. +0.j ]
[0. +0.j 0.70710678+0.70710678j]]
_toffoli_matrix :
[[1. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0. 0.]
[0. 0. 0. 0. 0. 1. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 1.]
[0. 0. 0. 0. 0. 0. 1. 0.]]
_wroot_matrix :
[[ 0.70710678+0.j -0.5 -0.5j]
[ 0.5 -0.5j 0.70710678+0.j ]]
_x_matrix :
[[0. 1.]
[1. 0.]]
_xx_matrix :
[[0. 0. 0. 1.]
[0. 0. 1. 0.]
[0. 1. 0. 0.]
[1. 0. 0. 0.]]
_y_matrix :
[[ 0.+0.j -0.-1.j]
[ 0.+1.j 0.+0.j]]
_yy_matrix :
[[ 0.+0.j 0.-0.j 0.-0.j -1.+0.j]
[ 0.+0.j 0.+0.j 1.-0.j 0.-0.j]
[ 0.+0.j 1.-0.j 0.+0.j 0.-0.j]
[-1.+0.j 0.+0.j 0.+0.j 0.+0.j]]
_z_matrix :
[[ 1. 0.]
[ 0. -1.]]
_zz_matrix :
[[ 1. 0. 0. 0.]
[ 0. -1. 0. -0.]
[ 0. 0. -1. -0.]
[ 0. -0. -0. 1.]]
非幺正门#
tc.Circuit
由于其张量网络引擎性质而自动支持非幺正电路仿真
[26]:
c = tc.Circuit(n)
c.exp1(1, unitary=tc.gates._x_matrix, theta=K.ones([]) + 1.0j * K.ones([]))
c.state()
[26]:
<tf.Tensor: shape=(8,), dtype=complex64, numpy=
array([0.83373 -0.9888977j, 0. +0.j ,
0.63496387-1.2984576j, 0. +0.j ,
0. +0.j , 0. +0.j ,
0. +0.j , 0. +0.j ], dtype=complex64)>
请注意,在这种情况下,最终量子态不再归一化。
[27]:
try:
np.testing.assert_allclose(K.norm(c.state()), 1.0)
except AssertionError as e:
print(e)
Not equal to tolerance rtol=1e-07, atol=0
Mismatched elements: 1 / 1 (100%)
Max absolute difference: 0.93963802
Max relative difference: 0.93963802
x: array(1.939638+0.j, dtype=complex64)
y: array(1.)