Zum Hauptinhalt springen
Dieses Projekt befindet sich in der Beta-Phase. Einen Fehler gefunden? GitHub Issue erstellen. Frage oder Idee? In Discussions fragen — wir freuen uns über dein Feedback!
Wie ist die Übersetzungsqualität auf dieser Seite?

Ü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 { +1,i,−1,−i }\set{+1, i, -1, -i}. 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 Eigenschaft Operator.data verwenden.

  • dim: Um die gesamte Ein- und Ausgabedimension des Operators zurückzugeben, kannst du die Eigenschaft Operator.dim verwenden. 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 2N2^N mal 2M2^M 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 6×66\times6-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​

Empfehlungen