BELLOP = 'bc3'
import matplotlib.pyplot as plt
import numpy as np
import json, csv
from functools import partial
#%config InlineBackend.figure_formats = ['svg']
import os
EXPORTDIR = 'data_export'
FIGUREDIR = 'figures'
os.makedirs(EXPORTDIR, exist_ok=True)
os.makedirs(FIGUREDIR, exist_ok=True)
def path_fig(filename):
return os.path.join(FIGUREDIR, filename)
SAVEFIG_KWARGS = {'metadata':{'CreationDate':None}}
def path_export(filename):
return os.path.join(EXPORTDIR, filename)
from IPython.display import Markdown as md, display, HTML
import html
import warnings
def report_error(message):
display(md('<b style="font-size:5rem; color:red; line-height:5rem">{}</b>'.format(
html.escape(message)
)))
display(md(f'# Results for {BELLOP.upper()}'))
FIELDS = [BELLOP,'cond_entropy','cond_entropy_bound']
bell_val_bounds = {}
entropies_bounds = {}
with open(path_export(f'witness_bounds_{BELLOP}.tsv'), 'w', newline='') as outfile:
csvwr = csv.writer(outfile, delimiter='\t')
csvwr.writerow(FIELDS)
for bound in range(0, 105, 5):
entropies, bell_val = [], []
bound /= 100
with open(f'out_bell/bound_witnesses_{BELLOP}.{bound:.2f}.jsonl') as f:
last = None
for l in f:
d = json.loads(l)
entropies.append(d['cond_entropy'])
bell_val.append(d[BELLOP])
last = d
if last:
csvwr.writerow((last[BELLOP], last['cond_entropy'], -bound))
bell_val_bounds[-bound] = bell_val
entropies_bounds[-bound] = entropies
fig = plt.figure(figsize=(8,7))
for bound, bell_val in reversed(bell_val_bounds.items()):
plt.plot(bell_val, label=str(bound))
plt.title(f'maximized {BELLOP.upper()}')
plt.xlabel('iterations (witness count)')
plt.ylabel(BELLOP.upper())
plt.grid()
plt.legend()
plt.show(fig)
fig.savefig(path_fig(f'witn_{BELLOP}_val.pdf'), **SAVEFIG_KWARGS)
plt.close(fig)
fig = plt.figure(figsize=(8,7))
for bound, entropies in entropies_bounds.items():
plt.plot(entropies, label=str(bound))
plt.title(f'Entropies for maximized {BELLOP.upper()}')
plt.xlabel('iterations (witness count)')
plt.ylabel('conditional entropy')
plt.grid()
plt.legend()
plt.show(fig)
fig.savefig(path_fig(f'witn_{BELLOP}_entr.pdf'), **SAVEFIG_KWARGS)
plt.close(fig)
def extract_by_keys(data, keys):
return [ data[key] for key in keys ]
def read_data(path, extract_funcs):
rows = []
with open(path, 'r') as f:
for line in f:
try:
row = []
data = json.loads(line)
for func in extract_funcs:
row += (
matrix_to_octave_str(value) if isinstance(value, list) else value
for value in func(data)
)
rows.append(row)
except json.JSONDecodeError as e:
warnings.warn(f"Failed to decode line {len(rows)+1} in {path}: {e!r}")
break
return rows
def fields(bellop):
return [bellop, 'cond_entropy','s_bound']
DATA_PATH_FMT = 'out_bell/{bellop}_seesaw_{bound}_{apx}.jsonl'
EXPECTED_ROWS = 100
incomplete_paths = []
def plot(bound, bellop=BELLOP):
fig, ax = plt.subplots(figsize=(12, 7))
ax.grid(True)
handles = []
stats = {'s_bound': bound}
rowsum = 0
for i, apx in enumerate((+1, -1)):
data_path = DATA_PATH_FMT.format(bound=bound, apx=apx, bellop=bellop)
try:
rows = read_data(data_path,
[partial(extract_by_keys, keys=fields(bellop))])
except FileNotFoundError as e:
warnings.warn(f'{data_path}: {FileNotFoundError!r}')
rows = []
rowsum += len(rows)
if len(rows) != EXPECTED_ROWS:
incomplete_paths.append((data_path, len(rows)))
if len(rows) == 0:
report_error(f"Empty file: {data_path}")
continue
elif len(rows) < EXPECTED_ROWS:
report_error(f"Only {len(rows)} lines read, but expected {EXPECTED_ROWS}: {data_path}")
elif len(rows) > EXPECTED_ROWS:
report_error(f"More lines ({len(rows)}) than expected ({EXPECTED_ROWS}): {data_path}")
bell_vals, cond_entropy, s_bound = zip(*rows)
if not (np.array(s_bound) == bound).all():
print(s_bound, 'should be equal', bound)
stats[f'max_entr_{apx:+}'], stats[f'min_entr_{apx:+}'] = max(cond_entropy), min(cond_entropy)
stats[f'max_{bellop}_{apx:+}'], stats[f'min_{bellop}_{apx:+}'] = max(bell_vals), min(bell_vals)
handles[i:i] = ax.plot(cond_entropy, bell_vals, '.', markersize=4., label=f'{bound} apx={apx}')
lim = plt.ylim()
ax.vlines(bound, -10, 10)
plt.ylim(lim)
ax.legend(handles=handles)
ax.set_ylabel(bellop.upper())
ax.set_xlabel('conditional entropy')
if rowsum != 0:
plt.show(fig)
plt.close(fig)
return stats
records = []
for b in np.linspace(-1,0,21).round(12):
records.append(plot(b))
from pprint import pprint
pprint(incomplete_paths)
if len(incomplete_paths) > 0:
report_error('Incomplete files:')
print(' '.join(path for path, count in incomplete_paths))
import pandas as pd
stats = pd.DataFrame.from_records(records)
pd.set_option("precision", 7)
stats
diffs = stats[["s_bound"]].copy()
for apx in +1, -1:
diffs[f's_max_diff_{apx:+}'] = stats[f'max_entr_{apx:+}'] - stats[f'min_entr_{apx:+}']
diffs[f'{BELLOP}_max_diff_{apx:+}'] = stats[f'max_{BELLOP}_{apx:+}'] - stats[f'min_{BELLOP}_{apx:+}']
def both_apx(fmtstr, bellop=BELLOP):
return [fmtstr.format(apx=+1, bellop=bellop), fmtstr.format(apx=-1, bellop=bellop)]
diffs[f's_max_diff'] = (
stats[both_apx('max_entr_{apx:+}')].max(axis=1)
- stats[both_apx('min_entr_{apx:+}')].min(axis=1)
)
diffs[f'{BELLOP}_max_diff'] = (
stats[both_apx('max_{bellop}_{apx:+}')].max(axis=1)
- stats[both_apx('min_{bellop}_{apx:+}')].min(axis=1)
)
pd.set_option("precision", 5)
diffs
fig, (ax, ax2) = plt.subplots(nrows=2, figsize=(12, 24), dpi=150)
hp1, = ax.plot(stats['s_bound'], stats[f'max_{BELLOP}_+1'], 'x-', label=f'max_{BELLOP}[apx=+1]')
hm1, = ax.plot(stats['s_bound'], stats[f'max_{BELLOP}_-1'], '.-', label=f'max_{BELLOP}[apx=-1]')
ax.legend(handles=[hp1,hm1])
ax.grid(True)
ax2.grid(True)
h3diff, = ax2.plot(diffs['s_bound'], diffs[f'{BELLOP}_max_diff'], '+-b', label=f'max_{BELLOP}_diff')
hdiff, = ax2.plot(stats['s_bound'], stats[f'max_{BELLOP}_-1']-stats[f'max_{BELLOP}_+1'], '.-g', label=f'max_{BELLOP}[apx=-1]-max_{BELLOP}[apx=+1]')
h2diff, = ax2.plot(stats['s_bound'], stats[f'max_{BELLOP}_-1']-stats[f'min_{BELLOP}_+1'], 'x-r', label=f'max_{BELLOP}[apx=-1]-min_{BELLOP}[apx=+1]')
ax2.legend(handles=[hdiff,h2diff, h3diff])
plt.show(fig)
fig.savefig(path_fig(f'seesaw_apx_{BELLOP}.pdf'), **SAVEFIG_KWARGS)
plt.close(fig)
export = stats[['s_bound', f'max_{BELLOP}_-1', f'max_{BELLOP}_+1']].copy()
export[f'max_{BELLOP}_is_-1'] = export[[f'max_{BELLOP}_-1', f'max_{BELLOP}_+1']].max(axis=1) == export[f'max_{BELLOP}_-1']
pd.set_option("precision", 8)
export
export.to_csv(path_export(f'seesaw_max_export_{BELLOP}.tsv'), sep='\t')
witness_bounds = pd.read_csv(path_export(f'witness_bounds_{BELLOP}.tsv'), sep='\t')
FIXEDM_FIELDS = fields(BELLOP)+['apx']
fixedm = read_data(f'out_bell/fixedm_{BELLOP}_entr_approx_states.jsonl', [partial(extract_by_keys, keys=FIXEDM_FIELDS)])
foundm = read_data(f'out_bell/foundm/fixedm_{BELLOP}_entr_approx_states.jsonl', [partial(extract_by_keys, keys=FIXEDM_FIELDS)])
witness_bounds
fixedm = pd.DataFrame.from_records(fixedm, columns=FIXEDM_FIELDS)
fixedm_p1, fixedm_m1 = fixedm[fixedm['apx']==+1], fixedm[fixedm['apx']==-1]
foundm = pd.DataFrame.from_records(foundm, columns=FIXEDM_FIELDS)
foundm_p1, foundm_m1 = foundm[foundm['apx']==+1], foundm[foundm['apx']==-1]
pd.set_option("precision", 10)
fixedm_p1.merge(fixedm_m1, on='s_bound', suffixes=('_p1', '_m1'))
# i z innym df
fixedm_p1.merge(witness_bounds, left_on='s_bound', right_on='cond_entropy_bound', suffixes=('_p1', '_m1'))
fig, ax = plt.subplots(figsize=(12, 12), dpi=150)
hwitn, = ax.plot(witness_bounds['cond_entropy_bound'], witness_bounds[BELLOP], 'r-', marker=5, label=f'max_{BELLOP} with witness (fixed meas.)')
hfp1, = ax.plot(fixedm_p1['s_bound'], fixedm_p1[BELLOP], 'c-', marker=6, label=f'max_{BELLOP} apx=+1 fixed mesurements')
hfm1, = ax.plot(fixedm_m1['s_bound'], fixedm_m1[BELLOP], 'b-', marker=7, label=f'max_{BELLOP} apx=-1 fixed mesurements')
hp1, = ax.plot(stats['s_bound'], stats[f'max_{BELLOP}_+1'], 'x-', label=f'max_{BELLOP}[apx=+1]')
hm1, = ax.plot(stats['s_bound'], stats[f'max_{BELLOP}_-1'], '.-', label=f'max_{BELLOP}[apx=-1]')
fndp1, = ax.plot(foundm_p1['s_bound'], foundm_p1[BELLOP], '|--', label=f'max_{BELLOP} apx=+1 found meas.')
fndm1, = ax.plot(foundm_m1['s_bound'], foundm_m1[BELLOP], '|--', label=f'max_{BELLOP} apx=-1 found meas.')
ax.legend(handles=[hp1,hm1, hwitn, hfp1,hfm1, fndp1, fndm1])
ax.grid(True)
plt.show(fig)
fig.savefig(path_fig(f'compare_{BELLOP}.pdf'), **SAVEFIG_KWARGS)
plt.close(fig)
diffbase = fixedm_p1
def diff(df, key_eq, key_val):
merged = diffbase.merge(df, left_on='s_bound', right_on=key_eq, suffixes=('_base', ''))
return merged['s_bound'], merged[key_val]-merged[f'{BELLOP}_base' if BELLOP in df.columns else BELLOP]
fig, ax = plt.subplots(figsize=(12, 12), dpi=150)
hwitn, = ax.plot(*diff(witness_bounds, 'cond_entropy_bound', BELLOP), 'r-', marker=5, label=f'max_{BELLOP} with witness (fixed meas.)')
hfp1, = ax.plot(*diff(fixedm_p1, 's_bound', BELLOP), 'c-', marker=6, label=f'max_{BELLOP} apx=+1 fixed mesurements')
hfm1, = ax.plot(*diff(fixedm_m1, 's_bound', BELLOP), 'b-', marker=7, label=f'max_{BELLOP} apx=-1 fixed mesurements')
hp1, = ax.plot(*diff(stats, 's_bound', f'max_{BELLOP}_+1'), 'x-', label=f'max_{BELLOP}[apx=+1]')
hm1, = ax.plot(*diff(stats, 's_bound', f'max_{BELLOP}_-1'), '.-', label=f'max_{BELLOP}[apx=-1]')
from matplotlib.ticker import SymmetricalLogLocator
plt.yscale('symlog', linthresh=1e-4)
ax.yaxis.set_minor_locator(SymmetricalLogLocator(linthresh=1e-4, base=10, subs=range(2,10)))
ax.tick_params(which='minor', length=4)
ax.legend(handles=[hp1,hm1, hwitn, hfp1,hfm1])
ax.grid(True)
plt.title(f'Value minus corresponding value of [max_{BELLOP} apx=-1 fixed mesurements]')
plt.show(fig)
fig.savefig(path_fig(f'diff_fixedm_p1_{BELLOP}.pdf'), **SAVEFIG_KWARGS)
plt.close(fig)
# Seesaw difference to fixedm_p1
s_bound, seesaw_p1_diff = diff(stats, 's_bound', f'max_{BELLOP}_+1')
s_bound2, seesaw_m1_diff = diff(stats, 's_bound', f'max_{BELLOP}_-1')
pd.DataFrame({'s_bound':s_bound, 'seesaw_p1_diff':seesaw_p1_diff, 'seesaw_m1_diff':seesaw_m1_diff, 's_bound2':s_bound2})