انتقل إلى المحتوى الرئيسي
هذا المشروع في مرحلة تجريبية. وجدت خطأ؟ افتح مشكلة على GitHub. لديك سؤال أو فكرة؟ اسأل في Discussions — نحب سماع ملاحظاتك!
كيف جودة الترجمة في هذه الصفحة؟

بناء الدوائر

إصدارات الحزم

تم تطوير الكود في هذه الصفحة باستخدام المتطلبات التالية. نوصي باستخدام هذه الإصدارات أو إصدارات أحدث.

qiskit[all]~=2.5.2

تلقي هذه الصفحة نظرة أقرب على فئة QuantumCircuit في Qiskit SDK، بما في ذلك بعض الطرق الأكثر تقدمًا التي يمكنك استخدامها لإنشاء دارات كمومية (Circuits).

ما هي الدائرة الكمومية؟​

الدائرة الكمومية البسيطة هي مجموعة من الكيوبتات وقائمة من التعليمات التي تعمل على تلك الكيوبتات. للتوضيح، تُنشئ الخلية التالية دائرة جديدة تضم كيوبتين جديدين، ثم تعرض خاصية الدائرة qubits، وهي قائمة من Qubits بالترتيب من أقل بت أهمية q0q_0 إلى أكثر بت أهمية qnq_n.

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

Output of the previous code cell

يمكن أن تحتوي كائنات تعليمات الدائرة على دوائر "تعريف" تصف التعليمة بمصطلحات تعليمات أكثر أساسية. على سبيل المثال، يُعرَّف بوابة X باعتبارها حالة خاصة من بوابة U3، وهي بوابة أكثر عمومية لكيوبت واحد.

# Draw definition circuit of 0th instruction in `qc`
qc.data[0].operation.definition.draw("mpl")

Output of the previous code cell

التعليمات والدوائر متشابهة في أنها تصف كلتاهما عمليات على البتات و 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")

Output of the previous code cell

لدمج دائرتين، استخدم طريقة compose. تقبل هذه الطريقة كائن QuantumCircuit آخر وقائمةً اختيارية من تعيينات qubits.

ملاحظة

تُعيد طريقة compose دائرةً جديدة ولا تُعدِّل أيًّا من الدائرتين اللتين تعمل عليهما. لتعديل الدائرة التي تستدعي عليها طريقة compose، استخدم الوسيط inplace=True.

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

Output of the previous code cell

قد ترغب أيضًا في تجميع الدوائر كتعليمات للحفاظ على تنظيمها. يمكنك تحويل دائرة إلى تعليمة باستخدام طريقة to_instruction، ثم إلحاقها بدائرة أخرى كما تفعل مع أي تعليمة أخرى. الدائرة المرسومة في الكود التالي مكافئة وظيفيًا للدائرة المرسومة في الكود السابق.

inst = qc_b.to_instruction()
qc_a.append(inst, [1, 3])
qc_a.draw("mpl")

Output of the previous code cell

إذا كانت دائرتك واحدية (unitary)، يمكنك تحويلها إلى Gate باستخدام طريقة to_gate. كائنات Gate هي أنواع محددة من التعليمات تمتلك ميزات إضافية، مثل طريقة control التي تُضيف تحكمًا كموميًا.

gate = qc_b.to_gate().control()
qc_a.append(gate, [0, 1, 3])
qc_a.draw("mpl")

Output of the previous code cell

لرؤية ما يجري، يمكنك استخدام طريقة decompose لتوسيع كل تعليمة إلى تعريفها.

ملاحظة

تُعيد طريقة decompose دائرةً جديدة ولا تُعدِّل الدائرة التي تعمل عليها.

qc_a.decompose().draw("mpl")

Output of the previous code cell

قياس qubits​

تُستخدم القياسات لأخذ عيِّنات من حالات qubits الفردية ونقل النتائج إلى سجل كلاسيكي. لاحظ أنه إذا كنت تُرسل الدوائر إلى بدائيّة Sampler، فإن القياسات مطلوبة. أما الدوائر المرسلة إلى بدائيّة Estimator فيجب ألا تحتوي على قياسات.

يمكن قياس qubits باستخدام ثلاث طرق: measure وmeasure_all وmeasure_active. لمعرفة كيفية تصور نتائج القياس، راجع صفحة تصور النتائج.

  1. QuantumCircuit.measure : يقيس كل كيوبت في المعامل الأول ويخزّن نتيجته في البت الكلاسيكي المحدد في المعامل الثاني. تتيح هذه الطريقة تحكمًا كاملًا في مكان تخزين نتيجة القياس.

  2. QuantumCircuit.measure_all : لا تأخذ أي معامل ويمكن استخدامها للدوائر الكمومية التي لا تحتوي على بتات كلاسيكية مُعرَّفة مسبقًا. تُنشئ أسلاكًا كلاسيكية وتخزن نتائج القياس بالترتيب. على سبيل المثال، يُخزَّن قياس الكيوبت qiq_i في cbitmeasimeas_i). كما تُضيف حاجزًا قبل القياس.

  3. QuantumCircuit.measure_active : مشابهة لـ measure_all، لكنها تقيس فقط qubits التي تحتوي على عمليات.

qc1 = QuantumCircuit(2, 2)
qc1.measure(0, 1)
qc1.draw("mpl", cregbundle=False)

Output of the previous code cell

qc2 = QuantumCircuit(2)
qc2.measure_all()
qc2.draw("mpl", cregbundle=False)

Output of the previous code cell

qc3 = QuantumCircuit(2)
qc3.x(1)
qc3.measure_active()
qc3.draw("mpl", cregbundle=False)

Output of the previous code cell

الدوائر ذات المعاملات​

تتضمن كثير من الخوارزميات الكمومية قريبة المدى تنفيذ صيغ متعددة من دائرة كمومية. بما أن بناء الدوائر الكبيرة وتحسينها قد يكون مُكلفًا حسابيًا، يدعم 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")

Output of the previous code cell

يُنشئ الكود التالي تغييرات عديدة على هذه الدائرة ويعرض أحدها.

circuits = []
for value in range(100):
circuits.append(qc.assign_parameters({angle: value}))

circuits[0].draw("mpl")

Output of the previous code cell

يمكنك العثور على قائمة المعاملات غير المُعرَّفة في الدائرة من خلال سمة 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)

الخطوات التالية​

توصيات