from pennylane import numpy as np
symbols = ["Be", "Be"]
x = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 1.5], requires_grad=True)
import pennylane as qml
def H(x):
return qml.qchem.molecular_hamiltonian(symbols, x, charge=0)[0]
hf = qml.qchem.hf_state(electrons=2, orbitals=8)
print(hf)
num_wires = 8
dev = qml.device("lightning.qubit", wires=num_wires)
@qml.qnode(dev, interface="autograd")
def circuit(params, obs, wires):
qml.BasisState(hf, wires=wires)
qml.DoubleExcitation(params[0], wires=[0, 1, 2, 3])
qml.DoubleExcitation(params[1], wires=[0, 1, 4, 5])
qml.DoubleExcitation(params[2], wires=[2, 3, 6, 7])
return qml.expval(obs)
def cost(params, x):
hamiltonian = H(x)
return circuit(params, obs=hamiltonian, wires=range(num_wires))
def finite_diff(f, x, delta=0.01):
"""Compute the central-difference finite difference of a function"""
gradient = []
for i in range(len(x)):
shift = np.zeros_like(x)
shift[i] += 0.5 * delta
res = (f(x + shift) - f(x - shift)) * delta**-1
gradient.append(res)
return gradient
def grad_x(params, x):
grad_h = finite_diff(H, x)
grad = [circuit(params, obs=obs, wires=range(num_wires)) for obs in grad_h]
return np.array(grad)
opt_theta = qml.GradientDescentOptimizer(stepsize=0.4)
opt_x = qml.GradientDescentOptimizer(stepsize=0.8)
theta = np.array([0.0, 0.0], requires_grad=True)
from functools import partial
# store the values of the cost function
energy = []
# store the values of the bond length
bond_length = []
# Factor to convert from Bohrs to Angstroms
bohr_angs = 0.529177210903
for n in range(100):
# Optimize the circuit parameters
theta.requires_grad = True
x.requires_grad = False
theta, _ = opt_theta.step(cost, theta, x)
# Optimize the nuclear coordinates
x.requires_grad = True
theta.requires_grad = False
_, x = opt_x.step(cost, theta, x, grad_fn=grad_x)
energy.append(cost(theta, x))
bond_length.append(np.linalg.norm(x[0:3] - x[3:6]) * bohr_angs)
if n % 4 == 0:
print(f"Step = {n}, E = {energy[-1]:.8f} Ha, bond length = {bond_length[-1]:.5f} A")
# Check maximum component of the nuclear gradient
if np.max(grad_x(theta, x)) <= 1e-05:
break
print("\n" f"Final value of the ground-state energy = {energy[-1]:.8f} Ha")
print("\n" "Ground-state equilibrium geometry")
print("%s %4s %8s %8s" % ("symbol", "x", "y", "z"))
for i, atom in enumerate(symbols):
print(f" {atom} {x[3 * i]:.4f} {x[3 * i + 1]:.4f} {x[3 * i + 2]:.4f}")
this code is showing error
IndexError: index 2 is out of bounds for axis 0 with size 2
Can you explain if I use this tutorial code for other molecules , how can I change the values ?