app: stacked_cores: 52-xx: add some facilities for plotting 52-xx or gate runs
it's primitive; not the *best* results
This commit is contained in:
parent
ff68e57fa5
commit
286a267f75
|
@ -46,6 +46,16 @@ class ParameterizedMeas:
|
|||
def add_meas(self, params: tuple, meas_rows: list):
|
||||
self.meas[tuple(params)] = meas_rows
|
||||
|
||||
def all_rows(self) -> list:
|
||||
# this is just `sum(self.meas.values())` but python is a idiot
|
||||
rows = []
|
||||
for mrows in self.meas.values():
|
||||
rows.extend(mrows)
|
||||
return rows
|
||||
|
||||
def runs(self) -> list:
|
||||
return self.meas.values()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
meas_entries = "\n".join(
|
||||
f" {format_float_tuple(k)}: {indented(format_list(v))}," for (k, v) in sorted(self.meas.items())
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from math import sqrt
|
||||
|
||||
import plotly.express as px
|
||||
from pandas import DataFrame
|
||||
|
||||
from stacked_cores_52xx import *
|
||||
|
||||
def plot(name: str, x_name: str, y_series: list):
|
||||
df = DataFrame(data={ x_name: sweep_1d(len(y_series)), "y": y_series })
|
||||
fig = px.line(df, x=x_name, y="y", title=name)
|
||||
fig.show()
|
||||
|
||||
def eval_series(meas: 'ParameterizedMeas', points: list, y_idx: int = -1):
|
||||
return [sample_all(meas, *p)[y_idx] for p in points]
|
||||
|
||||
def sample_all(meas: 'ParameterizedMeas', a0: float, a1: float) -> tuple:
|
||||
runs = [extract_transfer_from_meas_rows(r) for r in meas.runs()]
|
||||
distances = [(distance_to(m, (a0, a1)), m) for m in runs]
|
||||
|
||||
return weighted_sum_of_neighbors_by_inv_distance(distances)
|
||||
|
||||
def extract_transfer_from_meas_rows(meas_rows: list) -> tuple:
|
||||
return (meas_rows[0].m[0], meas_rows[0].m[1], meas_rows[1].m[2], meas_rows[2].m[3])
|
||||
|
||||
def interpolate(meas: 'ParameterizedMeas', a0: float, a1: float) -> tuple:
|
||||
"""
|
||||
this interpolates a point among four neighboring points in 2d.
|
||||
the implementation only supports 2d, but the technique is extendable to N dim.
|
||||
"""
|
||||
rows = [r.m for r in meas.all_rows()]
|
||||
distances = [(distance_to(m, (a0, a1)), m) for m in rows]
|
||||
# a0_below_dist, a0_below_val = min(d for d in distances if d[1][0] <= a0)
|
||||
# a0_above_dist, a0_above_val = min(d for d in distances if d[1][0] >= a0)
|
||||
# a1_below_dist, a1_below_val = min(d for d in distances if d[1][1] <= a1)
|
||||
# a1_above_dist, a1_above_val = min(d for d in distances if d[1][1] >= a1)
|
||||
a0_below = min((d for d in distances if d[1][0] <= a0), default=None)
|
||||
a0_above = min((d for d in distances if d[1][0] >= a0), default=None)
|
||||
a1_below = min((d for d in distances if d[1][1] <= a1), default=None)
|
||||
a1_above = min((d for d in distances if d[1][1] >= a1), default=None)
|
||||
|
||||
neighbors = [a for a in [a0_below, a0_above, a1_below, a1_above] if a is not None]
|
||||
return weighted_sum_of_neighbors_by_inv_distance(neighbors)
|
||||
|
||||
def weighted_sum_of_neighbors_by_inv_distance(neighbors: list) -> tuple:
|
||||
"""
|
||||
each neighbor is (distance, value).
|
||||
return a weighted sum of these neighbors, where lower-distance neighbors are more strongly weighted.
|
||||
"""
|
||||
D = sum(a[0] for a in neighbors)
|
||||
weight_n = lambda n: 1/max(n[0], 1e-3) # non-normalized weight for neighbor
|
||||
W = sum(weight_n(n) for n in neighbors)
|
||||
weighted_n = lambda n: weighted(n[1], weight_n(n)/W) # normalized weighted contribution for neighbor
|
||||
return element_sum([weighted_n(n) for n in neighbors])
|
||||
|
||||
def weighted_sum_of_neighbors(neighbors: list) -> tuple:
|
||||
"""
|
||||
each neighbor is (distance, value).
|
||||
return a weighted sum of these neighbors, where lower-distance neighbors are more strongly weighted.
|
||||
"""
|
||||
D = sum(a[0] for a in neighbors)
|
||||
weight_n = lambda n: D - n[0] # non-normalized weight for neighbor
|
||||
W = sum(weight_n(n) for n in neighbors)
|
||||
weighted_n = lambda n: weighted(n[1], weight_n(n)/W) # normalized weighted contribution for neighbor
|
||||
return element_sum([weighted_n(n) for n in neighbors])
|
||||
|
||||
def distance_to(p0: tuple, p1: tuple) -> float:
|
||||
return sqrt(sum((x0-x1)*(x0-x1) for (x0, x1) in zip(p0, p1)))
|
||||
|
||||
def element_sum(lists: list) -> list:
|
||||
elems = lists[0]
|
||||
for l in lists[1:]:
|
||||
for i, e in enumerate(l):
|
||||
elems[i] += e
|
||||
return elems
|
||||
|
||||
def weighted(l: list, scale: float) -> list:
|
||||
return [e*scale for e in l]
|
||||
|
||||
|
||||
or_gates = DB
|
||||
|
||||
sweep_1d = lambda points=101: [unit_to_m(x/(points-1)) for x in range(points)]
|
||||
sweep_a0 = lambda a1, points=101: [(unit_to_m(x/(points-1)), a1) for x in range(points)]
|
||||
sweep_a1 = lambda a0, points=101: [(a0, unit_to_m(x/(points-1))) for x in range(points)]
|
||||
|
||||
unit_to_m = lambda u: -17000 + 34000 * u
|
||||
|
||||
for name, meas in sorted(or_gates.items()):
|
||||
trace = eval_series(meas, sweep_a1(-17000))
|
||||
plot(f"{name}", "a1", trace)
|
Loading…
Reference in New Issue