def _benchmark(): """generate different problem instances and solve them using the Gurobi backend""" yield 'n', 'd', 'method', 'duration', 'error', 'avg_n', 'avg_e', 'avg_d', 'avg_v' ns = [2**e for e in range(3, 9)] ds = [4, 6] fs = [rgraph_normal, rgraph_scale_free] rs = list(range(3)) logging.info(f'{ns} x {ds} x {fs} x {rs}') configurations = list(product(ns, ds, fs, rs)) logging.info(f'run benchmark for {len(configurations)} examples') for n, d, factory, _ in tqdm(reversed(configurations)): # ensure that for each configuration one simulation succeeds while True: try: # generate example # ensure that at least 85% of the nodes remain in the example and the mapping is non trivial while True: lts_1, lts_2, ref_mapping = generate_example(factory, n, d) if all( map(lambda l: len(l.states) >= .85 * n, (lts_1, lts_2))) and 0 < len(ref_mapping) < 26: break # prepare simulator similarities = BetaDistributedSimilarity(1., 12., LABELS_LC, LABELS_UC, ref_mapping, threshold=.3) simulator = LPSimulator(similarities, gap_penalty=.25, backend='GUROBI_CMD') # compute and assess mapping duration, mapping = timeit( lambda: trace(lts_1, lts_2, simulator)) error = len( set.symmetric_difference(ref_mapping, mapping)) / max( len(ref_mapping), len(mapping)) # LTS stats deg_1 = lts_degrees(lts_1) deg_2 = lts_degrees(lts_2) avg_n = (len(lts_1.states) + len(lts_2.states)) / 2 avg_e = (len(lts_1.transitions) + len(lts_2.transitions)) / 2 avg_d = (sum(deg_1) + sum(deg_2)) / (len(deg_1) + len(deg_2)) avg_v = (variance(deg_1) + variance(deg_2)) / 2 yield n, d, factory.__name__, duration, error, avg_n, avg_e, avg_d, avg_v break except Exception as error: logging.debug(f'{type(error)}: {error}')
def examples_original(): """examples (labels changed) from original paper""" logging.getLogger().setLevel(logging.INFO) simulator = LPSimulator(SIMILARITIES_1, .25) examples = [ (LTS_P, LTS_Q), # example from fig 3 (LTS_P, LTS_S), # example from fig 4 ] for i, (lts_1, lts_2) in enumerate(examples, start=1): m_1 = trace(lts_1, lts_2, simulator) m_2 = trace(lts_2, lts_1, simulator) logging.info(f'm_1 = {m_1}') logging.info(f'm_2 = {m_2}') logging.info(f'm_1 U m_2 = {merge(m_1, m_2)}')
def take_measurement( n_grid: np.int, n_rays: np.int, r_theta: np.float64 ) -> (np.ndarray, np.ndarray, np.ndarray, np.ndarray): """ Take a measurement with the tomograph from direction r_theta. Arguments: n_grid: number of cells of grid in each direction n_rays: number of parallel rays r_theta: direction of rays (in radians) Return: intensities: measured intensities for all <n_rays> rays of the measurement. intensities[n] contains the intensity for the n-th ray ray_indices: indices of rays that intersect a cell isect_indices: indices of intersected cells lengths: lengths of segments in intersected cells The tuple (ray_indices[n], isect_indices[n], lengths[n]) stores which ray has intersected which cell with which length. n runs from 0 to the amount of ray/cell intersections (-1) of this measurement. Raised Exceptions: - Side Effects: - """ # compute ray direction in Cartesian coordinates cs = np.cos(r_theta) sn = np.sin(r_theta) r_dir = np.array([-cs, -sn]) # compute start positions for rays r_pos = np.zeros((n_rays, 2)) for i, g in enumerate(np.linspace(-0.99, 0.99, n_rays)): r_pos[i] = np.array([cs - sn * g, sn + cs * g]) else: r_pos[0] = np.array([cs, sn]) # compute measures intensities for each ray intensities = np.zeros(n_rays) for i, rs in enumerate(r_pos): intensities[i] = trace(rs, r_dir) # take exponential fall off into account intensities = np.log(1.0 / intensities) # compute traversal distance in each grid cell ray_indices, isect_indices, lengths = grid_intersect(n_grid, r_pos, r_dir) return intensities, ray_indices, isect_indices, lengths
def _simulate(alpha, beta, gap_penalty=.25): similarities = BetaDistributedSimilarity(alpha, beta, LTS_P.labels, LTS_Q.labels, REFERENCE_MAPPING, .3) s_def = LPSimulator(similarities, gap_penalty) s_min = LPSimulator(similarities, gap_penalty, strategy=min) s_max = LPSimulator(similarities, gap_penalty, strategy=max) s_avg = LPSimulator(similarities, gap_penalty, strategy=s_average) m_pq = trace(LTS_P, LTS_Q, s_def) m_qp = trace(LTS_Q, LTS_P, s_def) return [ greedy_mapper(similarities, .3), m_pq, {(b, a) for a, b in m_qp}, merge(m_pq, m_qp, resolution=cr_prune), merge(m_pq, m_qp, resolution=cr_ignore), merge(m_pq, m_qp, strict=True, resolution=cr_prune), merge(m_pq, m_qp, strict=True, resolution=cr_ignore), trace(LTS_P, LTS_Q, s_min, bisimulation=True), trace(LTS_P, LTS_Q, s_max, bisimulation=True), trace(LTS_P, LTS_Q, s_avg, bisimulation=True), ]
def examples_paper(): """examples used for seminar paper""" logging.getLogger().setLevel(logging.INFO) configurations = [ ('I_J_L2', LTS_I, LTS_J, SIMILARITIES_2, .25), ('Q_P_L3', LTS_Q, LTS_P, SIMILARITIES_3, .25), ('O_U_L1', LTS_O, LTS_U, SIMILARITIES_1, .25), ('P_Q_L1', LTS_P, LTS_Q, SIMILARITIES_1, .25), ('Q_P_L1', LTS_Q, LTS_P, SIMILARITIES_1, .25), ('P_S_L1', LTS_P, LTS_S, SIMILARITIES_1, .25), ('S_P_L1', LTS_S, LTS_P, SIMILARITIES_1, .25), ('P_Q_L3', LTS_P, LTS_Q, SIMILARITIES_3, .25), ('Y_X_L1', LTS_Y, LTS_X, SIMILARITIES_1, .25), ('Z_X_L1', LTS_Z, LTS_X, SIMILARITIES_1, .25), ] for name, lts_1, lts_2, similarities, gap_penalty in configurations: out_dir = WORKING_DIRECTORY.joinpath(f'example_{name}') render = partial(Digraph.render, directory=out_dir, format='pdf', cleanup=True) out_dir.mkdir(exist_ok=True) simulator = LPSimulator(similarities, gap_penalty, lp_path=out_dir.joinpath('simulation.lp')) simulation = simulator.simulate(lts_1, lts_2) mapping, record = trace(lts_1, lts_2, simulator, record=True) logging.info(f'mapping {mapping}') # store setup with out_dir.joinpath('setup.txt').open(mode='wt') as f: print(f'Example: {name}\n', file=f) print(f'LTS_1: {repr(lts_1)}', file=f) print(f'LTS_2: {repr(lts_2)}', file=f) print(f'Simulator: {repr(simulator)}\n', file=f) print(f'L{repr(similarities)[1:]}\n', file=f) print(f'Q{repr(simulation)[1:]}\n', file=f) print(f'M = {mapping}', file=f) # render similarities with out_dir.joinpath('similarities.tex').open(mode='wt') as f: print('\\caption{Label Similarities $L$}', file=f) f.write(similarities.fmt(tablefmt='latex', numalign='decimal', floatfmt='.1f')) # render simulation with out_dir.joinpath('simulation.tex').open(mode='wt') as f: print(f'\\caption{{Simulation $Q$ of $LTS_{lts_1.name}$ by $LTS_{lts_2.name}$, p={gap_penalty}}}', file=f) f.write(simulation.fmt(tablefmt='latex', numalign='decimal', floatfmt='.4f')) # render call graph dot = Digraph(engine='dot') dot.attr(dpi='300') dot.attr('node', shape='box', style='filled', fillcolor='grey90') record.dot(dot) render(dot, 'callgraph') record.tex(out_dir) with out_dir.joinpath('caption_callgraph.tex').open(mode='wt') as f: print( f'\\caption{{Callgraph of ${{\\textsc{{Trace}}}}\\left(' f'{lts_1.initial_state}, {lts_2.initial_state}' f'\\right)$}}', file=f) # render mapping edge_kwargs = {} for color, eq_class in zip(cycle(PALETTE), equivalence_classes(mapping)): for label in eq_class: edge_kwargs[label] = {'color': color, 'penwidth': '2'} dot = Digraph(engine='dot') dot.attr(compound='true', dpi='150') dot.attr('node', shape='circle', style='filled', fillcolor='grey70') dot.attr('edge', arrowhead='normal') # invisible dummy cluster with dot.subgraph(name='cluster_global') as gc: gc.attr(style='invis') gc.node('global_void', label='', style='invis') for i, lts in enumerate((lts_1, lts_2), start=1): with dot.subgraph(name=f'cluster_lts_{i}') as lc: lc.attr(label=lts.name) lc.attr(style='filled,rounded', color='grey95') lts.dot(lc, prefix=f'cluster_lts_{i}', void='global_void', **edge_kwargs) render(dot, 'mapping'.lower()) with out_dir.joinpath('caption_mapping.tex').open(mode='wt') as f: m_str = ', '.join(map(lambda t: '(' + ','.join(t) + ')', mapping)) print('\\caption{Mapping \\\\ $', file=f, end='') print(f'M = \\left\\lbrace {m_str} \\right\\rbrace', file=f, end='') print('$}', file=f)