בניית Circuit
גרסאות חבילות
הקוד בדף זה פותח תוך שימוש בדרישות הבאות. אנו ממליצים להשתמש בגרסאות אלה או בחדשות יותר.
qiskit[all]~=2.3.0
דף זה בוחן לעומק את המחלקה QuantumCircuit ב-Qiskit SDK, כולל מספר שיטות מתקדמות יותר שבהן תוכל להשתמש כדי ליצור Circuit קוונטיים.
מהו Circuit קוונטי?
Circuit קוונטי פשוט הוא אוסף של Qubit ורשימת הוראות הפועלות עליהם. להמחשה, התא הבא יוצר Circuit חדש עם שני Qubit חדשים, ולאחר מכן מציג את המאפיין qubits של ה-Circuit, שהוא רשימה של Qubit בסדר מהביט הפחות משמעותי עד הביט המשמעותי ביותר .
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.qubits
[<Qubit register=(2, "q"), index=0>, <Qubit register=(2, "q"), index=1>]
ניתן לשלב מספר אובייקטים מסוג QuantumRegister ו-ClassicalRegister כדי ליצור Circuit. לכל 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>]
תוכל למצוא את האינדקס והרגיסטר של Qubit על-ידי שימוש בשיטה find_bit של ה-Circuit ובמאפייניה.
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)]
הוספת הוראה ל-Circuit מוסיפה את ההוראה למאפיין data של ה-Circuit. פלט התא הבא מראה כי 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, שמחזירה המחשה ויזואלית של Circuit. ראה המחשת Circuit לדרכים שונות להצגת Circuit קוונטיים.
qc.draw("mpl")
אובייקטים של הוראות Circuit יכולים להכיל Circuit "הגדרה" המתארים את ההוראה במונחים של הוראות בסיסיות יותר. לדוגמה, ה-X-gate מוגדר כמקרה מיוחד של ה-U3-gate, Gate כללי יותר לQubit בודד.
# Draw definition circuit of 0th instruction in `qc`
qc.data[0].operation.definition.draw("mpl")
הוראות ו-Circuit דומים בכך ששניהם מתארים פעולות על ביטים ו-Qubit, אך יש להם מטרות שונות:
- הוראות נחשבות כקבועות, ושיטותיהן יחזירו בדרך כלל הוראות חדשות (מבלי לשנות את האובייקט המקורי).
- Circuit מיועדים לבנייה על פני שורות קוד רבות, ושיטות
QuantumCircuitלרוב משנות את האובייקט הקיים.
מהי עומק Circuit?
ה-depth() של Circuit קוונטי הוא מדד למספר ה"שכבות" של Gate קוונטיים, המבוצעות במקביל, הנדרשות להשלמת החישוב המוגדר על ידי ה-Circuit. מכיוון שמימוש Gate קוונטיים לוקח זמן, העומק של Circuit תואם בקירוב לכמות הזמן שלוקח למחשב הקוונטי לבצע את ה-Circuit. לפיכך, עומק ה-Circuit הוא אחד הכמויות החשובות המשמשות למדידת האפשרות להריץ Circuit קוונטי על מכשיר.
שאר הדף ממחיש כיצד לתפעל Circuit קוונטיים.
בניית Circuit
שיטות כגון QuantumCircuit.h ו-QuantumCircuit.cx מוסיפות הוראות ספציפיות ל-Circuit. כדי להוסיף הוראות ל-Circuit באופן כללי יותר, השתמש בשיטה append. שיטה זו מקבלת הוראה ורשימת Qubit עליהם יש להחיל את ההוראה. ראה את תיעוד ה-API של ספריית Circuit לקבלת רשימת הוראות נתמכות.
from qiskit.circuit.library import HGate
qc = QuantumCircuit(1)
qc.append(
HGate(), # New HGate instruction
[0], # Apply to qubit 0
)
qc.draw("mpl")
כדי לשלב שני Circuit, השתמש בשיטה compose. שיטה זו מקבלת QuantumCircuit נוסף ורשימת מיפויי Qubit אופציונלית.
qc_a = QuantumCircuit(4)
qc_a.x(0)
qc_b = QuantumCircuit(2, name="qc_b")
qc_b.y(0)
qc_b.z(1)
# compose qubits (0, 1) of qc_a to qubits (1, 3) of qc_b respectively
combined = qc_a.compose(qc_b, qubits=[1, 3])
combined.draw("mpl")
ייתכן שתרצה גם לקמפל Circuit להוראות כדי לשמור על ארגון ה-Circuit שלך. תוכל להמיר Circuit להוראה על-ידי שימוש בשיטה to_instruction, ולאחר מכן לצרף אותה ל-Circuit אחר כמו כל הוראה אחרת. ה-Circuit המצויר בתא הבא שקול מבחינה פונקציונלית ל-Circuit המצויר בתא הקודם.
inst = qc_b.to_instruction()
qc_a.append(inst, [1, 3])
qc_a.draw("mpl")
אם ה-Circuit שלך הוא יוניטרי, תוכל להמיר אותו ל-Gate על-ידי שימוש בשיטה to_gate. אובייקטי Gate הם סוגים ספציפיים של הוראות בעלות תכונות נוספות, כגון שיטת control, שמוסיפה בקרה קוונטית.
gate = qc_b.to_gate().control()
qc_a.append(gate, [0, 1, 3])
qc_a.draw("mpl")
כדי לראות מה קורה, תוכל להשתמש בשיטה decompose כדי לפרק כל הוראה להגדרתה.
השיטה decompose מחזירה Circuit חדש ואינה משנה את ה-Circuit עליו היא פועלת.
qc_a.decompose().draw("mpl")
מדידת Qubit
מדידות משמשות לדגימת מצבי Qubit בודדים ולהעברת התוצאות לרגיסטר קלאסי. שים לב שאם אתה שולח Circuit ל-primitive מסוג Sampler, מדידות הן חובה. עם זאת, Circuit הנשלחים ל-primitive מסוג Estimator אסור שיכילו מדידות.
ניתן למדוד Qubit בשלוש שיטות: measure, measure_all ו-measure_active. כדי ללמוד כיצד להמחיש תוצאות מדידה, ראה את דף המחשת תוצאות.
-
QuantumCircuit.measure: מודד כל Qubit בארגומנט הראשון על הביט הקלאסי הנתון כארגומנט השני. שיטה זו מאפשרת שליטה מלאה על מקום אחסון תוצאת המדידה. -
QuantumCircuit.measure_all: אינה מקבלת ארגומנט וניתן להשתמש בה עבור Circuit קוונטיים ללא ביטים קלאסיים מוגדרים מראש. היא יוצרת חוטים קלאסיים ומאחסנת תוצאות מדידה בסדר. לדוגמה, מדידה של Qubit מאוחסנת ב-cbit ). היא גם מוסיפה מחסום לפני המדידה. -
QuantumCircuit.measure_active: דומה ל-measure_all, אך מודדת רק Qubit שיש להם פעולות.
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)
Circuit פרמטריים
אלגוריתמים קוונטיים רבים לטווח הקרוב כוללים הרצה של וריאציות רבות של Circuit קוונטי. מכיוון שבניית Circuit גדולים ואופטימיזציה שלהם עלולים להיות יקרים מבחינה חישובית, Qiskit תומך ב-Circuit פרמטריים. ל-Circuit אלה יש פרמטרים לא מוגדרים, וערכיהם אינם חייבים להיות מוגדרים עד ממש לפני הרצת ה-Circuit. זה מאפשר לך להוציא את בניית ה-Circuit ואופטימיזציה שלו מחוץ ללולאת התוכנית הראשית. התא הבא יוצר ומציג Circuit פרמטרי.
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")
התא הבא יוצר וריאציות רבות של Circuit זה ומציג אחת מהן.
circuits = []
for value in range(100):
circuits.append(qc.assign_parameters({angle: value}))
circuits[0].draw("mpl")
תוכל למצוא רשימת הפרמטרים הלא מוגדרים של Circuit במאפיין parameters שלו.
qc.parameters
ParameterView([Parameter(angle)])
שינוי שם פרמטר
כברירת מחדל, שמות הפרמטרים של Circuit פרמטרי מקבלים קידומת 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)
השלבים הבאים
- כדי ללמוד על אלגוריתמים קוונטיים לטווח הקרוב, קח את הקורס עיצוב אלגוריתם ורייאציוני.
- ראה דוגמה של Circuit בשימוש בהדרכה אלגוריתם של גרובר.
- עבוד עם Circuit פשוטים באמצעות IBM Quantum Composer.