Skip to content

Commit dde5df0

Browse files
examples of vqnhe
1 parent fe54a83 commit dde5df0

File tree

4 files changed

+188
-7
lines changed

4 files changed

+188
-7
lines changed

examples/adiabatic_vqnhe.py

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import cirq
2+
import numpy as np
3+
import scipy
4+
import sympy as sy
5+
import networkx as nx
6+
import tensorflow_quantum as tfq
7+
import tensorflow as tf
8+
from functools import partial
9+
from functools import lru_cache
10+
import tensornetwork as tn
11+
from itertools import product
12+
import json
13+
import sys
14+
15+
sys.path.insert(0, "../")
16+
import tensorcircuit as tc
17+
from tensorcircuit.applications.layers import *
18+
from tensorcircuit.applications.van import *
19+
from tensorcircuit.applications.graphdata import *
20+
from tensorcircuit.applications.dqas import *
21+
from tensorcircuit.applications.vags import *
22+
from tensorcircuit.applications.vqes import *
23+
24+
tc.set_backend("tensorflow")
25+
tc.set_dtype("complex128")
26+
27+
28+
def initial_param(t, last=None, lastlast=None):
29+
if ((t % 3 == 1) and last) or ((t % 3 == 2) and lastlast):
30+
if t % 3 == 2:
31+
last = lastlast
32+
qw = last[-1]
33+
qw = tf.Variable(
34+
qw.numpy() + np.random.uniform(low=-0.1, high=0.1, size=qw.numpy().shape)
35+
)
36+
cw = last[-2]
37+
for i, t in enumerate(cw):
38+
cw[i] = t + np.random.uniform(low=-0.1, high=0.1, size=t.shape)
39+
return {"c": cw, "q": qw}
40+
41+
return {}
42+
43+
44+
def adiabatic_range(hm, history):
45+
if len(history) > 0:
46+
last = sorted(
47+
[
48+
(
49+
r["energy"],
50+
r["quantum_energy"],
51+
r["model_weights"],
52+
r["circuit_weights"],
53+
)
54+
for r in history[-1]
55+
],
56+
key=lambda s: s[0],
57+
)[0]
58+
else:
59+
last = None
60+
if len(history) > 1:
61+
lastlast = sorted(
62+
[
63+
(
64+
r["energy"],
65+
r["quantum_energy"],
66+
r["model_weights"],
67+
r["circuit_weights"],
68+
)
69+
for r in history[-1]
70+
],
71+
key=lambda s: s[0],
72+
)[0]
73+
else:
74+
lastlast = None
75+
print("begin caculation on new")
76+
vqeinstance = VQNHE(
77+
4,
78+
hm,
79+
{"max_value": 5, "init_value": 1.0, "min_value": 0.1},
80+
{"filled_qubit": [0]},
81+
)
82+
83+
def learn_q():
84+
return JointSchedule(180, 0.009, 800, 0.001, 800)
85+
86+
def learn_c():
87+
return JointSchedule(160, 0.002, 10000, 0.2, 1500)
88+
89+
rs = vqeinstance.multi_training(
90+
tries=2,
91+
maxiter=150, # 10000
92+
threshold=0.2 * 1e-8,
93+
learn_q=learn_q, # JointSchedule(2800, 0.009, 800, 0.002, 100),
94+
learn_c=learn_c,
95+
initialization_func=partial(initial_param, last=last, lastlast=lastlast),
96+
)
97+
print(
98+
sorted(
99+
[(r["energy"], r["quantum_energy"], r["iterations"]) for r in rs],
100+
key=lambda s: s[0],
101+
)
102+
)
103+
return rs
104+
105+
106+
if __name__ == "__main__":
107+
history = []
108+
lihh = np.load("data_file")
109+
for i, h in enumerate(lihh[3:6]):
110+
history.append(adiabatic_range(h.tolist(), history))
111+
print(history)
112+
# vqeinstance = VQNHE(
113+
# 4,
114+
# lihh,
115+
# {"max_value": 5, "init_value": 1.0, "min_value": 0.1},
116+
# {"filled_qubit": [0]},
117+
# )
118+
119+
# def learn_q():
120+
# return JointSchedule(180, 0.009, 800, 0.001, 800)
121+
122+
# def learn_c():
123+
# return JointSchedule(160, 0.002, 10000, 0.2, 1500)
124+
125+
# rs = vqeinstance.multi_training(
126+
# tries=10,
127+
# maxiter=15000,
128+
# threshold=0.2 * 1e-8,
129+
# learn_q=learn_q, # JointSchedule(2800, 0.009, 800, 0.002, 100),
130+
# learn_c=learn_c,
131+
# )
132+
# print(rs)
133+
# print(
134+
# sorted(
135+
# [(r["energy"], r["quantum_energy"], r["iterations"]) for r in rs],
136+
# key=lambda s: s[0],
137+
# )
138+
# )

examples/vqnhe_h6.py

-1
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,4 @@ def learn_c():
5656
debug=200,
5757
checkpoints=[(900, -3.18), (2600, -3.19), (4500, -3.2)],
5858
)
59-
# -3.1659 # -3.1664 # complex 3.18 # exact:-3.237746566460727 # RBM -3.2139 (-3.2097)
6059
print(rs)

tensorcircuit/applications/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ In `applications`, framework and relevant applications of DQAS are implemented.
44

55
The entrypoint of DQAS framework is `DQAS_search` and `DQAS_search_pmb` for advanced probabilistic model based DQAS.
66
One can also check [examples](/examples) for integrated example demos.
7+
8+
## Variational Quantum-Neural Hybrid Eigensolver
9+
10+
The main library functions and utilities are in `vqes.py`. Also see [examples](/examples) including `vqnhe_h6.py` and `adiabatic_vqnhe.py`.

tensorcircuit/applications/vqes.py

+46-6
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,16 @@ def __init__(
171171
self.model = self.create_model(**model_params)
172172
self.model_params = model_params
173173
if not circuit_params:
174-
circuit_params = {"epochs": 2}
174+
circuit_params = {"epochs": 2, "stddev": 0.1}
175175
self.epochs = circuit_params.get("epochs", 2)
176+
self.circuit_stddev = circuit_params.get("stddev", 0.1)
176177

177178
self.circuit_variable = tf.Variable(
178179
tf.random.normal(
179-
mean=0.0, stddev=0.2, shape=[2 * self.epochs, self.n], dtype=tf.float64
180+
mean=0.0,
181+
stddev=self.circuit_stddev,
182+
shape=[2 * self.epochs, self.n],
183+
dtype=tf.float64,
180184
)
181185
)
182186
self.circuit = self.create_circuit(**circuit_params)
@@ -201,6 +205,8 @@ def create_model(self, choose: str = "real", **kws: Any) -> Model:
201205
return self.create_real_model(**kws)
202206
if choose == "complex":
203207
return self.create_complex_model(**kws)
208+
if choose == "real-rbm":
209+
return self.create_real_rbm_model(**kws)
204210
if choose == "complex-rbm":
205211
return self.create_complex_rbm_model(**kws)
206212

@@ -273,6 +279,19 @@ def create_complex_model(
273279
model = tf.keras.Model(inputs=inputs, outputs=outputs)
274280
return model
275281

282+
def create_real_rbm_model(
283+
self, stddev: float = 0.1, width: int = 2, **kws: Any
284+
) -> Model:
285+
inputs = tf.keras.layers.Input(shape=[self.n])
286+
x = tf.keras.layers.Dense(width * self.n, activation=None)(inputs)
287+
x = tf.math.log(2 * tf.math.cosh(x))
288+
x = tf.reduce_sum(x, axis=-1)
289+
x = tf.reshape(x, [-1, 1])
290+
y = tf.keras.layers.Dense(1, activation=None)(inputs)
291+
outputs = y + x
292+
model = tf.keras.Model(inputs=inputs, outputs=outputs)
293+
return model
294+
276295
def create_complex_rbm_model(
277296
self, stddev: float = 0.1, width: int = 2, **kws: Any
278297
) -> Model:
@@ -286,8 +305,23 @@ def create_complex_rbm_model(
286305
model = tf.keras.Model(inputs=inputs, outputs=outputs)
287306
return model
288307

289-
def create_circuit(
290-
self, epochs: int = 2, filled_qubit: List[int] = [0]
308+
def create_circuit(self, choose="hea", **kws: Any) -> Callable[[Tensor], Tensor]:
309+
if choose == "hea":
310+
return self.create_hea_circuit(**kws)
311+
if choose == "hn":
312+
return self.create_hn_circuit(**kws)
313+
314+
def create_hn_circuit(self, **kws: Any) -> Callable[[Tensor], Tensor]:
315+
def circuit(a: Tensor) -> Tensor:
316+
c = Circuit(self.n)
317+
for i in range(self.n):
318+
c.H(i) # type: ignore
319+
return c
320+
321+
return circuit
322+
323+
def create_hea_circuit(
324+
self, epochs: int = 2, filled_qubit: List[int] = [0], **kws: Any
291325
) -> Callable[[Tensor], Tensor]:
292326
def circuit(a: Tensor) -> Tensor:
293327
c = Circuit(self.n)
@@ -321,6 +355,12 @@ def evaluation(self, cv: Tensor) -> Tuple[Tensor, Tensor, Tensor]:
321355
else:
322356
loss = tf.math.real(vqe_energy_shortcut(c2, self.hop))
323357
grad = tape.gradient(loss, [cv, self.model.variables])
358+
for i, gr in enumerate(grad):
359+
if gr is None:
360+
if i == 0:
361+
grad[i] = tf.zeros_like(cv)
362+
else:
363+
grad[i] = tf.zeros_like(self.model.variables[i - 1])
324364
return loss, grad, nm
325365

326366
@tf.function # type: ignore
@@ -359,7 +399,7 @@ def training(
359399

360400
optc = tf.keras.optimizers.Adam(learning_rate=learnc)
361401
optq = tf.keras.optimizers.Adam(learning_rate=learnq)
362-
402+
nm = tf.constant(1.0)
363403
for j in range(maxiter):
364404
if j < onlyq:
365405
loss, grad = self.plain_evaluation(self.circuit_variable)
@@ -427,7 +467,7 @@ def multi_training(
427467
self.circuit_variable = tf.Variable(
428468
tf.random.normal(
429469
mean=0.0,
430-
stddev=0.2,
470+
stddev=self.circuit_stddev,
431471
shape=[2 * self.epochs, self.n],
432472
dtype=tf.float64,
433473
)

0 commit comments

Comments
 (0)