Skip to content

Commit a59cc53

Browse files
Iterate on tfim_vqe.py (experimental)
1 parent b017d06 commit a59cc53

File tree

1 file changed

+19
-26
lines changed

1 file changed

+19
-26
lines changed

scripts/tfim_vqe.py

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,6 @@
232232
# Step 4: Setup localized TFIM from Hamiltonian
233233

234234
def estimate_local_parameters(qubit_hamiltonian, n_qubits):
235-
"""
236-
Estimate (z, J, h) per qubit from Hamiltonian.
237-
z: number of ZZ neighbors
238-
J: average ZZ coefficient
239-
h: average X coefficient
240-
"""
241235
z = np.zeros(n_qubits, dtype=int)
242236
J = np.zeros(n_qubits)
243237
h = np.zeros(n_qubits)
@@ -247,48 +241,41 @@ def estimate_local_parameters(qubit_hamiltonian, n_qubits):
247241
q, pauli = term[0]
248242
if pauli == "X":
249243
h[q] += np.abs(coeff)
244+
elif pauli == "Y":
245+
h[q] += 0.5 * np.abs(coeff)
250246
elif len(term) == 2:
251247
(q1, p1), (q2, p2) = term
252-
if {p1, p2} == {"Z"}:
248+
if {p1, p2} <= {"Z"}:
253249
J[q1] += np.abs(coeff) / 2
254250
J[q2] += np.abs(coeff) / 2
255251
z[q1] += 1
256252
z[q2] += 1
253+
else:
254+
h[q1] += 0.25 * np.abs(coeff)
255+
h[q2] += 0.25 * np.abs(coeff)
257256
return z, J, h
258257

259258
def tfim_ground_state_angles(n_qubits, J_vec, h_vec, z_vec, t=10.0):
260-
"""
261-
Generate RY angles based on TFIM magnetization estimates.
262-
"""
263259
ry_angles = np.zeros(n_qubits)
264260
for i in range(n_qubits):
265261
m = tfim_magnetization(J=J_vec[i], h=h_vec[i], z=z_vec[i], theta=np.random.rand() * np.pi, t=t, n_qubits=1)
266262
p = np.clip((1.0 - m) / 2.0, 1e-6, 1 - 1e-6)
267263
ry_angles[i] = 2.0 * np.arcsin(np.sqrt(p))
268264
return ry_angles
269265

270-
def build_ansatz(angles, wires):
271-
for i, angle in enumerate(angles):
272-
qml.RY(angle, wires=wires[i])
273-
for i in range(len(wires) - 1):
274-
qml.CNOT(wires=[wires[i], wires[i+1]])
275-
276-
def tfim_energy_estimate(qubit_hamiltonian, n_qubits, dev=None):
266+
def hybrid_tfim_vqe(qubit_hamiltonian, n_qubits, dev=None, layers=1):
277267
"""
278268
Estimate energy from TFIM-predicted RY angles.
279269
"""
280270
z, J, h = estimate_local_parameters(qubit_hamiltonian, n_qubits)
281271
angles = tfim_ground_state_angles(n_qubits, J, h, z)
272+
weights_shape = {"weights": (layers, n_qubits, 3)}
282273

283274
if dev is None:
284275
dev = qml.device("default.qubit", wires=n_qubits)
285276

286-
# Step 4: Extract Qubit Terms for PennyLane
287277
coeffs = []
288278
observables = []
289-
n_qubits = molecule.n_qubits # Auto-detect qubit count
290-
print(str(n_qubits) + " qubits...")
291-
292279
for term, coefficient in qubit_hamiltonian.terms.items():
293280
pauli_operators = []
294281
for qubit_idx, pauli in term:
@@ -310,14 +297,20 @@ def tfim_energy_estimate(qubit_hamiltonian, n_qubits, dev=None):
310297
hamiltonian = qml.Hamiltonian(coeffs, observables)
311298

312299
@qml.qnode(dev)
313-
def circuit():
314-
build_ansatz(angles, wires=range(n_qubits))
300+
def circuit(weights):
301+
for i, angle in enumerate(angles):
302+
qml.RY(angle, wires=i)
303+
qml.StronglyEntanglingLayers(weights, wires=range(n_qubits))
315304
return qml.expval(hamiltonian)
316305

317-
return circuit()
306+
return circuit, weights_shape
318307

319308
# Step 5: Setup Qrack simulator and calculate energy expectation value
320309
dev = qml.device("qrack.simulator", wires=n_qubits)
321-
energy = tfim_energy_estimate(qubit_hamiltonian, n_qubits, dev)
310+
circuit, weights_shape = hybrid_tfim_vqe(qubit_hamiltonian, n_qubits)
311+
weights = np.random.randn(*weights_shape["weights"])
322312

323-
print(f"Optimized Ground State Energy: {energy} Ha")
313+
opt = qml.AdamOptimizer(stepsize=0.1)
314+
for i in range(100):
315+
weights = opt.step(lambda w: circuit(w), weights)
316+
print(f"Step {i}: Energy = {circuit(weights)}")

0 commit comments

Comments
 (0)