from pennylane import numpy as np import pennylane as qml import os from multiprocessing import Queue os.environ["OMP_NUM_THREADS"] = '16' def get_sctructure_from_xyz_path(path: str): return qml.qchem.read_structure("methane.xyz") def run_vqe(q: 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) q.put([n, energy,params]) if conv <= conv_tol: break