-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqiskit_utils.py
151 lines (115 loc) · 6.07 KB
/
qiskit_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
## imports
from qiskit import *
from qiskit.algorithms import *
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
from qiskit import quantum_info, IBMQ, Aer
from qiskit import BasicAer
from qiskit.utils import QuantumInstance
# backend = BasicAer.get_backend("statevector_simulator")
# quantum_instance = QuantumInstance(backend)
from qiskit.algorithms import AmplitudeEstimation
from qiskit.circuit.library import RYGate ,SwapGate, CSwapGate
#from qiskit.ignis.verification.tomography import state_tomography_circuits, StateTomographyFitter
from qiskit.visualization import plot_histogram, plot_state_qsphere, plot_bloch_multivector, plot_bloch_vector
import numpy as np
from numpy import pi
import seaborn as sns
from IPython.display import Image
import matplotlib.pyplot as plt
from typing import Optional, Union, Iterable
# provider = IBMQ.load_account()
# IBMQ.get_provider(hub='ibm-q-education', group='iit-madras-1', project='quantum-computin')
# # setup required backends
# lima = provider.get_backend('ibmq_lima')
# manila = provider.get_backend('ibmq_manila')
qsm = Aer.get_backend('qasm_simulator')
stv = Aer.get_backend('statevector_simulator')
aer = Aer.get_backend('aer_simulator')
##################################################################################################
## helper functions ##
##################################################################################################
def bit_conditional( num: int, qc: QuantumCircuit, cntrl: QuantumRegister): ## @helper_function
""" helper function to assist the conditioning of ancillas
ARGS:
----
num : the integer to be conditioned upon
qc : QuantumCircuit of the original circuit
register : QuantumRegister corresponding to the control_ancilla which is conditioned upon
RETURNS:
-------
Works inplace i.e modifies the original circuit 'qc' that was passed """
n = len(cntrl)
bin_str = format(num, "b").zfill(n)
assert len(bin_str) == len(cntrl) ## need to assurethe bit ordering covention according tto qiskit's
bin_str = bin_str[::-1] ## reverse the bit string
for index, bit in enumerate(bin_str):
if bit== '0': qc.x(cntrl[index])
def measure_and_plot(qc: QuantumCircuit, shots:int= 1024, show_counts:bool= False, return_counts:bool= False, measure_cntrls: bool = False, decimal_count_keys:bool = True , cntrl_specifier:Union[int, list, str] = 'all'):
""" Measure and plot the state of the data registers, optionally measure the control ancillas, without modifying the original circuit.
ARGS:
----
qc : 'QuantumCircuit'
the circuit to be measured
shots: 'int'
no. of shots for the measurement
show_counts : 'bool'
print the counts dictionary
measure_cntrls : 'bool'
indicates whether to measure the control ancilla registers.
return_counts : 'bool'
returns the counts obtained if True, else retruns the histogram plot
measure_cntrls: 'bool'
indicates whether to measure the controll ancill qubits
decimal_count_keys: 'bool'
if 'True' converts the binary state of the controll ancilllas to integer represntation
cntrl_specifier : 'int'
inidicates whihch of the control registers to meausure,
for eg. cntrl_specifier= 2 refers to the first control ancilla cntrl_2
cntrl_specifier= 'all' refers to all the ancillas
RETURNS:
-------
plots histogram over the computational basis states
"""
qc_m = qc.copy()
creg = ClassicalRegister( len(qc_m.qregs[0]) )
qc_m.add_register(creg)
qc_m.measure(qc_m.qregs[0], creg)
if measure_cntrls== True:
if isinstance(cntrl_specifier, int):
print('int')##cflag
if cntrl_specifier > len(qc_m.qregs) or cntrl_specifier < 1: raise ValueError(" 'cntrl_specifier' should be less than no. of control registers and greater than 0")
creg_cntrl = ClassicalRegister(len(qc_m.qregs[cntrl_specifier-1]))
qc_m.add_register(creg_cntrl)
qc_m.measure(qc_m.qregs[cntrl_specifier-1], creg_cntrl )
elif isinstance(cntrl_specifier, list ):
print('list')##cflag
for ancilla in cntrl_specifier:
if ancilla > len(qc_m.qregs) or ancilla < 1: raise ValueError(" 'ancilla' should be less than no. of control registers and greater than 0")
creg_cntrl = ClassicalRegister(len(qc_m.qregs[ancilla-1]))
qc_m.add_register(creg_cntrl)
qc_m.measure(qc_m.qregs[ancilla-1], creg_cntrl )
elif isinstance(cntrl_specifier, str) and cntrl_specifier== "all":
print('str')##cflag
for reg in qc_m.qregs[1:] :
creg = ClassicalRegister(len(reg))
qc_m.add_register(creg)
qc_m.measure(reg, creg)
# plt.figure()
counts = execute(qc_m, qsm, shots= shots).result().get_counts()
if decimal_count_keys:
counts_m = {}
for key in counts.keys():
split_key = key.split(' ')
if measure_cntrls:
key_m = 'key: '
for string in split_key[:-1]:
key_m+= str(int(string, 2)) + ' '
key_m += '-> '
else: key_m = ''
key_m += split_key[-1][::-1] ##to-check
counts_m[key_m] = counts[key]
counts = counts_m
if show_counts== True: print(counts)
if return_counts: return counts
else: return plot_histogram(counts)
####################################################################################################