דלג לתוכן הראשי
פרויקט זה בשלב בטא. מצאת באג? פתח issue ב-GitHub. יש שאלה או רעיון? שאל ב-Discussions — נשמח לשמוע ממך!
מה איכות התרגום בדף זה?

סקירה של מחלקות אופרטורים

Package versions

הקוד בעמוד הזה פותח באמצעות הדרישות הבאות. אנחנו ממליצים להשתמש בגרסאות האלה או חדשות יותר.

qiskit[all]~=2.5.2

ב-Qiskit, אופרטורים קוונטיים מיוצגים באמצעות מחלקות ממודול quantum_info. מחלקת האופרטור החשובה ביותר היא SparsePauliOp, המייצגת אופרטור קוונטי כללי כצירוף לינארי של מחרוזות Pauli. SparsePauliOp היא המחלקה הנפוצה ביותר לייצוג משתנים קוונטיים הניתנים לצפייה. שאר הדף מסביר כיצד להשתמש ב-SparsePauliOp ובמחלקות אופרטורים אחרות.

# 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​

המחלקה SparsePauliOp מייצגת צירוף לינארי של מחרוזות Pauli. ישנן מספר דרכים לאתחל SparsePauliOp, אך הדרך הגמישה ביותר היא להשתמש בשיטה from_sparse_list, כפי שמודגם בתא הקוד הבא. ה-from_sparse_list מקבל רשימה של שלשות (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 תומך בפעולות חשבוניות, כפי שמודגם בתא הקוד הבא.

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​

המחלקה Pauli מייצגת מחרוזת Pauli בודדת עם מקדם פאזה אופציונלי מהקבוצה { +1,i,−1,−i }\set{+1, i, -1, -i}. ניתן לאתחל Pauli על ידי העברת מחרוזת תווים מהקבוצה {"I", "X", "Y", "Z"}, עם קידומת אופציונלית אחת מ-{"", "i", "-", "-i"} לייצוג מקדם הפאזה.

op1 = Pauli("iXX")
op1
Pauli('iXX')

תא הקוד הבא מדגים את השימוש בכמה מאפיינים ומתודות.

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 יש מספר שיטות נוספות למניפולציה של האופרטורים כגון קביעת הצמוד שלו, האם הוא (אנטי)מתחלף עם Pauli אחר, וחישוב המכפלה (ההרכבה) עם Pauli אחר. ראה בתיעוד ה-API למידע נוסף.

Operator​

המחלקה Operator מייצגת אופרטור לינארי כללי. בניגוד ל-SparsePauliOp, ה-Operator שומר את האופרטור הלינארי כמטריצה צפופה. מכיוון שהזיכרון הנדרש לאחסון מטריצה צפופה גדל באופן אקספוננציאלי עם מספר ה-Qubits, מחלקת Operator מתאימה רק לשימוש עם מספר קטן של qubits.

אתה יכול לאתחל Operator על ידי העברת מערך Numpy המאחסן את המטריצה של האופרטור. לדוגמה, תא הקוד הבא יוצר אופרטור Pauli XX דו-Qubit:

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))

אובייקט האופרטור שומר את המטריצה הבסיסית, וממדי הקלט והפלט של תת-מערכות.

  • data: לגישה למערך Numpy הבסיסי, ניתן להשתמש במאפיין Operator.data.

  • dim: להחזרת ממד הקלט והפלט הכולל של האופרטור, ניתן להשתמש במאפיין Operator.dim. שים לב: הפלט מוחזר כ-tuple (input_dim, output_dim), שהוא בסדר הפוך לצורה (shape) של המטריצה הבסיסית.

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)

מחלקת האופרטור עוקבת גם אחר ממדי תת-מערכות, שניתן להשתמש בהם להרכבת אופרטורים זה עם זה. ניתן לגשת אליהם באמצעות הפונקציות input_dims ו-output_dims.

עבור אופרטורים בגודל 2N2^N על 2M2^M, ממדי הקלט והפלט מונחים אוטומטית להיות M-Qubit ו-N-Qubit:

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,)

אם מטריצת הקלט אינה ניתנת לחלוקה לתת-מערכות של qubit, היא תישמר כאופרטור של qubit בודד. לדוגמה, עבור מטריצה 6×66\times6:

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,)

ניתן גם לציין ידנית את ממד הקלט והפלט בעת אתחול אופרטור חדש:

# 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)

אתה יכול גם לחלץ רק את ממדי הקלט או הפלט של תת-קבוצת תת-מערכות באמצעות הפונקציות input_dims ו-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,)

השלבים הבאים​