def test_exception_convert_observable(qubit_op, tol):
    r"""Test that an error is raised if the QubitOperator contains complex coefficients.
    Currently the vqe.Hamiltonian class does not support complex coefficients.
    """
    with pytest.raises(
            TypeError,
            match="The coefficients entering the QubitOperator must be real"):
        qchem.convert_observable(qubit_op, tol=tol)
def test_exception_convert_observable():
    r"""Test that an error is raised if the QubitOperator contains complex coefficients.
    Currently the vqe.Hamiltonian class does not support complex coefficients.
    """
    qubit_op = (QubitOperator("Y0 Y1", 1 + 0j) +
                QubitOperator("Z0 X1", 4.5 + 1.5j) + QubitOperator("Y0 X1", 2))

    with pytest.raises(
            TypeError,
            match="The coefficients entering the QubitOperator must be real"):
        qchem.convert_observable(qubit_op)
Exemplo n.º 3
0
def test_integration_observable_to_vqe_cost(monkeypatch, mol_name, terms_ref,
                                            expected_cost, tol):
    r"""Test if `convert_observable()` in qchem integrates with `VQECost()` in pennylane"""

    qOp = QubitOperator()
    if terms_ref is not None:
        monkeypatch.setattr(qOp, "terms", terms_ref)
    vqe_observable = qchem.convert_observable(qOp)

    # maybe make num_qubits a @property of the Hamiltonian class?
    num_qubits = max(
        1, len(set([w for op in vqe_observable.ops for w in op.wires])))

    dev = qml.device("default.qubit", wires=num_qubits)
    print(vqe_observable.terms)

    # can replace the ansatz with more suitable ones later.
    def dummy_ansatz(phis, wires):
        for phi, w in zip(phis, wires):
            qml.RX(phi, wires=w)

    dummy_cost = qml.VQECost(dummy_ansatz, vqe_observable, dev)
    params = [0.1 * i for i in range(num_qubits)]
    res = dummy_cost(params)

    assert np.allclose(res, expected_cost, **tol)
def test_integration_observable_to_vqe_cost(monkeypatch, mol_name, terms_ref,
                                            expected_cost, custom_wires, tol):
    r"""Test if `convert_observable()` in qchem integrates with `ExpvalCost()` in pennylane"""

    qOp = QubitOperator()
    if terms_ref is not None:
        monkeypatch.setattr(qOp, "terms", terms_ref)
    vqe_observable = qchem.convert_observable(qOp, custom_wires)

    num_qubits = len(vqe_observable.wires)
    assert vqe_observable.terms.__repr__()  # just to satisfy codecov

    if custom_wires is None:
        wires = num_qubits
    elif isinstance(custom_wires, dict):
        wires = qchem.structure._process_wires(custom_wires)
    else:
        wires = custom_wires[:num_qubits]
    dev = qml.device("default.qubit", wires=wires)

    # can replace the ansatz with more suitable ones later.
    def dummy_ansatz(phis, wires):
        for phi, w in zip(phis, wires):
            qml.RX(phi, wires=w)

    dummy_cost = qml.ExpvalCost(dummy_ansatz, vqe_observable, dev)
    params = [0.1 * i for i in range(num_qubits)]
    res = dummy_cost(params)

    assert np.allclose(res, expected_cost, **tol)
Exemplo n.º 5
0
def test_observable_conversion(mol_name, terms_ref, monkeypatch):
    r"""Test the correctness of the QubitOperator observable conversion from
    OpenFermion to Pennylane.

    The parametrized inputs are `.terms` attribute of the output `QubitOperator`s based on
    the same set of test molecules as `test_gen_hamiltonian_pauli_basis`.

    The equality checking is implemented in the `qchem` module itself as it could be
    something useful to the users as well.
    """
    qOp = QubitOperator()
    if terms_ref is not None:
        monkeypatch.setattr(qOp, "terms", terms_ref)

    vqe_observable = qchem.convert_observable(qOp)

    assert qchem._qubit_operators_equivalent(qOp, vqe_observable)
Exemplo n.º 6
0
def test_types_consistency():
    r"""Test the type consistency of the qubit Hamiltonian constructed by 'convert_observable' from
    an OpenFermion QubitOperator with respect to the same observable built directly using PennyLane
    operations"""

    # Reference PL operator
    pl_ref = 1 * qml.Identity(0) + 2 * qml.PauliZ(0) @ qml.PauliX(1)

    # Corresponding OpenFermion QubitOperator
    of = QubitOperator("", 1) + QubitOperator("Z0 X1", 2)

    # Build PL operator using 'convert_observable'
    pl = qchem.convert_observable(of)

    ops = pl.terms[1]
    ops_ref = pl_ref.terms[1]

    for i, op in enumerate(ops):
        assert op.name == ops_ref[i].name
        assert type(op) == type(ops_ref[i])
def test_integration_mol_file_to_vqe_cost(name, core, active, mapping,
                                          expected_cost, custom_wires, tol):
    r"""Test if the output of `decompose()` works with `convert_observable()`
    to generate `ExpvalCost()`"""

    ref_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                           "test_ref_files")
    hf_file = os.path.join(ref_dir, name)
    qubit_hamiltonian = qchem.decompose(
        hf_file,
        mapping=mapping,
        core=core,
        active=active,
    )

    vqe_hamiltonian = qchem.convert_observable(qubit_hamiltonian, custom_wires)
    assert len(vqe_hamiltonian.ops) > 1  # just to check if this runs

    num_qubits = len(vqe_hamiltonian.wires)
    assert num_qubits == 2 * len(active)

    if custom_wires is None:
        wires = num_qubits
    elif isinstance(custom_wires, dict):
        wires = qchem.structure._process_wires(custom_wires)
    else:
        wires = custom_wires[:num_qubits]
    dev = qml.device("default.qubit", wires=wires)

    # can replace the ansatz with more suitable ones later.
    def dummy_ansatz(phis, wires):
        for phi, w in zip(phis, wires):
            qml.RX(phi, wires=w)

    phis = np.load(os.path.join(ref_dir, "dummy_ansatz_parameters.npy"))

    dummy_cost = qml.ExpvalCost(dummy_ansatz, vqe_hamiltonian, dev)
    res = dummy_cost(phis)

    assert np.abs(res - expected_cost) < tol["atol"]
Exemplo n.º 8
0
def test_integration_mol_file_to_vqe_cost(hf_filename, docc_mo, act_mo,
                                          type_of_transformation,
                                          expected_cost, tol):
    r"""Test if the output of `decompose_hamiltonian()` works with `convert_observable()`
    to generate `VQECost()`"""
    ref_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                           "test_ref_files")

    transformed_hamiltonian = qchem.decompose_hamiltonian(
        hf_filename,
        ref_dir,
        mapping=type_of_transformation,
        docc_mo_indices=docc_mo,
        active_mo_indices=act_mo,
    )

    vqe_hamiltonian = qchem.convert_observable(transformed_hamiltonian)
    assert len(vqe_hamiltonian.ops) > 1  # just to check if this runs

    num_qubits = max(
        1, len(set([w for op in vqe_hamiltonian.ops for w in op.wires])))
    assert num_qubits == 2 * len(act_mo)

    dev = qml.device("default.qubit", wires=num_qubits)

    # can replace the ansatz with more suitable ones later.
    def dummy_ansatz(phis, wires):
        for phi, w in zip(phis, wires):
            qml.RX(phi, wires=w)

    phis = np.load(os.path.join(ref_dir, "dummy_ansatz_parameters.npy"))

    dummy_cost = qml.VQECost(dummy_ansatz, vqe_hamiltonian, dev)
    res = dummy_cost(phis)

    assert np.abs(res - expected_cost) < tol["atol"]