Skip to content

Commit

Permalink
Improvement of BTC01
Browse files Browse the repository at this point in the history
  • Loading branch information
gonfeco committed May 24, 2024
1 parent 1628752 commit 6858c35
Show file tree
Hide file tree
Showing 16 changed files with 2,717 additions and 177 deletions.
35 changes: 28 additions & 7 deletions tests/test_btc_01_pl.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
sys.path.append(l_path)
sys.path.append(l_path+"BTC_01_PL")
from BTC_01_PL.my_benchmark_execution import KERNEL_BENCHMARK as PL_CLASS
from get_qpu import get_qpu
from PL.qpu.select_qpu import select_qpu

def create_folder(folder_name):
"""
Expand Down Expand Up @@ -44,14 +44,35 @@ def create_folder(folder_name):
def test_pl():
kernel_configuration = {
"load_method" : "multiplexor",
"qpu" : "c", #python, qlmass, default
"relative_error": None,
"absolute_error": None
}
name = "PL_{}".format(kernel_configuration["load_method"])
print(os.getcwdb())
kernel_configuration.update({"qpu": get_qpu(kernel_configuration['qpu'])})

# Naive qpu configuration
qpu_conf = {
"qpu_type": "c",
"t_gate_1qb" : None,
"t_gate_2qbs" : None,
"t_readout": None,
"depol_channel" : {
"active": False,
"error_gate_1qb" : None,
"error_gate_2qbs" : None
},
"idle" : {
"amplitude_damping": False,
"dephasing_channel": False,
"t1" : None,
"t2" : None
},
"meas": {
"active":False,
"readout_error": None
}
}

kernel_configuration.update({"qpu": select_qpu(qpu_conf)})
benchmark_arguments = {
#Pre benchmark configuration
"pre_benchmark": True,
Expand All @@ -68,7 +89,7 @@ def test_pl():
"min_meas": 10,
"max_meas": 15,
#List number of qubits tested
"list_of_qbits": [4],
"list_of_qbits": [6],
}

benchmark_arguments.update({"kernel_configuration": kernel_configuration})
Expand All @@ -77,8 +98,8 @@ def test_pl():
ae_bench.exe()
filename = folder + benchmark_arguments["summary_results"]
a = pd.read_csv(filename, header=[0, 1], index_col=[0, 1])
print(100* list(a['KS']['mean'])[0])
assert(100* list(a['KS']['mean'])[0] < 1.0)
assert(list(a['KS']['mean'])[0] < 0.1)
assert(list(a['KL']['mean'])[0] < 0.01)

shutil.rmtree(folder)
test_pl()
5 changes: 3 additions & 2 deletions tnbs/BTC_01_PL/PL/data_loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,10 @@ def get_theoric_probability(n_qbits: int) -> (np.ndarray, np.ndarray, float, flo
data = norma.pdf(x_)
data = data/np.sum(data)
mindata = np.min(data)
shots = min(1000000, max(10000, round(100/mindata)))
#shots = min(1000000, max(10000, round(100/mindata)))
shots = min(1e7, round(100/mindata))
#data = np.sqrt(data)
return x_, data, mean, sigma, float(step), shots, norma
return x_, data, mean, sigma, float(step), int(shots), norma

def get_qlm_probability(data, load_method, shots, qpu):
"""
Expand Down
151 changes: 103 additions & 48 deletions tnbs/BTC_01_PL/PL/load_probabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
"""

import time
import itertools
import numpy as np
import pandas as pd
from scipy.stats import entropy, chisquare, chi2
from scipy.stats import entropy, kstest
from data_loading import get_theoric_probability, get_qlm_probability

class LoadProbabilityDensity:
Expand Down Expand Up @@ -54,19 +55,21 @@ def __init__(self, **kwargs):
#Metric stuff
self.ks = None
self.kl = None
self.chi2 = None
self.fidelity = None
self.pvalue = None
self.pdf = None
self.observed_frecuency = None
self.expected_frecuency = None
self.kl_pdf = None
self.samples = None
self.ks_scipy = None
self.ks_pvalue = None

def get_quantum_pdf(self):
"""
Computing quantum probability density function
"""
self.result, self.circuit, self.quantum_time = get_qlm_probability(
self.data, self.load_method, self.shots, self.qpu)
# For ordering the index using the Int_lsb
self.result.reset_index(inplace=True)

def get_theoric_pdf(self):
"""
Expand All @@ -80,37 +83,42 @@ def get_metrics(self):
Computing Metrics
"""
#Kolmogorov-Smirnov
# Transform from state to x value
self.result["x"] = self.x_[self.result["Int_lsb"]]
# Compute cumulative distribution function of the quantum data
self.result["CDF_quantum"] = self.result["Probability"].cumsum()
# Obtain the cumulative distribution function of the
# theoretical Gaussian distribution
self.result["CDF_theorical"] = self.dist.cdf(self.result["x"])
self.ks = np.abs(
self.result["Probability"].cumsum() - self.data.cumsum()
).max()
self.result["CDF_quantum"] - self.result["CDF_theorical"]).max()

#Kullback-Leibler divergence
epsilon = self.data.min() * 1.0e-5
# Create pandas DF for KL computations
self.kl_pdf = pd.merge(
pd.DataFrame(
[self.x_, self.data], index=["x", "p_th"]
).T,
self.result[["x", "Probability"]],
on=["x"], how="outer"
).fillna(epsilon)
self.kl = entropy(
self.data,
np.maximum(epsilon, self.result["Probability"])
self.kl_pdf["p_th"], self.kl_pdf["Probability"]
)
#Fidelity
self.fidelity = self.result["Probability"] @ self.data / \
(np.linalg.norm(self.result["Probability"]) * \
np.linalg.norm(self.data))

#Chi square
self.observed_frecuency = np.round(
self.result["Probability"] * self.shots, decimals=0)
self.expected_frecuency = np.round(
self.data * self.shots, decimals=0)
try:
self.chi2, self.pvalue = chisquare(
f_obs=self.observed_frecuency,
f_exp=self.expected_frecuency
)
except ValueError:
self.chi2 = np.sum(
(self.observed_frecuency - self.expected_frecuency) **2 / \
self.expected_frecuency

# For testing purpouses
self.samples = list(itertools.chain(
*self.result.apply(
lambda x: [x["x"]] * int(round(
x["Probability"] * self.shots
)),
axis=1
)
count = len(self.observed_frecuency)
self.pvalue = chi2.sf(self.chi2, count -1)
))
ks_scipy = kstest(self.samples, self.dist.cdf)
self.ks_scipy = ks_scipy.statistic
self.ks_pvalue = ks_scipy.pvalue

def exe(self):
"""
Expand Down Expand Up @@ -140,18 +148,15 @@ def summary(self):
self.pdf["shots"] = [self.shots]
self.pdf["KS"] = [self.ks]
self.pdf["KL"] = [self.kl]
self.pdf["fidelity"] = [self.fidelity]
self.pdf["chi2"] = [self.chi2]
self.pdf["p_value"] = [self.pvalue]
self.pdf["elapsed_time"] = [self.elapsed_time]
self.pdf["quantum_time"] = [self.quantum_time]


if __name__ == "__main__":
import argparse
import sys
sys.path.append("../")
from get_qpu import get_qpu
import json
from qpu.benchmark_utils import combination_for_list
from qpu.select_qpu import select_qpu


parser = argparse.ArgumentParser()
Expand All @@ -178,16 +183,66 @@ def summary(self):
default="python",
help="QPU for simulation: See function get_qpu in get_qpu module",
)
parser.add_argument(
"--count",
dest="count",
default=False,
action="store_true",
help="For counting elements on the list",
)
parser.add_argument(
"--print",
dest="print",
default=False,
action="store_true",
help="For printing "
)
parser.add_argument(
"-id",
dest="id",
type=int,
help="For executing only one element of the list",
default=None,
)
parser.add_argument(
"-json_qpu",
dest="json_qpu",
type=str,
default="qpu/qpu.json",
help="JSON with the qpu configuration",
)
parser.add_argument(
"--exe",
dest="execution",
default=False,
action="store_true",
help="For executing program",
)
args = parser.parse_args()
print(args)


configuration = {
"load_method" : args.method,
"number_of_qbits": args.n_qbits,
"qpu": get_qpu(args.qpu)
}
prob_dens = LoadProbabilityDensity(**configuration)
prob_dens.exe()
print(prob_dens.pdf)

with open(args.json_qpu) as json_file:
noisy_cfg = json.load(json_file)
final_list = combination_for_list(noisy_cfg)


if args.count:
print(len(final_list))
if args.print:
if args.id is not None:
configuration = {
"load_method" : args.method,
"number_of_qbits": args.n_qbits,
"qpu": final_list[args.id]
}
print(configuration)
else:
print(final_list)
if args.execution:
if args.id is not None:
configuration = {
"load_method" : args.method,
"number_of_qbits": args.n_qbits,
"qpu": select_qpu(final_list[args.id])
}
prob_dens = LoadProbabilityDensity(**configuration)
prob_dens.exe()
print(prob_dens.pdf)
Loading

0 comments on commit 6858c35

Please sign in to comment.