Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PennyLane IO entry point for loading Qiskit operators #453

Merged
merged 27 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a4c59d3
save draft of SparsePauliOp conversion
lillian542 Feb 5, 2024
09cdefe
Merge branch 'master' into sparse_pauli_op
lillian542 Feb 14, 2024
1b021d3
Add docstring to `convert_sparse_pauli_op_to_pl()`
Mandrenkov Feb 21, 2024
1891c48
Add tests for `convert_sparse_pauli_op_to_pl()`
Mandrenkov Feb 21, 2024
8cbe0e7
Synchronize `qiskit` and `qiskit-terra` requirements
Mandrenkov Feb 21, 2024
717f169
Merge branch 'master' into sparse_pauli_op
Mandrenkov Feb 21, 2024
53fe08d
Remove unused requirement `tweedledum`
Mandrenkov Feb 22, 2024
3c66e1a
Add `wires` argument to `convert_sparse_pauli_op_to_pl()`
Mandrenkov Feb 22, 2024
16269f8
Swap order of `params` and `wires` arguments
Mandrenkov Feb 22, 2024
531e845
Merge branch 'master' into sparse_pauli_op
Mandrenkov Feb 22, 2024
e47512b
Pass `coeffs` by keyword argument in docstring example
Mandrenkov Feb 22, 2024
3d494bb
Pass `params` by keyword argument in example
Mandrenkov Feb 22, 2024
abe6782
Add comment about wire ordering to Qiskit term `for` loop
Mandrenkov Feb 22, 2024
c528969
Rename function to `convert_sparse_pauli_op()`
Mandrenkov Feb 22, 2024
ad1e351
Reword note according to PR suggestion
Mandrenkov Feb 22, 2024
38b96e2
Add 'Usage Details' section to docstring
Mandrenkov Feb 22, 2024
51f6f71
Rename function to `load_pauli_op()`
Mandrenkov Feb 22, 2024
867024b
Rename `sparse_op` to `pauli_op`
Mandrenkov Feb 22, 2024
f3f745c
Merge branch 'master' into sparse_pauli_op
Mandrenkov Feb 22, 2024
22c02b9
Fix import ordering
Mandrenkov Feb 22, 2024
b3f229f
Add PennyLane entry point for loading Qiskit operators
Mandrenkov Feb 22, 2024
22d0782
Merge branch 'master' into sc-56187-from-qiskit-op-entry-point
Mandrenkov Feb 22, 2024
d11e202
Add `SparsePauliOp` notes to changelog
Mandrenkov Feb 23, 2024
122c599
Merge branch 'master' into sc-56187-from-qiskit-op-entry-point
Mandrenkov Feb 23, 2024
3ed49ba
Add missing check for `pauli_op` type
Mandrenkov Feb 23, 2024
91664b7
Synchronize docstrings between PennyLane and plugin
Mandrenkov Feb 23, 2024
28b41d0
Tag PR in existing changelog note
Mandrenkov Feb 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@
``Barrier``, ``CYGate``, ``CHGate``, ``CPhase``, ``CCZGate``, ``ECRGate``, and ``GlobalPhaseGate``.
[(#449)](https://github.com/PennyLaneAI/pennylane-qiskit/pull/449)

* Added the ability to convert a Qiskit `SparsePauliOp` instance into a PennyLane `Operator`.
[(#401)](https://github.com/PennyLaneAI/pennylane-qiskit/pull/401)
[(#453)](https://github.com/PennyLaneAI/pennylane-qiskit/pull/453)

* Added a `pennylane.io` entry point for converting Qiskit operators.
[(#453)](https://github.com/PennyLaneAI/pennylane-qiskit/pull/453)

* Unused parameters are now ignored when a `QuantumCircuit` is converted using `load`.
[(#454)](https://github.com/PennyLaneAI/pennylane-qiskit/pull/454)

Expand Down
24 changes: 15 additions & 9 deletions pennylane_qiskit/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,16 +557,17 @@ def load_pauli_op(
params: Any = None,
wires: Union[Sequence, None] = None,
) -> qml.operation.Operator:
"""Loads a PennyLane operator from a Qiskit SparsePauliOp.
"""Loads a PennyLane ``Operator`` from a Qiskit `SparsePauliOp
<https://docs.quantum.ibm.com/api/qiskit/qiskit.quantum_info.SparsePauliOp>`_.

Args:
pauli_op (qiskit.quantum_info.SparsePauliOp): the SparsePauliOp to be converted
params (Any): optional assignment of coefficient values for the SparsePauliOp; see the
pauli_op (qiskit.quantum_info.SparsePauliOp): the ``SparsePauliOp`` to be converted
params (Any): optional assignment of coefficient values for the ``SparsePauliOp``; see the
`Qiskit documentation <https://docs.quantum.ibm.com/api/qiskit/qiskit.quantum_info.SparsePauliOp#assign_parameters>`__
to learn more about the expected format of these parameters
wires (Sequence | None): optional assignment of wires for the converted SparsePauliOp; if
the original SparsePauliOp acted on :math:`N` qubits, then this must be a sequence of
length :math:`N`
wires (Sequence | None): optional assignment of wires for the converted ``SparsePauliOp``;
if the original ``SparsePauliOp`` acted on :math:`N` qubits, then this must be a
sequence of length :math:`N`

Returns:
pennylane.operation.Operator: The equivalent PennyLane operator.
Expand All @@ -575,8 +576,10 @@ def load_pauli_op(

The wire ordering convention differs between PennyLane and Qiskit: PennyLane wires are
enumerated from left to right, while the Qiskit convention is to enumerate from right to
left. A ``SparsePauliOp`` term defined by the string ``"XYZ"`` applies ``Z`` on wire 0,
``Y`` on wire 1, and ``X`` on wire 2.
left. This means a ``SparsePauliOp`` term defined by the string ``"XYZ"`` applies ``Z`` on
wire 0, ``Y`` on wire 1, and ``X`` on wire 2. For more details, see the
`String representation <https://docs.quantum.ibm.com/api/qiskit/qiskit.quantum_info.Pauli>`_
section of the Qiskit documentation for the ``Pauli`` class.

**Example**

Expand All @@ -594,7 +597,7 @@ def load_pauli_op(
SparsePauliOp(['II', 'XY'],
coeffs=[1.+0.j, 1.+0.j])

To convert the ``SparsePauliOp`` into a PennyLane operator, use:
To convert the ``SparsePauliOp`` into a PennyLane ``Operator``, use:

>>> from pennylane_qiskit import load_pauli_op
>>> load_pauli_op(qiskit_op)
Expand Down Expand Up @@ -640,6 +643,9 @@ def load_pauli_op(
>>> load_pauli_op(wired_qiskit_op, wires=[3, 5, 7])
Y(5) @ Z(3) @ X(7)
"""
if not isinstance(pauli_op, SparsePauliOp):
raise ValueError(f"The operator {pauli_op} is not a valid Qiskit SparsePauliOp.")

if wires is not None and len(wires) != pauli_op.num_qubits:
raise RuntimeError(
f"The specified number of wires - {len(wires)} - does not match the "
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
],
'pennylane.io': [
'qiskit = pennylane_qiskit:load',
'qiskit_op = pennylane_qiskit:load_pauli_op',
'qasm = pennylane_qiskit:load_qasm',
'qasm_file = pennylane_qiskit:load_qasm_from_file',
],
Expand Down
8 changes: 8 additions & 0 deletions tests/test_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -1937,3 +1937,11 @@ def test_convert_with_too_many_wires(self):
)
with pytest.raises(RuntimeError, match=match):
load_pauli_op(SparsePauliOp("II"), wires=[0, 1, 2])

def test_convert_with_invalid_operator(self):
"""Tests that a ValueError is raised if an attempt is made to convert an object which is not
a SparsePauliOp into a PennyLane operator.
"""
match = r"The operator 123 is not a valid Qiskit SparsePauliOp\."
with pytest.raises(ValueError, match=match):
load_pauli_op(123)
Loading