def test_atomic_orbital(self, symbols, geometry, alpha, coeff, index, position, ref_value): r"""Test that the computed atomic orbital value is correct.""" mol = Molecule(symbols, geometry, alpha=alpha, coeff=coeff) x, y, z = position ao = mol.atomic_orbital(index) ao_value = ao(x, y, z) assert np.allclose(ao_value, ref_value)
def test_molecular_orbital(self, symbols, geometry, index, position, ref_value): r"""Test that the computed atomic orbital value is correct.""" mol = Molecule(symbols, geometry) x, y, z = position _ = generate_scf(mol)() mo = mol.molecular_orbital(index) mo_value = mo(x, y, z) assert np.allclose(mo_value, ref_value)
def test_nuclear_energy_gradient(symbols, geometry, g_ref): r"""Test that nuclear energy gradients are correct.""" mol = Molecule(symbols, geometry) args = [mol.coordinates] g = autograd.grad(nuclear_energy(mol.nuclear_charges, mol.coordinates))(*args) assert np.allclose(g, g_ref)
def test_core_matrix_diff_positions(symbols, geometry, alpha, c_ref): r"""Test that core_matrix returns the correct matrix when positions are differentiable.""" mol = Molecule(symbols, geometry, alpha=alpha) r_basis = mol.coordinates args = [mol.coordinates, mol.alpha, r_basis] c = generate_core_matrix(mol.basis_set, mol.nuclear_charges, mol.coordinates)(*args) assert np.allclose(c, c_ref)
def test_gradient_kinetic_matrix(symbols, geometry, alpha, coeff, g_alpha_ref, g_coeff_ref): r"""Test that the kinetic gradients are correct.""" mol = Molecule(symbols, geometry, alpha=alpha, coeff=coeff) args = [mol.alpha, mol.coeff] g_alpha = autograd.jacobian(generate_kinetic_matrix(mol.basis_set), argnum=0)(*args) g_coeff = autograd.jacobian(generate_kinetic_matrix(mol.basis_set), argnum=1)(*args) assert np.allclose(g_alpha, g_alpha_ref) assert np.allclose(g_coeff, g_coeff_ref)
def test_molecule_data(self, symbols, geometry, n_electrons, n_orbitals, nuclear_charges): r"""Test that the molecule object contains correct molecular data.""" mol = Molecule(symbols, geometry) assert mol.n_electrons == n_electrons assert mol.n_orbitals == n_orbitals assert mol.nuclear_charges == nuclear_charges
def test_hf_energy_gradient(symbols, geometry, g_ref): r"""Test that the gradient of the Hartree-Fock energy wrt differentiable parameters is correct.""" mol = Molecule(symbols, geometry) args = [mol.coordinates] g = autograd.grad(hf_energy(mol))(*args) assert np.allclose(g, g_ref)
def test_generate_overlap(symbols, geometry, alpha, coef, r, o_ref): r"""Test that generate_overlap function returns a correct value for the overlap integral.""" mol = Molecule(symbols, geometry) basis_a = mol.basis_set[0] basis_b = mol.basis_set[1] args = [p for p in [alpha, coef, r] if p.requires_grad] o = generate_overlap(basis_a, basis_b)(*args) assert np.allclose(o, o_ref)
def test_default_inputs(self, symbols, geometry, charge, mult, basis_name): r"""Test that the molecule object contains correct default molecular input data.""" mol = Molecule(symbols, geometry) assert mol.symbols == symbols assert np.allclose(mol.coordinates, geometry) assert mol.charge == charge assert mol.mult == mult assert mol.basis_name == basis_name
def test_generate_kinetic(symbols, geometry, alpha, coeff, t_ref): r"""Test that generate_kinetic function returns a correct value for the kinetic integral.""" mol = Molecule(symbols, geometry, alpha=alpha, coeff=coeff) basis_a = mol.basis_set[0] basis_b = mol.basis_set[1] args = [p for p in [alpha, coeff] if p.requires_grad] t = generate_kinetic(basis_a, basis_b)(*args) assert np.allclose(t, t_ref)
def test_generate_fermionic_hamiltonian(symbols, geometry, alpha, coeffs_h_ref, ops_h_ref): r"""Test that generate_fermionic_hamiltonian returns the correct Hamiltonian.""" mol = Molecule(symbols, geometry, alpha=alpha) args = [alpha] h = generate_fermionic_hamiltonian(mol)(*args) assert np.allclose(h[0], coeffs_h_ref) assert h[1] == ops_h_ref
def test_gradient_attraction_matrix(symbols, geometry, alpha, coeff, g_r_ref): r"""Test that the attraction gradients are correct.""" mol = Molecule(symbols, geometry, alpha=alpha, coeff=coeff) r_basis = mol.coordinates args = [mol.coordinates, mol.alpha, mol.coeff, r_basis] g_r = autograd.jacobian( generate_attraction_matrix(mol.basis_set, mol.nuclear_charges, mol.coordinates), argnum=0 )(*args) assert np.allclose(g_r, g_r_ref)
def test_generate_hamiltonian(symbols, geometry, h_ref_data): r"""Test that generate_hamiltonian returns the correct Hamiltonian.""" mol = Molecule(symbols, geometry) args = [] h = generate_hamiltonian(mol)(*args) h_ref = qml.Hamiltonian(h_ref_data[0], h_ref_data[1]) assert np.allclose(h.terms[0], h_ref.terms[0]) assert qml.Hamiltonian(np.ones(len(h.terms[0])), h.terms[1]).compare( qml.Hamiltonian(np.ones(len(h_ref.terms[0])), h_ref.terms[1]))
def test_basisset(self, symbols, geometry, l, alpha, coeff, r): r"""Test that the molecule object contains the correct basis set and non-default basis data for a given molecule. """ mol = Molecule(symbols, geometry) assert set(map(type, mol.basis_set)) == {BasisFunction} assert mol.l == l assert np.allclose(mol.alpha, alpha) assert np.allclose(mol.coeff, coeff) assert np.allclose(mol.r, r)
def test_scf(symbols, geometry, v_fock, coeffs, fock_matrix, h_core, repulsion_tensor): r"""Test that generate_scf returns the correct values.""" mol = Molecule(symbols, geometry) v, c, f, h, e = generate_scf(mol)() assert np.allclose(v, v_fock) assert np.allclose(c, coeffs) assert np.allclose(f, fock_matrix) assert np.allclose(h, h_core) assert np.allclose(e, repulsion_tensor)
def test_generate_electron_integrals(symbols, geometry, core, active, e_core, one_ref, two_ref): r"""Test that generate_electron_integrals returns the correct values.""" mol = Molecule(symbols, geometry) args = [] e, one, two = generate_electron_integrals(mol, core=core, active=active)(*args) assert np.allclose(e, e_core) assert np.allclose(one, one_ref) assert np.allclose(two, two_ref)
def test_generate_attraction(symbols, geometry, alpha, coeff, a_ref): r"""Test that generate_attraction function returns a correct value for the kinetic integral.""" mol = Molecule(symbols, geometry, alpha=alpha, coeff=coeff) basis_a = mol.basis_set[0] basis_b = mol.basis_set[1] args = [p for p in [alpha, coeff] if p.requires_grad] if geometry.requires_grad: args = [geometry[0]] + args + [geometry] a = generate_attraction(geometry[0], basis_a, basis_b)(*args) assert np.allclose(a, a_ref)
def test_gradient_expvalH(): r"""Test that the gradient of expval(H) computed with ``autograd.grad`` is equal to the value obtained with the finite difference method.""" symbols = ["H", "H"] geometry = (np.array([[0.0, 0.0, -0.3674625962], [0.0, 0.0, 0.3674625962]], requires_grad=False) / 0.529177210903) alpha = np.array( [[3.42525091, 0.62391373, 0.1688554], [3.42525091, 0.62391373, 0.1688554]], requires_grad=True, ) mol = Molecule(symbols, geometry, alpha=alpha) args = [alpha] dev = qml.device("default.qubit", wires=4) def energy(mol): @qml.qnode(dev) def circuit(*args): qml.PauliX(0) qml.PauliX(1) qml.DoubleExcitation(0.22350048111151138, wires=[0, 1, 2, 3]) h_qubit = generate_hamiltonian(mol)(*args) return qml.expval(h_qubit) return circuit grad_autograd = autograd.grad(energy(mol), argnum=0)(*args) alpha_1 = np.array( [[3.42515091, 0.62391373, 0.1688554], [3.42525091, 0.62391373, 0.1688554]], requires_grad=False, ) # alpha[0][0] -= 0.0001 alpha_2 = np.array( [[3.42535091, 0.62391373, 0.1688554], [3.42525091, 0.62391373, 0.1688554]], requires_grad=False, ) # alpha[0][0] += 0.0001 e_1 = energy(mol)(*[alpha_1]) e_2 = energy(mol)(*[alpha_2]) grad_finitediff = (e_2 - e_1) / 0.0002 assert np.allclose(grad_autograd[0][0], grad_finitediff)
def test_gradient_attraction(symbols, geometry, alpha, coeff): r"""Test that the attraction gradient computed with respect to the basis parameters is correct.""" mol = Molecule(symbols, geometry, alpha=alpha, coeff=coeff) basis_a = mol.basis_set[0] basis_b = mol.basis_set[1] args = [mol.alpha, mol.coeff] r_nuc = geometry[0] g_alpha = autograd.grad(generate_attraction(r_nuc, basis_a, basis_b), argnum=0)(*args) g_coeff = autograd.grad(generate_attraction(r_nuc, basis_a, basis_b), argnum=1)(*args) # compute attraction gradients with respect to alpha and coeff using finite diff delta = 0.0001 g_ref_alpha = np.zeros(6).reshape(alpha.shape) g_ref_coeff = np.zeros(6).reshape(coeff.shape) for i in range(len(alpha)): for j in range(len(alpha[0])): alpha_minus = alpha.copy() alpha_plus = alpha.copy() alpha_minus[i][j] = alpha_minus[i][j] - delta alpha_plus[i][j] = alpha_plus[i][j] + delta a_minus = generate_attraction(r_nuc, basis_a, basis_b)(*[alpha_minus, coeff]) a_plus = generate_attraction(r_nuc, basis_a, basis_b)(*[alpha_plus, coeff]) g_ref_alpha[i][j] = (a_plus - a_minus) / (2 * delta) coeff_minus = coeff.copy() coeff_plus = coeff.copy() coeff_minus[i][j] = coeff_minus[i][j] - delta coeff_plus[i][j] = coeff_plus[i][j] + delta a_minus = generate_attraction(r_nuc, basis_a, basis_b)(*[alpha, coeff_minus]) a_plus = generate_attraction(r_nuc, basis_a, basis_b)(*[alpha, coeff_plus]) g_ref_coeff[i][j] = (a_plus - a_minus) / (2 * delta) assert np.allclose(g_alpha, g_ref_alpha) assert np.allclose(g_coeff, g_ref_coeff)
def test_core_matrix_nodiff(symbols, geometry, c_ref): r"""Test that core_matrix returns the correct matrix when no differentiable parameter is used.""" mol = Molecule(symbols, geometry) c = generate_core_matrix(mol.basis_set, mol.nuclear_charges, mol.coordinates)() assert np.allclose(c, c_ref)
def test_core_matrix(symbols, geometry, alpha, c_ref): r"""Test that core_matrix returns the correct matrix.""" mol = Molecule(symbols, geometry, alpha=alpha) args = [mol.alpha] c = generate_core_matrix(mol.basis_set, mol.nuclear_charges, mol.coordinates)(*args) assert np.allclose(c, c_ref)
def test_symbol_error(self, symbols, geometry): r"""Test that an error is raised if a wrong/not-supported atomic symbol is entered.""" with pytest.raises(ValueError, match="are not supported"): Molecule(symbols, geometry)
def test_overlap_matrix(symbols, geometry, alpha, s_ref): r"""Test that overlap_matrix returns the correct matrix.""" mol = Molecule(symbols, geometry, alpha=alpha) args = [alpha] s = generate_overlap_matrix(mol.basis_set)(*args) assert np.allclose(s, s_ref)
def test_basis_error(self, symbols, geometry): r"""Test that an error is raised if a wrong basis set name is entered.""" with pytest.raises(ValueError, match="Currently, the only supported basis set is"): Molecule(symbols, geometry, basis_name="6-31g")
def test_build_molecule(self, symbols, geometry): r"""Test that the generated molecule object has the correct type.""" mol = Molecule(symbols, geometry) assert isinstance(mol, Molecule)
def test_overlap_matrix_nodiff(symbols, geometry, s_ref): r"""Test that overlap_matrix returns the correct matrix when no differentiable parameter is used.""" mol = Molecule(symbols, geometry) s = generate_overlap_matrix(mol.basis_set)() assert np.allclose(s, s_ref)
def test_repulsion_tensor_nodiff(symbols, geometry, e_ref): r"""Test that repulsion_tensor returns the correct matrix when no differentiable parameter is used.""" mol = Molecule(symbols, geometry) e = generate_repulsion_tensor(mol.basis_set)() assert np.allclose(e, e_ref)
def test_attraction_matrix_nodiff(symbols, geometry, v_ref): r"""Test that attraction_matrix returns the correct matrix.""" mol = Molecule(symbols, geometry) v = generate_attraction_matrix(mol.basis_set, mol.nuclear_charges, mol.coordinates)() assert np.allclose(v, v_ref)
def test_default_basisdata(self, symbols, geometry, n_basis, basis_data): r"""Test that the molecule object contains correct default basis data for a given molecule.""" mol = Molecule(symbols, geometry) assert mol.n_basis == n_basis assert np.allclose(mol.basis_data, basis_data)
def test_repulsion_tensor(symbols, geometry, alpha, e_ref): r"""Test that repulsion_tensor returns the correct matrix.""" mol = Molecule(symbols, geometry, alpha=alpha) args = [mol.alpha] e = generate_repulsion_tensor(mol.basis_set)(*args) assert np.allclose(e, e_ref)