Sari la conținutul principal

Construiește circuite

Versiuni de pachete

Codul de pe această pagină a fost dezvoltat folosind următoarele cerințe. Recomandăm utilizarea acestor versiuni sau a unora mai noi.

qiskit[all]~=2.3.0

Această pagină aruncă o privire mai atentă asupra clasei QuantumCircuit din SDK-ul Qiskit, inclusiv câteva metode mai avansate pe care le poți folosi pentru a crea circuite cuantice.

Ce este un circuit cuantic?

Un circuit cuantic simplu este o colecție de qubiți și o listă de instrucțiuni care acționează asupra acelor qubiți. Pentru a demonstra, celula următoare creează un circuit nou cu doi qubiți noi, apoi afișează atributul qubits al circuitului, care este o listă de Qubit în ordine de la bitul cel mai puțin semnificativ q0q_0 până la bitul cel mai semnificativ 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>]

Mai multe obiecte QuantumRegister și ClassicalRegister pot fi combinate pentru a crea un circuit. Fiecare QuantumRegister și ClassicalRegister poate fi, de asemenea, denumit.

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>]

Poți găsi indexul și registrul unui Qubit folosind metoda find_bit a circuitului și atributele sale.

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

Adăugarea unei instrucțiuni la circuit adaugă instrucțiunea la atributul data al circuitului. Rezultatul celulei următoare arată că data este o listă de obiecte CircuitInstruction, fiecare dintre ele având un atribut operation și un atribut 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=())]

Cel mai simplu mod de a vizualiza aceste informații este prin metoda draw, care returnează o vizualizare a unui circuit. Consultă Vizualizează circuite pentru diferite moduri de afișare a circuitelor cuantice.

qc.draw("mpl")

Output of the previous code cell

Obiectele de instrucțiuni ale circuitului pot conține circuite de „definiție" care descriu instrucțiunea în termeni de instrucțiuni mai fundamentale. De exemplu, X-gate este definit ca un caz specific al U3-gate, un gate mai general pentru un singur Qubit.

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

Output of the previous code cell

Instrucțiunile și circuitele sunt similare în sensul că ambele descriu operații pe biți și qubiți, dar au scopuri diferite:

  • Instrucțiunile sunt tratate ca fixe, iar metodele lor vor returna de obicei instrucțiuni noi (fără a muta obiectul original).
  • Circuitele sunt concepute pentru a fi construite pe parcursul multor linii de cod, iar metodele QuantumCircuit modifică adesea obiectul existent.

Ce este adâncimea unui circuit?

Adâncimea (depth()) unui circuit cuantic este o măsură a numărului de „straturi" de gate-uri cuantice, executate în paralel, necesare pentru a finaliza calculul definit de circuit. Deoarece gate-urile cuantice necesită timp pentru a fi implementate, adâncimea unui circuit corespunde aproximativ cu durata de timp necesară computerului cuantic pentru a executa circuitul. Prin urmare, adâncimea unui circuit este o cantitate importantă utilizată pentru a măsura dacă un circuit cuantic poate fi rulat pe un dispozitiv.

Restul acestei pagini ilustrează cum să manipulezi circuitele cuantice.

Construiește circuite

Metode precum QuantumCircuit.h și QuantumCircuit.cx adaugă instrucțiuni specifice circuitelor. Pentru a adăuga instrucțiuni unui circuit în mod mai general, folosește metoda append. Aceasta primește o instrucțiune și o listă de qubiți la care să aplice instrucțiunea. Consultă documentația API a Bibliotecii de Circuit pentru o listă de instrucțiuni acceptate.

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

Pentru a combina două circuite, folosește metoda compose. Aceasta acceptă un alt QuantumCircuit și o listă opțională de mapări de qubiți.

notă

Metoda compose returnează un circuit nou și nu modifică niciunul dintre circuitele asupra cărora acționează. Pentru a modifica circuitul pe care îl apelezi cu compose, folosește argumentul 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

S-ar putea să dorești, de asemenea, să compilezi circuitele în instrucțiuni pentru a-ți menține circuitele organizate. Poți converti un circuit într-o instrucțiune folosind metoda to_instruction, apoi să o adaugi la un alt circuit la fel cum ai face cu orice altă instrucțiune. Circuitul desenat în celula următoare este funcțional echivalent cu circuitul desenat în celula anterioară.

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

Output of the previous code cell

Dacă circuitul tău este unitar, îl poți converti într-un Gate folosind metoda to_gate. Obiectele Gate sunt tipuri specifice de instrucțiuni care au câteva caracteristici suplimentare, cum ar fi metoda control, care adaugă un control cuantic.

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

Output of the previous code cell

Pentru a vedea ce se întâmplă, poți folosi metoda decompose pentru a extinde fiecare instrucțiune în definiția sa.

notă

Metoda decompose returnează un circuit nou și nu modifică circuitul asupra căruia acționează.

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

Output of the previous code cell

Măsoară qubiții

Măsurătorile sunt folosite pentru a eșantiona stările qubiților individuali și a transfera rezultatele într-un registru clasic. Reține că, dacă trimiți circuite către un primitiv Sampler, măsurătorile sunt obligatorii. Cu toate acestea, circuitele trimise către un primitiv Estimator nu trebuie să conțină măsurători.

Qubiții pot fi măsurați folosind trei metode: measure, measure_all și measure_active. Pentru a învăța cum să vizualizezi rezultatele măsurate, consultă pagina Vizualizează rezultatele.

  1. QuantumCircuit.measure : măsoară fiecare Qubit din primul argument pe bitul clasic dat ca al doilea argument. Această metodă permite controlul complet asupra locului unde este stocat rezultatul măsurătorii.

  2. QuantumCircuit.measure_all : nu primește niciun argument și poate fi folosit pentru circuite cuantice fără biți clasici predefiniti. Creează fire clasice și stochează rezultatele măsurătorilor în ordine. De exemplu, măsurătoarea Qubitului qiq_i este stocată în cbitul measimeas_i). Adaugă, de asemenea, o barieră înainte de măsurătoare.

  3. QuantumCircuit.measure_active : similar cu measure_all, dar măsoară doar qubiții care au operații.

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

Circuite parametrizate

Mulți algoritmi cuantici pe termen scurt implică executarea mai multor variații ale unui circuit cuantic. Deoarece construirea și optimizarea circuitelor mari poate fi costisitoare din punct de vedere computațional, Qiskit acceptă circuite parametrizate. Aceste circuite au parametri nedefiniti, iar valorile lor nu trebuie definite decât imediat înainte de executarea circuitului. Aceasta îți permite să muți construirea și optimizarea circuitului în afara buclei principale a programului. Celula următoare creează și afișează un circuit parametrizat.

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

Celula următoare creează mai multe variații ale acestui circuit și afișează una dintre variații.

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

circuits[0].draw("mpl")

Output of the previous code cell

Poți găsi o listă a parametrilor nedefiniti ai unui circuit în atributul său parameters.

qc.parameters
ParameterView([Parameter(angle)])

Schimbă numele unui parametru

În mod implicit, numele parametrilor pentru un circuit parametrizat sunt prefixate cu x - de exemplu, x[0]. Poți schimba numele după ce acestea sunt definite, după cum se arată în exemplul următor.

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)
Ai uitat numele metodei? Încearcă să întrebi Qiskit Code Assistant.

Pașii următori

Recomandări