Przegląd klas operatorów
Wersje pakietów
Kod na tej stronie został opracowany z użyciem poniższych wymagań. Zalecamy korzystanie z tych lub nowszych wersji.
qiskit[all]~=2.3.0
W Qiskit operatory kwantowe są reprezentowane za pomocą klas z modułu quantum_info. Najważniejszą klasą operatorów jest SparsePauliOp, która reprezentuje ogólny operator kwantowy jako liniową kombinację ciągów Pauliego. SparsePauliOp to klasa najczęściej używana do reprezentowania kwantowych obserwowalnych. Pozostała część tej strony wyjaśnia, jak korzystać z SparsePauliOp i innych klas operatorów.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
import numpy as np
from qiskit.quantum_info.operators import Operator, Pauli, SparsePauliOp
SparsePauliOp
Klasa SparsePauliOp reprezentuje liniową kombinację ciągów Pauliego. Istnieje kilka sposobów inicjalizacji SparsePauliOp, jednak najbardziej elastycznym z nich jest użycie metody from_sparse_list, co zostało pokazane w poniższej komórce kodu. Metoda from_sparse_list przyjmuje listę trójek (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 obsługuje operacje arytmetyczne, co zostało przedstawione w poniższej komórce kodu.
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
Klasa Pauli reprezentuje pojedynczy ciąg Pauliego z opcjonalnym współczynnikiem fazowym ze zbioru . Obiekt Pauli można zainicjalizować, przekazując ciąg znaków ze zbioru {"I", "X", "Y", "Z"}, z opcjonalnym prefiksem z {"", "i", "-", "-i"} reprezentującym współczynnik fazowy.
op1 = Pauli("iXX")
op1
Pauli('iXX')
Poniższa komórka kodu demonstruje użycie wybranych atrybutów i metod.
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]]
Obiekty Pauli posiadają szereg innych metod do manipulowania operatorami, takich jak wyznaczanie sprzężenia hermitowskiego, sprawdzanie, czy (anty)komutuje z innym Pauli, oraz obliczanie iloczynu skalarnego z innym Pauli. Więcej informacji znajdziesz w dokumentacji API.
Operator
Klasa Operator reprezentuje ogólny operator liniowy. W przeciwieństwie do SparsePauliOp, klasa Operator przechowuje operator liniowy jako gęstą macierz. Ponieważ pamięć wymagana do przechowywania gęstej macierzy rośnie wykładniczo wraz z liczbą Qubitów, klasa Operator nadaje się do użytku jedynie z małą liczbą Qubitów.
Obiekt Operator możesz zainicjalizować, bezpośrednio przekazując tablicę Numpy przechowującą macierz operatora. Na przykład poniższa komórka kodu tworzy dwuqubitowy operator Pauli XX:
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))
Obiekt operatora przechowuje macierz bazową oraz wymiary wejściowe i wyjściowe podsystemów.
data: Aby uzyskać dostęp do bazowej tablicy Numpy, możesz skorzystać z właściwościOperator.data.dims: Aby zwrócić łączny wymiar wejściowy i wyjściowy operatora, możesz użyć właściwościOperator.dim. Uwaga: wynik jest zwracany jako krotka(input_dim, output_dim), co jest odwrotnością kształtu macierzy bazowej.
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)
Klasa operatora śledzi również wymiary podsystemów, co można wykorzystać do składania operatorów. Dostęp do nich można uzyskać za pomocą funkcji input_dims i output_dims.
Dla operatorów o wymiarach na wymiary wejściowe i wyjściowe są automatycznie przyjmowane jako M-qubitowe i N-qubitowe:
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,)
Jeśli macierz wejściowa nie jest podzielna na podsystemy qubitowe, zostanie zapisana jako operator jednopodsystemowy. Na przykład dla macierzy :
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,)
Wymiary wejściowe i wyjściowe można również podać ręcznie podczas inicjalizacji nowego operatora:
# 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)
Możesz również wyodrębnić tylko wymiary wejściowe lub wyjściowe podzbioru podsystemów, korzystając z funkcji input_dims i output_dims:
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,)
Następne kroki
- Dowiedz się, jak określać obserwowalne w bazie Pauliego.
- Zobacz przykład użycia operatorów w samouczku Łączenie opcji mitygacji błędów z prymitywem Estimator.
- Przeczytaj bardziej szczegółowe omówienie klasy Operator.
- Zapoznaj się z dokumentacją API klasy Operator.