Files
local_quantum_simulator/source/vqe.py
2026-03-16 22:13:26 +03:00

64 lines
1.8 KiB
Python

import os
from multiprocessing import Queue
import pennylane as qml
from pennylane import numpy as np
os.environ["OMP_NUM_THREADS"] = "16"
def get_sctructure_from_xyz_path(path: str):
return qml.qchem.read_structure("methane.xyz")
def run_vqe(
queue_callback: Queue,
symbols,
coordinates,
active_electrons,
active_orbitals,
max_iterations,
conv_tol,
step_size,
):
molecule = qml.qchem.Molecule(symbols, coordinates, load_data=True)
H, qubits = qml.qchem.molecular_hamiltonian(
molecule, active_electrons=active_electrons, active_orbitals=active_orbitals
)
dev = qml.device("lightning.qubit", wires=qubits)
singles, doubles = qml.qchem.excitations(active_electrons, qubits)
params = np.array(np.zeros(len(singles) + len(doubles)), requires_grad=True)
@qml.qnode(dev)
def circuit(param, wires):
# Map excitations to the wires the UCCSD circuit will act on
s_wires, d_wires = qml.qchem.excitations_to_wires(singles, doubles)
qml.UCCSD(
param,
wires,
s_wires=s_wires,
d_wires=d_wires,
init_state=qml.qchem.hf_state(active_electrons, qubits),
)
return qml.expval(H)
def cost_fn(param):
return circuit(param, wires=range(qubits))
opt = qml.GradientDescentOptimizer(stepsize=step_size)
for n in range(max_iterations):
# Take step
params, prev_energy = opt.step_and_cost(cost_fn, params)
energy = cost_fn(params)
# Calculate difference between new and old energies
conv = np.abs(energy - prev_energy)
queue_callback.put([n, energy, params])
if conv <= conv_tol:
break