نظرة عامة على فئات العمليات
إصدارات الحزم
تم تطوير الكود في هذه الصفحة باستخدام المتطلبات التالية. نوصي باستخدام هذه الإصدارات أو أحدث منها.
qiskit[all]~=2.3.0
في Qiskit، تُمثَّل العمليات الكمية باستخدام فئات من وحدة quantum_info. أهم فئة للعمليات هي SparsePauliOp، التي تُمثّل عملية كمية عامة على شكل تركيبة خطية من سلاسل Pauli. تُعدّ SparsePauliOp الفئة الأكثر استخداماً لتمثيل المراصد الكمية. يشرح الجزء المتبقي من هذه الصفحة كيفية استخدام SparsePauliOp وفئات العمليات الأخرى.
# 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
تُمثّل فئة 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 واحدة مع معامل طور اختياري من المجموعة . يمكن تهيئة 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 عددًا من الأساليب الأخرى للتعامل مع العمليات، كتحديد مرافقها (adjoint)، ومعرفة ما إذا كانت تتبادل أو تُعاكس في التبادل مع Pauli أخرى، وحساب حاصل الضرب النقطي مع Pauli أخرى. راجع توثيق API للمزيد من المعلومات.
Operator
تُمثّل فئة Operator عاملاً خطياً عاماً. على خ لاف SparsePauliOp، تخزّن Operator العامل الخطي على شكل مصفوفة كثيفة. نظرًا لأن الذاكرة اللازمة لتخزين المصفوفة الكثيفة تتضاعف أسيّاً مع عدد الكيوبتات، فإن فئة Operator مناسبة فقط للاستخدام مع عدد صغير من الكيوبتات.
يمكنك تهيئة Operator بتمرير مصفوفة Numpy مباشرةً تحتوي على مصفوفة العامل. على سبيل المثال، تُنشئ الخلية البرمجية التالية عامل 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))
يخزّن كائن العامل المصفوفة الأساسية، وأبعاد ال إدخال والإخراج للأنظمة الفرعية.
data: للوصول إلى مصفوفة Numpy الأساسية، يمكنك استخدام خاصيةOperator.data.dims: لإرجاع إجمالي أبعاد الإدخال والإخراج للعامل، يمكنك استخدام خاصيةOperator.dim. ملاحظة: يُعاد الناتج كصف (tuple)(input_dim, output_dim)، وهو عكس شكل المصفوفة الأساسية.
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.
بالنسبة لعوامل في ، يُفترض تلقائيًا أن أبعاد الإدخال والإخراج تناظر M-كيوبت وN-كيوبت:
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,)
إذا كانت المصفوفة المُدخلة لا يمكن تقسيمها إلى أنظمة فرعية من الكيوبتات، فستُخزَّن كعامل ذي كيو بت واحد. على سبيل المثال، لمصفوفة :
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,)
الخطوات التالية
- تعلّم كيفية تحديد المراصد في أساس Pauli.
- اطّلع على مثال لاستخدام العمليات في برنامج تعليمي دمج خيارات تخفيف الأخطاء مع primitive المقدِّر.
- اقرأ المزيد عن تغطية متعمقة لفئة Operator.
- استكشف مرجع Operator API.