-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutility_functions.py
212 lines (173 loc) · 8.31 KB
/
utility_functions.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
import os
import numpy as np
from datetime import datetime
import pandas as pd
from qiskit_quantuminspire.qi_provider import QIProvider
def prepare_file(basename: str="", suffix: str="", doraw: int=0):
'''
Creates the file name according to the basename and suffix that you provide.
'''
histname="hist_"+basename
circuitname="circuit_"+basename
rawname="Raw_"+basename
if (len(suffix)>0):
histname+='_'+suffix
circuitname+='_'+suffix
rawname+='_'+suffix
histname+='_API.txt'
circuitname+='_API.pdf'
rawname+="_API"
file=open(histname,'w')
file=open(circuitname,'w')
if (doraw==0):
return histname, circuitname
else:
return histname, circuitname, rawname
def GetTimeStamp():
'''
Returns the timestamp of the current date and time
'''
current_date = datetime.datetime.now()
thisyear=str(current_date.year)
thismonth="0"+str(current_date.month)
thisday="0"+str(current_date.day)
thishour="0"+str(current_date.hour)
thisminute="0"+str(current_date.minute)
thissecond="0"+str(current_date.second)
timestamp=thisyear[-2:]+thismonth[-2:]+thisday[-2:]+"_"+thishour[-2:]+thisminute[-2:]+thissecond[-2:]
return timestamp
def create_new_data_folder(datadir):
'''
Crates the folder with the current date in the specified path.
'''
data_folder_path = datadir + "/Data"
try:
os.makedirs(data_folder_path, exist_ok=False)
except:
print("Data folder already exists")
now = datetime.now()
timestamp = now.strftime("%Y%m%d")
today_path = data_folder_path + f"/{timestamp}"
try:
os.makedirs(today_path, exist_ok=False)
except:
print(f"Folder with timestamp {timestamp} already exists")
os.chdir(today_path) # change the current working directory to the specified path
return today_path
def return_raw_data(qc, result):
bit_register_size = qc.num_clbits
raw_data = result.get_memory()
for entry in range(len(raw_data)):
additional_len = bit_register_size - len(raw_data[entry])
for i in range(additional_len):
raw_data[entry] = '0' + raw_data[entry]
return raw_data
def get_raw_data_counts(qc, result):
raw_data = return_raw_data(qc, result)
raw_data_counts = []
bit_register_size = len(raw_data[0])
measurement_shots = len(raw_data)
for bit_index in range(bit_register_size):
counter_0 = 0
counter_1 = 0
for meas_index in range(measurement_shots):
if raw_data[meas_index][-bit_index-1] == '0':
counter_0 += 1
if raw_data[meas_index][-bit_index-1] == '1':
counter_1 += 1
raw_data_counts.append({'0': counter_0, '1': counter_1})
return raw_data_counts
def get_raw_data_prob(qc, result):
raw_data_counts = get_raw_data_counts(qc, result)
raw_data_prob = []
measurement_shots = raw_data_counts[0]['0'] + raw_data_counts[0]['1']
for entry in range(len(raw_data_counts)):
prob_0 = raw_data_counts[entry]['0'] / measurement_shots
prob_1 = raw_data_counts[entry]['1'] / measurement_shots
raw_data_prob.append({'prob(0)': prob_0, 'prob(1)': prob_1})
return raw_data_prob
def api_run_and_save(param, Qcircuit, histname: str="hist.txt", circuit_name: str="cqasm.txt", shots: int=16384, backend_name: str='Starmon 7', get_results: bool=True, get_hist_data: bool=False, measurement_list: list=[], get_raw_data: bool=False, rawdata_filename: str="rawdata"):
'''
Runs QI with qiskit program and returns histogram and the raw data
A copy of the cqasm program is saved to file circuit_name.
param: a reference number that you are free to choose.
Qcircuit: Qiskit quantum circuit.
histname: file name where you want to save the histogram data.
measurement_list: each entry of the list is equal to the number of measurements done simultaneously in the algorithm.
e.g. measurement_list = [1, 2, 1], it means that the rightmost entry of the classical bit string is the result of a single measurement,
the second and the third entries of the classical bit string are measured together and the last one is measured alone again.
circuit_name: name of the file in which you want to save the quantum circuit.
shots: desired number of shots. For Starmon-5, the max is 16384.
backend_name: specify the name of the backend that you want to use.
get_results: False: do not return the measurement result
True: return the measurement result
get_hist_data: False: do not return the histogram data
True: return the histogram data (if this is True make sure to specify the measurement_list)
measurement_list: each entry of the list is equal to the number of measurements done simultaneously in the algorithm.
e.g. measurement_list = [1, 2, 1], it means that the rightmost entry of the classical bit string is the result of a single measurement,
the second and the third entries of the classical bit string are measured together and the last one is measured alone again.
get_raw_data: False: do not return the raw data
True: return the raw data
rawdata_filename: name of the raw data file you want to save
'''
# Set the backend
provider = QIProvider()
backend = provider.get_backend(name = backend_name)
Qcircuit.draw('mpl', filename = circuit_name)
# Run the job
job = backend.run(Qcircuit, shots = shots, memory = get_raw_data)
results = job.result(timeout = 600) # get the results
# Get and save the histogram data
if get_hist_data:
histogram_data = results.get_counts()
histogram_keys = dict()
for entry_index, entry in enumerate(histogram_data):
additional_len = Qcircuit.num_clbits - len(entry)
for i in range(additional_len):
entry = ('0' + (entry))
histogram_keys[entry_index] = 'd' + entry
data = np.column_stack([list(histogram_keys.values()), list(histogram_data.values())])
process_data_and_save(data, measurement_list, histname)
# Get and save the raw data (if asked)
if get_raw_data:
raw_data = results.get_memory()
for entry in range(len(raw_data)):
additional_len = Qcircuit.num_clbits - len(raw_data[entry])
for i in range(additional_len):
raw_data[entry] = '0' + raw_data[entry]
for nr_shots in range(len(raw_data)):
raw_data[nr_shots] = 'd'+str(raw_data[nr_shots])
df = pd.DataFrame({
"Raw data values": raw_data
})
# Save to a csv file
output_file_rawdata = rawdata_filename+"_"+str(param)+".csv"
df.to_csv(output_file_rawdata, index = False)
if get_results:
return results
def process_data_and_save(data, q, filename):
q_cumsum = np.cumsum(q) # Cumulative sum of q to determine slicing indices
column_dicts = [{} for _ in q] # Create an empty dictionary for each entry in q
for row in data:
bitstring = row[0][1:] # Remove the 'd' at the start
count = int(row[1]) # Count of the bitstring
for i, length in enumerate(q):
if i == 0:
sliced = bitstring[:length] # First slice
else:
sliced = bitstring[q_cumsum[i-1]:q_cumsum[i]] # Subsequent slices
# Populate the dictionary for this column
if sliced in column_dicts[i]:
column_dicts[i][sliced] += count # Increment count if key exists
else:
column_dicts[i][sliced] = count # Initialize key with count
column_dicts_reversed = column_dicts[::-1]
# Write results to a file
with open(filename, 'w') as file:
for i, col_dict in enumerate(column_dicts_reversed):
file.write(f"{i}:")
file.write(r"{")
for key, value in col_dict.items():
file.write(f"'{key}': {value}")
file.write(r"}")
file.write("\n") # Add a blank line between dictionaries