Übersicht über Operator-Klassen
Paketversionen
Der Code auf dieser Seite wurde mit den folgenden Paketversionen entwickelt. Wir empfehlen, diese oder neuere Versionen zu verwenden.
qiskit[all]~=2.5.2
In Qiskit werden Quantenoperatoren mithilfe von Klassen aus dem Modul quantum_info dargestellt. Die wichtigste Operator-Klasse ist SparsePauliOp, die einen allgemeinen Quantenoperator als Linearkombination von Pauli-Strings repräsentiert. SparsePauliOp ist die am häufigsten verwendete Klasse zur Darstellung quantenmechanischer Observablen. Der Rest dieser Seite erklärt, wie du SparsePauliOp und andere Operator-Klassen verwendest.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"numpy": "numpy", "qiskit": "qiskit"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
import numpy as np
from qiskit.quantum_info.operators import Operator, Pauli, SparsePauliOp
SparsePauliOp
Die Klasse SparsePauliOp repräsentiert eine Linearkombination von Pauli-Strings. Es gibt mehrere Möglichkeiten, einen SparsePauliOp zu initialisieren, aber die flexibelste ist die Methode from_sparse_list, wie in der folgenden Code-Zelle gezeigt. from_sparse_list akzeptiert eine Liste von Tripeln der Form (pauli_string, qubit_indices, coefficient).
op1 = SparsePauliOp.from_sparse_list(
[("ZX", [1, 4], 1.0), ("YY", [0, 3], -1 + 1j)], num_qubits=5
)
op1
SparsePauliOp(['XIIZI', 'IYIIY'],
coeffs=[ 1.+0.j, -1.+1.j])
SparsePauliOp unterstützt arithmetische Operationen, wie in der folgenden Code-Zelle gezeigt.
op2 = SparsePauliOp.from_sparse_list(
[("XXZ", [0, 1, 4], 1 + 2j), ("ZZ", [1, 2], -1 + 1j)], num_qubits=5
)
# Addition
print("op1 + op2:")
print(op1 + op2)
print()
# Multiplication by a scalar
print("2 * op1:")
print(2 * op1)
print()
# Operator multiplication (composition)
print("op1 @ op2:")
print(op1 @ op2)
print()
# Tensor product
print("op1.tensor(op2):")
print(op1.tensor(op2))
op1 + op2:
SparsePauliOp(['XIIZI', 'IYIIY', 'ZIIXX', 'IIZZI'],
coeffs=[ 1.+0.j, -1.+1.j, 1.+2.j, -1.+1.j])
2 * op1:
SparsePauliOp(['XIIZI', 'IYIIY'],
coeffs=[ 2.+0.j, -2.+2.j])
op1 @ op2:
SparsePauliOp(['YIIYX', 'XIZII', 'ZYIXZ', 'IYZZY'],
coeffs=[ 1.+2.j, -1.+1.j, -1.+3.j, 0.-2.j])
op1.tensor(op2):
SparsePauliOp(['XIIZIZIIXX', 'XIIZIIIZZI', 'IYIIYZIIXX', 'IYIIYIIZZI'],
coeffs=[ 1.+2.j, -1.+1.j, -3.-1.j, 0.-2.j])
Pauli
Die Klasse Pauli repräsentiert einen einzelnen Pauli-String mit einem optionalen Phasenkoeffizienten aus der Menge . Ein Pauli kann durch Übergabe eines Strings aus Zeichen der Menge {"I", "X", "Y", "Z"} initialisiert werden, optional mit einem der Präfixe {"", "i", "-", "-i"} zur Darstellung des Phasenkoeffizienten.
op1 = Pauli("iXX")
op1
Pauli('iXX')
Die folgende Code-Zelle demonstriert die Verwendung einiger Attribute und Methoden.
print(f"Dimension of {op1}: {op1.dim}")
print(f"Phase of {op1}: {op1.phase}")
print(f"Matrix representation of {op1}: \n {op1.to_matrix()}")
Dimension of iXX: (4, 4)
Phase of iXX: 3
Matrix representation of iXX:
[[0.+0.j 0.+0.j 0.+0.j 0.+1.j]
[0.+0.j 0.+0.j 0.+1.j 0.+0.j]
[0.+0.j 0.+1.j 0.+0.j 0.+0.j]
[0.+1.j 0.+0.j 0.+0.j 0.+0.j]]
Pauli-Objekte verfügen über eine Reihe weiterer Methoden zur Manipulation von Operatoren, z. B. zur Bestimmung des Adjungierten, ob er mit einem anderen Pauli (anti)kommutiert, und zur Berechnung des Skalarprodukts mit einem anderen Pauli. Weitere Informationen findest du in der API-Dokumentation.
Operator
Die Klasse Operator repräsentiert einen allgemeinen linearen Operator. Im Gegensatz zu SparsePauliOp speichert Operator den linearen Operator als dichte Matrix. Da der für eine dichte Matrix benötigte Speicher exponentiell mit der Anzahl der Qubits wächst, ist die Klasse Operator nur für eine kleine Anzahl von Qubits geeignet.
Du kannst einen Operator initialisieren, indem du direkt ein Numpy-Array übergibst, das die Matrix des Operators enthält. Der folgende Code erstellt zum Beispiel einen Zwei-Qubit-Pauli-XX-Operator:
XX = Operator(
np.array(
[
[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 1, 0, 0],
[1, 0, 0, 0],
]
)
)
XX
Operator([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]],
input_dims=(2, 2), output_dims=(2, 2))
Das Operator-Objekt speichert die zugrundeliegende Matrix sowie die Ein- und Ausgabedimensionen der Teilsysteme.
-
data: Um auf das zugrundeliegende Numpy-Array zuzugreifen, kannst du die EigenschaftOperator.dataverwenden. -
dim: Um die gesamte Ein- und Ausgabedimension des Operators zurückzugeben, kannst du die EigenschaftOperator.dimverwenden. Hinweis: Die Ausgabe erfolgt als Tupel(input_dim, output_dim)— also in umgekehrter Reihenfolge gegenüber der Form der zugrundeliegenden Matrix.
XX.data
array([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]])
input_dim, output_dim = XX.dim
input_dim, output_dim
(4, 4)
Die Operator-Klasse verfolgt außerdem die Dimensionen der Teilsysteme, die zur Komposition von Operatoren verwendet werden können. Diese sind über die Funktionen input_dims und output_dims zugänglich.
Für mal Operatoren wird automatisch angenommen, dass die Ein- und Ausgabedimensionen M-Qubit- bzw. N-Qubit-Dimensionen sind:
op = Operator(np.random.rand(2**1, 2**2))
print("Input dimensions:", op.input_dims())
print("Output dimensions:", op.output_dims())
Input dimensions: (2, 2)
Output dimensions: (2,)
Wenn sich die übergebene Eingabematrix nicht in Qubit-Teilsysteme zerlegen lässt, wird sie als Einzelqubit-Operator gespeichert. Zum Beispiel für eine -Matrix:
op = Operator(np.random.rand(6, 6))
print("Input dimensions:", op.input_dims())
print("Output dimensions:", op.output_dims())
Input dimensions: (6,)
Output dimensions: (6,)
Die Ein- und Ausgabedimension kann beim Initialisieren eines neuen Operators auch manuell angegeben werden:
# Force input dimension to be (4,) rather than (2, 2)
op = Operator(np.random.rand(2**1, 2**2), input_dims=[4])
print("Input dimensions:", op.input_dims())
print("Output dimensions:", op.output_dims())
Input dimensions: (4,)
Output dimensions: (2,)
# Specify system is a qubit and qutrit
op = Operator(np.random.rand(6, 6), input_dims=[2, 3], output_dims=[2, 3])
print("Input dimensions:", op.input_dims())
print("Output dimensions:", op.output_dims())
Input dimensions: (2, 3)
Output dimensions: (2, 3)
Du kannst auch nur die Ein- oder Ausgabedimensionen einer Teilmenge von Teilsystemen mit den Funktionen input_dims und output_dims extrahieren:
print("Dimension of input system 0:", op.input_dims([0]))
print("Dimension of input system 1:", op.input_dims([1]))
Dimension of input system 0: (2,)
Dimension of input system 1: (3,)
Nächste Schritte
- Lerne, wie du Observablen in der Pauli-Basis angibst.
- Sieh dir ein Beispiel zur Verwendung von Operatoren im Tutorial Combine error mitigation options with the Estimator primitive an.
- Lies mehr zur ausführlichen Behandlung der Operator-Klasse.
- Erkunde die Operator-API-Referenz.