Source code for pennylane.ops.functions.commutator
# Copyright 2024 Xanadu Quantum Technologies Inc.# Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at# http://www.apache.org/licenses/LICENSE-2.0# Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License."""This file contains the implementation of the commutator function in PennyLane"""importpennylaneasqmlfrompennylane.pauliimportPauliSentence,PauliWord
[docs]defcommutator(op1,op2,pauli=False):r"""Compute commutator between two operators in PennyLane .. math:: [O_1, O_2] = O_1 O_2 - O_2 O_1 Args: op1 (Union[Operator, PauliWord, PauliSentence]): First operator op2 (Union[Operator, PauliWord, PauliSentence]): Second operator pauli (bool): When ``True``, all results are passed as a ``PauliSentence`` instance. Else, results are always returned as ``Operator`` instances. Returns: ~Operator or ~PauliSentence: The commutator **Examples** You can compute commutators between operators in PennyLane. >>> qml.commutator(X(0), Y(0)) 2j * Z(0) >>> op1 = X(0) @ X(1) >>> op2 = Y(0) @ Y(1) >>> qml.commutator(op1, op2) 0 * I() We can return a :class:`~PauliSentence` instance by setting ``pauli=True``. >>> op1 = X(0) @ X(1) >>> op2 = Y(0) + Y(1) >>> res = qml.commutator(op1, op2, pauli=True) >>> res 2j * X(1) @ Z(0) + 2j * Z(1) @ X(0) >>> isinstance(res, PauliSentence) True We can also input :class:`~PauliWord` and :class:`~PauliSentence` instances. >>> op1 = PauliWord({0:"X", 1:"X"}) >>> op2 = PauliWord({0:"Y"}) + PauliWord({1:"Y"}) >>> res = qml.commutator(op1, op2, pauli=True) >>> res 2j * Z(0) @ X(1) + 2j * X(0) @ Z(1) >>> isinstance(res, PauliSentence) True Note that when ``pauli=False``, even if Pauli operators are used as inputs, ``qml.commutator`` returns Operators. >>> res = qml.commutator(op1, op2, pauli=False) >>> res 2j * (Z(0) @ X(1)) + 2j * (X(0) @ Z(1)) >>> isinstance(res, qml.operation.Operator) True It is worth noting that computing commutators with Paulis is typically faster. Internally, ``qml.commutator`` uses the ``op.pauli_rep`` whenever that is available for both operators. .. details:: :title: Usage Details The input and result of ``qml.commutator`` is not recorded in a tape context (and inside a :class:`~QNode`). .. code-block:: python3 with qml.tape.QuantumTape() as tape: a = qml.X(0) # gets recorded b = PauliWord({0:"Y"}) # does not get recorded comm = qml.commutator(a, b) # does not get recorded In this example, we obtain ``tape.operations = [qml.X(0)]``. When desired, we can still record the result of the commutator by using :func:`~apply`, i.e. ``qml.apply(comm)`` inside the recording context. A peculiarity worth repeating is how in a recording context every created operator is recorded. .. code-block:: python3 with qml.tape.QuantumTape() as tape: comm = qml.commutator(qml.X(0), qml.Y(0)) In this example, both :class:`~PauliX` and :class:`PauliY` get recorded because they were created inside the recording context. To avoid this, create the input to ``qml.commutator`` outside the recording context / qnode or insert an extra ``stop_recording()`` context (see :class:`~QueuingManager`). """both_have_pauli_rep=op1.pauli_repisnotNoneandop2.pauli_repisnotNoneifpauliorboth_have_pauli_rep:ifnotisinstance(op1,PauliSentence):op1=qml.pauli.pauli_sentence(op1)ifnotisinstance(op2,PauliSentence):op2=qml.pauli.pauli_sentence(op2)res=op1.commutator(op2)returnresifpaulielseres.operation(wire_order=res.wires)# If no pauli processing is possible, use operator arithmeticwithqml.QueuingManager.stop_recording():ifisinstance(op1,(PauliWord,PauliSentence)):op1=op1.operation()ifisinstance(op2,(PauliWord,PauliSentence)):op2=op2.operation()res=qml.sum(qml.prod(op1,op2),qml.s_prod(-1.0,qml.prod(op2,op1)))res=res.simplify()returnres