def test_excitations(electrons, orbitals, delta_sz, n_singles, n_doubles, singles_exp, doubles_exp): r"""Test the correctness of the generated configurations""" singles, doubles = qchem.excitations(electrons, orbitals, delta_sz) assert len(singles) == len(singles_exp) assert len(doubles) == len(doubles_exp) assert singles == singles_exp assert doubles == doubles_exp
class TestSparseExpvalQChem: """Tests for the expval function with qchem workflow""" symbols = ["Li", "H"] geometry = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 2.969280527]) H, qubits = qchem.molecular_hamiltonian( symbols, geometry, ) H_sparse = qml.utils.sparse_hamiltonian(H) active_electrons = 1 hf_state = qchem.hf_state(active_electrons, qubits) singles, doubles = qchem.excitations(active_electrons, qubits) excitations = singles + doubles @pytest.fixture(params=[np.complex64, np.complex128]) def dev(self, request): return qml.device("lightning.qubit", wires=12, c_dtype=request.param) @pytest.mark.parametrize( "qubits, wires, H_sparse, hf_state, excitations", [ [qubits, np.arange(qubits), H_sparse, hf_state, excitations], [ qubits, np.random.permutation(np.arange(qubits)), H_sparse, hf_state, excitations, ], ], ) def test_sparse_Pauli_words(self, qubits, wires, H_sparse, hf_state, excitations, tol, dev): """Test expval of some simple sparse Hamiltonian""" @qml.qnode(dev, diff_method="parameter-shift") def circuit(): qml.BasisState(hf_state, wires=range(qubits)) for i, excitation in enumerate(excitations): if len(excitation) == 4: qml.DoubleExcitation(1, wires=excitation) elif len(excitation) == 2: qml.SingleExcitation(1, wires=excitation) return qml.expval(qml.SparseHamiltonian(H_sparse, wires=wires)) dev_default = qml.device("default.qubit", wires=qubits) @qml.qnode(dev_default, diff_method="parameter-shift") def circuit_default(): qml.BasisState(hf_state, wires=range(qubits)) for i, excitation in enumerate(excitations): if len(excitation) == 4: qml.DoubleExcitation(1, wires=excitation) elif len(excitation) == 2: qml.SingleExcitation(1, wires=excitation) return qml.expval(qml.SparseHamiltonian(H_sparse, wires=wires)) assert np.allclose(circuit(), circuit_default(), atol=tol, rtol=0)
def test_inconsistent_excitations(electrons, orbitals, delta_sz, message_match): r"""Test that an error is raised if a set of inconsistent arguments is input""" with pytest.raises(ValueError, match=message_match): qchem.excitations(electrons, orbitals, delta_sz)
# :func:`~.pennylane.templates.subroutines.SingleExcitationUnitary` and # :func:`~.pennylane.templates.subroutines.DoubleExcitationUnitary` functions. # # Now, we demonstrate how to use PennyLane functionalities to build up the UCCSD # ansatz for VQE simulations. First, we use the :func:`~.pennylane_qchem.qchem.excitations` # function to generate the whole set of single- and double-excitations for :math:`N_e` # ``electrons`` populating ``qubits`` spin orbitals. Furthermore, we can define the selection rules # :math:`s_{z_p} - s_{z_r} = \Delta s_z` and # :math:`s_{z_p} + s_{z_q} - s_{z_r} - s_{z_s}= \Delta s_z` for the spin-projection of the # molecular orbitals involved in the single and double excitations # using the keyword argument ``delta_sz``. This allows us to prepare a # correlated state whose total-spin projection :math:`S_z` is different from the one of # the Hartree-Fock state by the quantity ``delta_sz``. Therefore, we choose ``delta_sz = 0`` to # prepare the ground state of the :math:`\mathrm{H}_2` molecule. singles, doubles = qchem.excitations(electrons, qubits, delta_sz=0) print(singles) print(doubles) ############################################################################## # The output lists ``singles`` and ``doubles`` contain the indices representing the single and # double excitations. For the hydrogen molecule in a minimal basis set we have two single # and one double excitations. The latter means that in preparing the UCCSD ansatz the # :func:`~.pennylane.templates.subroutines.SingleExcitationUnitary` function has to be called # twice to exponentiate the two single-excitation operators while the # :func:`~.pennylane.templates.subroutines.DoubleExcitationUnitary` function is invoked once to # exponentiate the double excitation. # # We use the function # :func:`~.pennylane_qchem.qchem.excitations_to_wires` to generate the set of wires that the UCCSD # circuit will act on. The inputs to this function are the indices stored in the