بناء الدوائر
إصدارات الحزم
تم تطوير الكود في هذه الصفحة باستخدام المتطلبات التالية. نوصي باستخدام هذه الإصدارات أو إصدارات أحدث.
qiskit[all]~=2.5.2
تلقي هذه الصفحة نظرة أقرب على فئة QuantumCircuit في Qiskit SDK، بما في ذلك بعض الطرق الأكثر تقدمًا التي يمكنك استخدامها لإنشاء دارات كمومية (Circuits).
ما هي الدائرة الكمومية؟
الدائرة الكمومية البسيطة هي مجموعة من الكيوبتات وقائمة من التعليمات التي تعمل على تلك الكيوبتات. للتوضيح، تُنشئ الخلية التالية دائرة جديدة تضم كيوبتين جديدين، ثم تعرض خاصية الدائرة qubits، وهي قائمة من Qubits بالترتيب من أقل بت أهمية إلى أكثر بت أهمية .
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"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")
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.qubits
[<Qubit register=(2, "q"), index=0>, <Qubit register=(2, "q"), index=1>]
يمكن دمج كائنات QuantumRegister وClassicalRegister المتعددة لإنشاء دائرة. ويمكن تسمية كل QuantumRegister وClassicalRegister أيضًا.
from qiskit.circuit import QuantumRegister, ClassicalRegister
qr1 = QuantumRegister(2, "qreg1") # Create a QuantumRegister with 2 qubits
qr2 = QuantumRegister(1, "qreg2") # Create a QuantumRegister with 1 qubit
cr1 = ClassicalRegister(3, "creg1") # Create a ClassicalRegister with 3 cbits
combined_circ = QuantumCircuit(
qr1, qr2, cr1
) # Create a quantum circuit with 2 QuantumRegisters and 1 ClassicalRegister
combined_circ.qubits
[<Qubit register=(2, "qreg1"), index=0>,
<Qubit register=(2, "qreg1"), index=1>,
<Qubit register=(1, "qreg2"), index=0>]
يمكنك معرفة فهرس الكيوبت وسجله باستخدام طريقة find_bit الخاصة بالدائرة وسماتها.
desired_qubit = qr2[0] # Qubit 0 of register 'qreg2'
print("Index:", combined_circ.find_bit(desired_qubit).index)
print("Register:", combined_circ.find_bit(desired_qubit).registers)
Index: 2
Register: [(QuantumRegister(1, 'qreg2'), 0)]
إضافة تعليمة إلى الدائرة يُلحق التعليمة بسمة data الخاصة بالدائرة. يُظهر ناتج الكود التالي أن data هي قائمة من كائنات CircuitInstruction، ولكل منها سمة operation وسمة qubits.
qc.x(0) # Add X-gate to qubit 0
qc.data
[CircuitInstruction(operation=Instruction(name='x', num_qubits=1, num_clbits=0, params=[]), qubits=(<Qubit register=(2, "q"), index=0>,), clbits=())]
أسهل طريقة لعرض هذه المعلومات هي استخدام طريقة draw، التي تُعيد تمثيلًا مرئيًا للدائرة. راجع تصور الدوائر للاطلاع على طرق مختلفة لعرض الدوائر الكمومية.
qc.draw("mpl")
يمكن أن تحتوي كائنات تعليمات الدائرة على دوائر "تعريف" تصف التعليمة بمصطلحات تعليمات أكثر أساسية. على سبيل المثال، يُعرَّف بوابة X باعتبارها حالة خاصة من بوابة U3، وهي بوابة أكثر عمومية لكيوبت واحد.
# Draw definition circuit of 0th instruction in `qc`
qc.data[0].operation.definition.draw("mpl")
التعليمات والدوائر متشابهة في أنها تصف كلتاهما عمليات على البتات و qubits، لكنها تخدم أغراضًا مختلفة:
-
تُعامَل التعليمات على أنها ثابتة، وعادةً ما تُعيد طرقها تعليمات جديدة (دون تغيير الكائن الأصلي).
-
صُمِّمت الدوائر للبناء عبر أسطر كثيرة من الكود، وكثيرًا ما تُعدِّل طرق
QuantumCircuitالكائن الموجود.
ما هو عمق الدائرة؟
عمق الدائرة الكمومية هو مقياس لعدد "طبقات" البوابات الكمومية المنفَّذة بالتوازي اللازمة لإتمام الحساب الذي تُعرِّفه الدائرة. لأن البوابات الكمومية تستغرق وقتًا في التنفيذ، يتوافق عمق الدائرة تقريبًا مع المدة الزمنية التي يحتاجها الحاسوب الكمومي لتنفيذها. لذا يُعدّ عمق الدائرة أحد المقاييس المهمة المستخدمة لتقدير ما إذا كان بالإمكان تشغيل الدائرة الكمومية على جهاز ما.
تُوضِّح بقية هذه الصفحة كيفية التعامل مع الدوائر الكمومية.
بناء الدوائر
تُضيف طرق مثل QuantumCircuit.h وQuantumCircuit.cx تعليمات محددة إلى الدوائر. لإضافة تعليمات إلى دائرة بشكل أعم، استخدم طريقة append. تأخذ هذه الطريقة تعليمةً وقائمةً من qubits لتطبيق التعليمة عليها. راجع توثيق واجهة برمجة مكتبة الدوائر للاطلاع على قائمة التعليمات المدعومة.
from qiskit.circuit.library import HGate
qc = QuantumCircuit(1)
qc.append(
HGate(), # New HGate instruction
[0], # Apply to qubit 0
)
qc.draw("mpl")
لدمج دائرتين، استخدم طريقة compose. تقبل هذه الطريقة كائن QuantumCircuit آخر وقائمةً اختيارية من تعيينات qubits.
qc_a = QuantumCircuit(4)
qc_a.x(0)
qc_b = QuantumCircuit(2, name="qc_b")
qc_b.y(0)
qc_b.z(1)
# keep qubits (0, 1) of qc_a with same index.
# compose qubits (0,1) of qc_b to qubits (1, 3), respectively, of new composite circuit
combined = qc_a.compose(qc_b, qubits=[1, 3])
combined.draw("mpl")
قد ترغب أيضًا في تجميع الدوائر كتعليمات للحفاظ على تنظيمها. يمكنك تحويل دائرة إلى تعليمة باستخدام طريقة to_instruction، ثم إلحاقها بدائرة أخرى كما تفعل مع أي تعليمة أخرى. الدائرة المرسومة في الكود التالي مكافئة وظيفيًا للدائرة المرسومة في الكود السابق.
inst = qc_b.to_instruction()
qc_a.append(inst, [1, 3])
qc_a.draw("mpl")
إذا كانت دائرتك واحدية (unitary)، يمكنك تحويلها إلى Gate باستخدام طريقة to_gate. كائنات Gate هي أنواع محددة من التعليمات تمتلك ميزات إضافية، مثل طريقة control التي تُضيف تحكمًا كموميًا.
gate = qc_b.to_gate().control()
qc_a.append(gate, [0, 1, 3])
qc_a.draw("mpl")
لرؤية ما يجري، يمكنك استخدام طريقة decompose لتوسيع كل تعليمة إلى تعريفها.
تُعيد طريقة decompose دائرةً جديدة ولا تُعدِّل الدائرة التي تعمل عليها.
qc_a.decompose().draw("mpl")
قياس qubits
تُستخدم القياسات لأخذ عيِّنات من حالات qubits الفردية ونقل النتائج إلى سجل كلاسيكي. لاحظ أنه إذا كنت تُرسل الدوائر إلى بدائيّة Sampler، فإن القياسات مطلوبة. أما الدوائر المرسلة إلى بدائيّة Estimator فيجب ألا تحتوي على قياسات.
يمكن قياس qubits باستخدام ثلاث طرق: measure وmeasure_all وmeasure_active. لمعرفة كيفية تصور نتائج القياس، راجع صفحة تصور النتائج.
-
QuantumCircuit.measure: يقيس كل كيوبت في المعامل الأول ويخزّن نتيجته في البت الكلاسيكي المحدد في المعامل الثاني. تتيح هذه الطريقة تحكمًا كاملًا في مكان تخزين نتيجة القياس. -
QuantumCircuit.measure_all: لا تأخذ أي معامل ويمكن استخدامها للدوائر الكمومية التي لا تحتوي على بتات كلاسيكية مُعرَّفة مسبقًا. تُنشئ أسلاكًا كلاسيكية وتخزن نتائج القياس بالترتيب. على سبيل المثال، يُخزَّن قياس الكيوبت في cbit). كما تُضيف حاجزًا قبل القياس. -
QuantumCircuit.measure_active: مشابهة لـmeasure_all، لكنها تقيس فقط qubits التي تحتوي على عمليات.
qc1 = QuantumCircuit(2, 2)
qc1.measure(0, 1)
qc1.draw("mpl", cregbundle=False)
qc2 = QuantumCircuit(2)
qc2.measure_all()
qc2.draw("mpl", cregbundle=False)
qc3 = QuantumCircuit(2)
qc3.x(1)
qc3.measure_active()
qc3.draw("mpl", cregbundle=False)
الدوائر ذات المعاملات
تتضمن كثير من الخوارزميات الكمومية قريبة المدى تنفيذ صيغ متعددة من دائرة كمومية. بما أن بناء الدوائر الكبيرة وتحسينها قد يكون مُكلفًا حسابيًا، يدعم Qiskit الدوائر ذات المعاملات. هذه الدوائر تحتوي على معاملات غير مُعرَّفة، ولا يلزم تحديد قيمها إلا قُبيل تنفيذ الدائرة. يتيح لك ذلك نقل عملية بناء الدائرة وتحسينها خارج الحلقة الرئيسية للبرنامج. يُنشئ الكود التالي دائرة ذات معاملات ويعرضها.
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.circuit import Parameter
angle = Parameter("angle") # undefined number
# Create and optimize circuit once
qc = QuantumCircuit(1)
qc.rx(angle, 0)
qc = generate_preset_pass_manager(
optimization_level=3, basis_gates=["u", "cx"]
).run(qc)
qc.draw("mpl")
يُنشئ الكود التالي تغييرات عديدة على هذه الدائرة ويعرض أحدها.
circuits = []
for value in range(100):
circuits.append(qc.assign_parameters({angle: value}))
circuits[0].draw("mpl")
يمكنك العثور على قائمة المعاملات غير المُعرَّفة في الدائرة من خلال سمة parameters الخاصة بها.
qc.parameters
ParameterView([Parameter(angle)])
تغيير اسم المعامل
افتراضيًا، تبدأ أسماء المعاملات في الدوائر ذات المعاملات بالبادئة x- مثلًا x[0]. يمكنك تغيير الأسماء بعد تعريفها، كما هو موضح في المثال التالي.
from qiskit.circuit.library import z_feature_map
from qiskit.circuit import ParameterVector
# Define a parameterized circuit with default names
# For example, x[0]
circuit = z_feature_map(2)
# Set new parameter names
# They will now be prefixed by `hi` instead
# For example, hi[0]
training_params = ParameterVector("hi", 2)
# Assign parameter names to the quantum circuit
circuit = circuit.assign_parameters(parameters=training_params)
الخطوات التالية
- لتعلم الخوارزميات الكمومية قصيرة المدى، خذ دورة تصميم الخوارزميات التغايرية.
- اطلع على مثال للدوائر المستخدمة في درس خوارزمية غروفر.
- تعامل مع دوائر بسيطة باستخدام IBM Quantum Composer.