-
Notifications
You must be signed in to change notification settings - Fork 81
/
Copy pathmpsvsexact.py
91 lines (77 loc) · 2.34 KB
/
mpsvsexact.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
"""
A simple script to benchmark the approximation power of the MPS simulator.
"""
import sys
sys.path.insert(0, "../")
import tensorcircuit as tc
tc.set_backend("tensorflow")
tc.set_dtype("complex128")
def tfi_energy(c, n, j=1.0, h=-1.0):
e = 0.0
for i in range(n):
e += h * c.expectation((tc.gates.x(), [i]))
for i in range(n - 1):
e += j * c.expectation((tc.gates.z(), [i]), (tc.gates.z(), [(i + 1) % n]))
return e
def energy(param, mpsd=None):
if mpsd is None:
c = tc.Circuit(n)
else:
c = tc.MPSCircuit(n)
c.set_split_rules({"max_singular_values": mpsd})
for i in range(n):
c.H(i)
for j in range(nlayers):
for i in range(n - 1):
c.exp1(
i,
(i + 1) % n,
theta=param[2 * j, i],
unitary=tc.gates._zz_matrix,
)
for i in range(n):
c.rx(i, theta=param[2 * j + 1, i])
e = tfi_energy(c, n)
e = tc.backend.real(e)
if mpsd is not None:
fidelity = c._fidelity
else:
fidelity = None
return e, c.state(), fidelity
n, nlayers = 15, 20
print("number of qubits: ", n)
print("number of layers: ", nlayers)
param = tc.backend.implicit_randu([2 * nlayers, n])
# param = tc.backend.ones([2 * nlayers, n])
# it turns out that the mps approximation power highly depends on the
# parameters, if we use ``param = tc.backend.ones``, the apprixmation ratio decays very fast
# At least, the estimated fidelity is a very good proxy metric for real fidelity
# as long as it is larger than 50%
e0, s0, _ = energy(param)
print(
"entanglement: ",
tc.backend.numpy(
tc.quantum.entropy(tc.quantum.reduced_density_matrix(s0, cut=n // 2))
),
)
for mpsd in [2, 5, 10, 20, 50, 100]:
e1, s1, f1 = energy(param, mpsd=mpsd)
print("------------------------")
print("bond dimension: ", mpsd)
print(
"exact energy: ",
tc.backend.numpy(e0),
"mps simulator energy: ",
tc.backend.numpy(e1),
)
print(
"energy relative error(%): ",
tc.backend.numpy(tc.backend.abs((e1 - e0) / e0)) * 100,
)
print("estimated fidelity:", tc.backend.numpy(f1))
print(
"real fidelity:",
tc.backend.numpy(
tc.backend.abs(tc.backend.tensordot(tc.backend.conj(s1), s0, 1))
),
)