from qiskit import (QuantumCircuit, QuantumRegister, ClassicalRegister,
execute, Aer, __qiskit_version__)from qiskit.visualization import plot_bloch_multivector
import matplotlib as mpl
import matplotlib.pyplot as plt
import warnings
'ignore') warnings.filterwarnings(
Bramki wielokubitowe
def obwod(strategia):
= QuantumCircuit(QuantumRegister(1, name='qGra'))
qc for bramka in strategia:
if bramka == 'I':
id(0)
qc.elif bramka == 'H':
0)
qc.h(elif bramka == 'X':
0)
qc.x(return qc
%matplotlib inline
def animacja(strategia):
= QuantumCircuit(QuantumRegister(1, name="q0"))
qc = Aer.get_backend('statevector_simulator')
symulator = execute(qc, backend=symulator).result()
wynik = wynik.get_statevector()
stan
display(stan)print("stan poczatkowy:")
display(plot_bloch_multivector(stan))
plt.show()for it, bramka in enumerate(strategia):
if bramka == 'I':
id(0)
qc.elif bramka == 'H':
0)
qc.h(elif bramka == 'X':
0)
qc.x(= execute(qc, backend=symulator).result()
wynik = wynik.get_statevector()
stan print("stan po bramce", bramka)
display(plot_bloch_multivector(stan)) plt.show()
= 'XXX'
strategia 'mpl'))
display(obwod(strategia).draw( animacja(strategia)
Statevector([1.+0.j, 0.+0.j],
dims=(2,))
stan poczatkowy:
stan po bramce X
stan po bramce X
stan po bramce X
def sedzia(obwod):
= QuantumRegister(1)
qr = ClassicalRegister(1)
cr = QuantumCircuit(qr, cr)
ob
ob.append(obwod, qr)0, 0)
ob.measure(return execute(ob, backend=Aer.get_backend('qasm_simulator'), shots=1000).result()
= 'XXX'
strategia = sedzia(obwod(strategia)).get_counts()
stats print(stats)
{'1': 1000}
= 'HXH'
strategia = sedzia(obwod(strategia)).get_counts()
stats print(stats)
{'0': 1000}
def klasycze_strategie():
= []
wyniki for ruch_1 in ['I','X']:
for ruch_2 in ['I','X']:
for ruch_3 in ['I','X']:
= ruch_1 + ruch_2 + ruch_3
strategia print("strategia",strategia)
= obwod(strategia)
ob 'mpl'))
display(ob.draw(
plt.show()= sedzia(ob).get_counts()
stats print("statystyka", stats)
wyniki.append((strategia, stats))
klasycze_strategie()
strategia III
statystyka {'0': 1000}
strategia IIX
statystyka {'1': 1000}
strategia IXI
statystyka {'1': 1000}
strategia IXX
statystyka {'0': 1000}
strategia XII
statystyka {'1': 1000}
strategia XIX
statystyka {'0': 1000}
strategia XXI
statystyka {'0': 1000}
strategia XXX
statystyka {'1': 1000}
def kwantowe_strategie():
= []
wyniki for ruch_1 in ['H']:
for ruch_2 in ['I','X']:
for ruch_3 in ['H']:
= ruch_1 + ruch_2 + ruch_3
strategia print("strategia",strategia)
= obwod(strategia)
ob 'mpl'))
display(ob.draw(
plt.show()= sedzia(ob).get_counts()
stats print("statystyka", stats)
wyniki.append((strategia, stats))
kwantowe_strategie()
strategia HIH
statystyka {'0': 1000}
strategia HXH
statystyka {'0': 1000}
Proste obwody kwantowe
Barriers
- służą do oddzielenia logicznych części obwodu. Nie mają wpływu na działanie obwodu, ale mogą pomóc w jego czytelności.
from qiskit import QuantumCircuit
= QuantumCircuit(2,4)
qc 0)
qc.h(1,0],[2,3])
qc.measure(['mpl') qc.draw(
from qiskit import QuantumCircuit
= QuantumCircuit(2,4)
qc 0)
qc.h(
qc.barrier()1,0],[2,3])
qc.measure(['mpl') qc.draw(
Losowy bajt
# generator liczb losowych
from random import randrange
''.join([str(randrange(2)) for i in range(8)])
'00011001'
# mozna takze zrealizowac jako rzut monetą
import random
for n in range(5):
if random.random()<0.5: #if the random number is less than 0.5 print heads
print('HEADS')
else:
print('TAILS')
HEADS
TAILS
TAILS
HEADS
TAILS
# LOSOWY BAJT
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, execute, Aer
= QuantumRegister(8)
q = ClassicalRegister(8)
c
= QuantumCircuit(q,c)
qc # tutaj kod losowania
for i in range(8):
if randrange(2) == 0:
qc.x(q[i])
qc.barrier()
qc.measure(q,c)'mpl') qc.draw(
= execute(qc, Aer.get_backend('qasm_simulator'), shots=10)
job = job.result().get_counts() counts
counts
{'00100100': 10}
print(list(counts)[0], "wynosi: ", int(list(counts)[0],2))
00100100 wynosi: 36
# losowy kwantowo bajt
# LOSOWY BAJT
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, execute, Aer
= QuantumRegister(8)
q = ClassicalRegister(8)
c
= QuantumCircuit(q,c)
qc # tutaj kod losowania
qc.h(q)
qc.barrier()
qc.measure(q,c)'mpl'))
display(qc.draw(= execute(qc, Aer.get_backend('qasm_simulator'), shots=10)
job = job.result().get_counts()
counts counts
{'01000110': 1,
'00001001': 1,
'00100100': 1,
'11000000': 1,
'01000011': 1,
'11010001': 1,
'11100110': 1,
'11100100': 1,
'10101011': 1,
'11001100': 1}
for el in counts:
print(int(el,2))
70
9
36
192
67
209
230
228
171
204
# losowanie z zakresu liczb 0-15
= 4
n = QuantumRegister(n)
q = ClassicalRegister(n)
c = QuantumCircuit(q, c)
circuit
for j in range(n):
circuit.h(q[j])
circuit.measure(q,c)
= execute(circuit, Aer.get_backend('qasm_simulator'), shots=1000)
job
# get the histogram of bit string results, convert it to one of integers and plot it
= job.result().get_counts()
bit_counts = {}
int_counts for bitstring in bit_counts:
int(bitstring,2) ] = bit_counts[bitstring]
int_counts[
from qiskit.tools.visualization import plot_histogram
plot_histogram(int_counts)
SWAP GATE
\[ \text{SWAP}\ket{01} = \ket{10} \]
= QuantumCircuit(2)
qc 0)
qc.x(0,1)
qc.swap(
qc.measure_all()'mpl') qc.draw(
= execute(qc, Aer.get_backend('qasm_simulator'), shots=1).result()
counts counts.get_counts()
Stany splątane
= QuantumRegister(2)
qr = QuantumCircuit(qr)
qc 0])
qc.h(qr[0,1)
qc.cx(= Aer.get_backend('statevector_simulator')
backend = execute(qc, backend)
job = job.result()
result = result.get_statevector() state
'mpl'))
display(qc.draw('latex') state.draw(
\[\frac{\sqrt{2}}{2} |00\rangle+\frac{\sqrt{2}}{2} |11\rangle\]
= QuantumRegister(2)
qr = QuantumCircuit(qr)
qc 0])
qc.h(qr[0,1)
qc.cx(1)
qc.x(= Aer.get_backend('statevector_simulator')
backend = execute(qc, backend)
job = job.result()
result = result.get_statevector()
state 'mpl'))
display(qc.draw('latex') state.draw(
\[\frac{\sqrt{2}}{2} |01\rangle+\frac{\sqrt{2}}{2} |10\rangle\]
= QuantumRegister(2)
qr = QuantumCircuit(qr)
qc 0])
qc.h(qr[0,1)
qc.cx(1)
qc.z(= Aer.get_backend('statevector_simulator')
backend = execute(qc, backend)
job = job.result()
result = result.get_statevector()
state 'mpl'))
display(qc.draw('latex') state.draw(
\[\frac{\sqrt{2}}{2} |00\rangle- \frac{\sqrt{2}}{2} |11\rangle\]
= QuantumRegister(2)
qr = QuantumCircuit(qr)
qc 0])
qc.h(qr[0,1)
qc.cx(1)
qc.x(1)
qc.z(= Aer.get_backend('statevector_simulator')
backend = execute(qc, backend)
job = job.result()
result = result.get_statevector()
state 'mpl'))
display(qc.draw('latex') state.draw(
\[\frac{\sqrt{2}}{2} |01\rangle- \frac{\sqrt{2}}{2} |10\rangle\]
Half adder cirquit
Napisz operator 1+1 na układzie 4 kubitów
\[ 0+0 = 00 \] \[ 0+1 = 01 \] \[ 1+0 = 01 \] \[ 1+1 = 10 \]
zauwaz, ze mamy dwa typy rozwiązań:
- dwa bity wejsciowe są takie same (00, 11) i dają na prawym bicie odpowiedzi 0.
- dwa bity wejsciowe są rózne (10,01) i dają na prawym bicie odpowiedzi 1.
Aby napisać prawidłowe rozwiązanie musimy stworzyć bramki, które będą rozpoznawać czy dwa kubity są takie same czy tez rózne. Dla przypomnienia - klasycznie rolę taką pełni bramka XOR
.
Input 1 | Input 2 | XOR |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 1 | 1 |
1 | 0 | 0 |
Podobnie działa bramka CNOT
= QuantumCircuit(2)
qc 0,1)
qc.cx(='mpl') qc.draw(output
= QuantumCircuit(4,2)
qc # zakodowanie danych wejściowych do kubitu 1 i 2
0)
qc.x(1) # bo chcemy policzyc 1+1
qc.x(# uzyjemy CNOT - bramka XOR dla porownania kubitow 1 i 2
0,2)
qc.cx(1,2)
qc.cx(2,0) # wydobycie wyniku XOR
qc.measure(3,1) # wydobycie wyniku AND
qc.measure(='mpl') qc.draw(output
Zastosowanie dwóch CNOT do inputów rozwiązuje nam problem prawego bitu odpowiedzi.
Co z pierszym bitem odpowiedzi otrzymywanym po pomiarzze q3
?
- jego wartość dla pierwszych trzech równań zawsze wynosi 0.
Jednak dla równania 1+1 powinniśmy otrzymać 1.
Do rozwiązania tego problemu mozna wykorzystać bramkę operującą na 3 kubitach. Bramka ta to bramka Toffoli
.
= QuantumCircuit(4,2)
qc # zakodowanie danych wejściowych do kubitu 1 i 2
0)
qc.x(1) # bo chcemy policzyc 1+1
qc.x(# uzyjemy CNOT
0,2)
qc.cx(1,2)
qc.cx(0,1,3) # AND
qc.ccx(2,0) # wydobycie wyniku XOR
qc.measure(3,1) # wydobycie wyniku AND
qc.measure(='mpl') qc.draw(output
from qiskit.visualization import plot_histogram
= execute(qc,Aer.get_backend('qasm_simulator'),shots=1).result().get_counts()
counts plot_histogram(counts)
Dla przypomnienia:
print("wynik 1+1 =",int('10',2))
wynik 1+1 = 2
sprawdźmy wszystkie mozliwe wyniki
for input in ['00','01','10','11']:
= QuantumCircuit(4,2)
mycircuit1
#Initialization - Note qiskit order
if input[0] == '1':
1)
mycircuit1.x(if input[1] == '1':
0)
mycircuit1.x(
0,2)
mycircuit1.cx(1,2)
mycircuit1.cx(0,1,3)
mycircuit1.ccx(
2,0)
mycircuit1.measure(3,1)
mycircuit1.measure(
= execute(mycircuit1,Aer.get_backend('qasm_simulator'),shots=1)
job = job.result().get_counts(mycircuit1)
counts print("Input:", input, "Output:", counts)
Input: 00 Output: {'00': 1}
Input: 01 Output: {'01': 1}
Input: 10 Output: {'01': 1}
Input: 11 Output: {'10': 1}
Zadanie - czy potrafisz utworzyć 3 kubitową wersję bramki
OR