דלג לתוכן הראשי

בניית Circuit

גרסאות חבילות

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

qiskit[all]~=2.3.0

דף זה בוחן לעומק את המחלקה QuantumCircuit ב-Qiskit SDK, כולל מספר שיטות מתקדמות יותר שבהן תוכל להשתמש כדי ליצור Circuit קוונטיים.

מהו Circuit קוונטי?

Circuit קוונטי פשוט הוא אוסף של Qubit ורשימת הוראות הפועלות עליהם. להמחשה, התא הבא יוצר Circuit חדש עם שני Qubit חדשים, ולאחר מכן מציג את המאפיין qubits של ה-Circuit, שהוא רשימה של Qubit בסדר מהביט הפחות משמעותי q0q_0 עד הביט המשמעותי ביותר qnq_n.

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

Output of the previous code cell

אובייקטים של הוראות Circuit יכולים להכיל Circuit "הגדרה" המתארים את ההוראה במונחים של הוראות בסיסיות יותר. לדוגמה, ה-X-gate מוגדר כמקרה מיוחד של ה-U3-gate, Gate כללי יותר לQubit בודד.

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

Output of the previous code cell

הוראות ו-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")

Output of the previous code cell

כדי לשלב שני Circuit, השתמש בשיטה compose. שיטה זו מקבלת QuantumCircuit נוסף ורשימת מיפויי Qubit אופציונלית.

הערה

השיטה compose מחזירה Circuit חדש ואינה משנה את אף אחד מה-Circuit עליהם היא פועלת. כדי לשנות את ה-Circuit שעליו אתה קורא לשיטה 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)

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

Output of the previous code cell

ייתכן שתרצה גם לקמפל Circuit להוראות כדי לשמור על ארגון ה-Circuit שלך. תוכל להמיר Circuit להוראה על-ידי שימוש בשיטה to_instruction, ולאחר מכן לצרף אותה ל-Circuit אחר כמו כל הוראה אחרת. ה-Circuit המצויר בתא הבא שקול מבחינה פונקציונלית ל-Circuit המצויר בתא הקודם.

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

Output of the previous code cell

אם ה-Circuit שלך הוא יוניטרי, תוכל להמיר אותו ל-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 מחזירה Circuit חדש ואינה משנה את ה-Circuit עליו היא פועלת.

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

Output of the previous code cell

מדידת Qubit

מדידות משמשות לדגימת מצבי Qubit בודדים ולהעברת התוצאות לרגיסטר קלאסי. שים לב שאם אתה שולח Circuit ל-primitive מסוג Sampler, מדידות הן חובה. עם זאת, Circuit הנשלחים ל-primitive מסוג Estimator אסור שיכילו מדידות.

ניתן למדוד Qubit בשלוש שיטות: measure, measure_all ו-measure_active. כדי ללמוד כיצד להמחיש תוצאות מדידה, ראה את דף המחשת תוצאות.

  1. QuantumCircuit.measure : מודד כל Qubit בארגומנט הראשון על הביט הקלאסי הנתון כארגומנט השני. שיטה זו מאפשרת שליטה מלאה על מקום אחסון תוצאת המדידה.

  2. QuantumCircuit.measure_all : אינה מקבלת ארגומנט וניתן להשתמש בה עבור Circuit קוונטיים ללא ביטים קלאסיים מוגדרים מראש. היא יוצרת חוטים קלאסיים ומאחסנת תוצאות מדידה בסדר. לדוגמה, מדידה של Qubit qiq_i מאוחסנת ב-cbit measimeas_i). היא גם מוסיפה מחסום לפני המדידה.

  3. QuantumCircuit.measure_active : דומה ל-measure_all, אך מודדת רק Qubit שיש להם פעולות.

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

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

Output of the previous code cell

התא הבא יוצר וריאציות רבות של Circuit זה ומציג אחת מהן.

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

circuits[0].draw("mpl")

Output of the previous code cell

תוכל למצוא רשימת הפרמטרים הלא מוגדרים של 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)
Forgotten the method name? Try asking Qiskit Code Assistant.

השלבים הבאים

המלצות