Skip to content

Commit 84c3f54

Browse files
committed
reformat the SHVQE script
1 parent 9a32bab commit 84c3f54

File tree

1 file changed

+48
-39
lines changed

1 file changed

+48
-39
lines changed

examples/shvqe.py

+48-39
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""
66

77
import sys
8+
89
sys.path.insert(0, "../")
910

1011
import numpy as np
@@ -16,9 +17,9 @@
1617
ctype, rtype = tc.set_dtype("complex64")
1718
K = tc.set_backend("tensorflow")
1819

19-
n = 10 # the number of qubits (must be even for consistency later)
20-
ncz = 2 # number of cz layers in Schrodinger circuit
21-
nlayersq = ncz + 1 # Schrodinger parameter layers
20+
n = 10 # the number of qubits (must be even for consistency later)
21+
ncz = 2 # number of cz layers in Schrodinger circuit
22+
nlayersq = ncz + 1 # Schrodinger parameter layers
2223

2324
# training setup
2425
epochs = 1000
@@ -28,6 +29,7 @@
2829
h6h = np.load("./h6_hamiltonian.npy") # reported in 0.99 A
2930
hamiltonian = construct_matrix_v3(h6h.tolist())
3031

32+
3133
def hybrid_ansatz(structure, paramq, preprocess="direct", train=True):
3234
"""_summary_
3335
@@ -54,50 +56,51 @@ def hybrid_ansatz(structure, paramq, preprocess="direct", train=True):
5456
pass
5557

5658
structure = K.cast(structure, ctype)
57-
structure = tf.reshape(structure, shape=[n//2, 2])
59+
structure = tf.reshape(structure, shape=[n // 2, 2])
5860

5961
# quantum variational in Schrodinger part, first consider a ring topol
6062
for j in range(nlayersq):
61-
if j !=0 and j!=nlayersq-1:
62-
for i in range(j%2,n,2):
63-
c.cz(i, (i+1)%n)
63+
if j != 0 and j != nlayersq - 1:
64+
for i in range(j % 2, n, 2):
65+
c.cz(i, (i + 1) % n)
6466
for i in range(n):
6567
c.rx(i, theta=paramq[j, i, 0])
6668
c.ry(i, theta=paramq[j, i, 1])
6769
c.rz(i, theta=paramq[j, i, 2])
6870

6971
# Clifford part, which is actually virtual
7072
if train:
71-
for j in range(0,n//2-1):
73+
for j in range(0, n // 2 - 1):
7274
dis = j + 1
73-
for i in range(0,n):
75+
for i in range(0, n):
7476
c.unitary(
7577
i,
76-
(i+dis) % n,
78+
(i + dis) % n,
7779
unitary=structure[j, 0] * tc.gates.ii().tensor
7880
+ structure[j, 1] * tc.gates.cz().tensor,
7981
)
8082

81-
for i in range(0,n//2):
83+
for i in range(0, n // 2):
8284
c.unitary(
8385
i,
84-
i + n//2,
85-
unitary=structure[n//2-1, 0] * tc.gates.ii().tensor
86-
+ structure[n//2-1, 1] * tc.gates.cz().tensor,
86+
i + n // 2,
87+
unitary=structure[n // 2 - 1, 0] * tc.gates.ii().tensor
88+
+ structure[n // 2 - 1, 1] * tc.gates.cz().tensor,
8789
)
88-
else: # if not for training, we just put nontrivial gates
89-
for j in range(0,n//2-1):
90+
else: # if not for training, we just put nontrivial gates
91+
for j in range(0, n // 2 - 1):
9092
dis = j + 1
91-
for i in range(0,n):
92-
if structure[j, 1]==1:
93-
c.cz(i, (i+dis) % n)
93+
for i in range(0, n):
94+
if structure[j, 1] == 1:
95+
c.cz(i, (i + dis) % n)
9496

95-
for i in range(0,n//2):
96-
if structure[j, 1]==1:
97-
c.cz(i, i + n//2)
97+
for i in range(0, n // 2):
98+
if structure[j, 1] == 1:
99+
c.cz(i, i + n // 2)
98100

99101
return c
100102

103+
101104
def hybrid_vqe(structure, paramq, preprocess="direct"):
102105
"""_summary_
103106
@@ -118,6 +121,7 @@ def hybrid_vqe(structure, paramq, preprocess="direct"):
118121
c = hybrid_ansatz(structure, paramq, preprocess)
119122
return tc.templates.measurements.operator_expectation(c, hamiltonian)
120123

124+
121125
def sampling_from_structure(structures, batch=1):
122126
ch = structures.shape[-1]
123127
prob = K.softmax(K.real(structures), axis=-1)
@@ -137,7 +141,7 @@ def best_from_structure(structures):
137141

138142

139143
def nmf_gradient(structures, oh):
140-
""" compute the Monte Carlo gradient with respect of naive mean-field probabilistic model
144+
"""compute the Monte Carlo gradient with respect of naive mean-field probabilistic model
141145
142146
Parameters
143147
----------
@@ -166,21 +170,25 @@ def nmf_gradient(structures, oh):
166170
indices,
167171
tf.ones([structures.shape[0]], dtype=ctype),
168172
)
169-
) # in oh : 1-p, not in oh : -p
173+
) # in oh : 1-p, not in oh : -p
174+
170175

171176
# vmap for a batch of structures
172-
nmf_gradient_vmap = K.jit(
173-
K.vmap(nmf_gradient, vectorized_argnums=1))
177+
nmf_gradient_vmap = K.jit(K.vmap(nmf_gradient, vectorized_argnums=1))
174178

175179
# vvag for a batch of structures
176180
vvag_hybrid = K.jit(
177181
K.vectorized_value_and_grad(hybrid_vqe, vectorized_argnums=(0,), argnums=(1,)),
178-
static_argnums=(2,))
182+
static_argnums=(2,),
183+
)
184+
179185

180-
def train_hybrid(stddev=0.05, lr=None, epochs=2000, debug_step=50, batch=256, verbose=False):
186+
def train_hybrid(
187+
stddev=0.05, lr=None, epochs=2000, debug_step=50, batch=256, verbose=False
188+
):
181189
# params = K.implicit_randn([n//2, 2], stddev=stddev)
182-
params = K.ones([n//2, 2], dtype=float)
183-
paramq = K.implicit_randn([nlayersq, n, 3], stddev=stddev) * 2*np.pi
190+
params = K.ones([n // 2, 2], dtype=float)
191+
paramq = K.implicit_randn([nlayersq, n, 3], stddev=stddev) * 2 * np.pi
184192
if lr is None:
185193
lr = tf.keras.optimizers.schedules.ExponentialDecay(0.6, 100, 0.8)
186194
structure_opt = K.optimizer(tf.keras.optimizers.Adam(lr))
@@ -197,7 +205,7 @@ def train_hybrid(stddev=0.05, lr=None, epochs=2000, debug_step=50, batch=256, ve
197205
vs, gq = vvag_hybrid(batched_stucture, paramq, "direct")
198206
loss_history.append(np.min(vs))
199207
gq = gq[0]
200-
avcost = K.mean(vs) # average cost of the batch
208+
avcost = K.mean(vs) # average cost of the batch
201209
gs = nmf_gradient_vmap(params, batched_stucture) # \nabla lnp
202210
gs = K.mean(K.reshape(vs - avcost2, [-1, 1, 1]) * gs, axis=0)
203211
# avcost2 is averaged cost in the last epoch
@@ -214,15 +222,14 @@ def train_hybrid(stddev=0.05, lr=None, epochs=2000, debug_step=50, batch=256, ve
214222
)
215223

216224
# max over choices, min over layers and qubits
217-
minp = tf.math.reduce_min(tf.math.reduce_max(tf.math.softmax(params), axis=-1))
225+
minp = tf.math.reduce_min(
226+
tf.math.reduce_max(tf.math.softmax(params), axis=-1)
227+
)
218228
if minp > 0.5:
219229
print("probability converged")
220230

221231
if verbose:
222-
print(
223-
"strcuture parameter: \n",
224-
params.numpy()
225-
)
232+
print("strcuture parameter: \n", params.numpy())
226233

227234
cand_preset = best_from_structure(params)
228235
print(cand_preset)
@@ -232,6 +239,8 @@ def train_hybrid(stddev=0.05, lr=None, epochs=2000, debug_step=50, batch=256, ve
232239
return hybrid_vqe(params, paramq, "most"), params, paramq, loss_history
233240

234241

235-
print('Train hybrid.')
236-
ee, params, paramq, loss_history = train_hybrid(epochs=epochs, batch=batch, verbose=True)
237-
print('Energy:', ee)
242+
print("Train hybrid.")
243+
ee, params, paramq, loss_history = train_hybrid(
244+
epochs=epochs, batch=batch, verbose=True
245+
)
246+
print("Energy:", ee)

0 commit comments

Comments
 (0)