def test_ye_ratio(self): # TODO: use ye curve from examples ? good_proto = Proto(dim=2, div=5, cubes=[ (0, 0), (0, 1), (1, 1), (1, 0), (2, 0), (2, 1), (2, 2), (1, 2), (0, 2), (0, 3), (0, 4), (1, 4), (1, 3), (2, 3), (2, 4), (3, 4), (4, 4), (4, 3), (3, 3), (3, 2), (4, 2), (4, 1), (3, 1), (3, 0), (4, 0), ]) # in new version we have (0,0)->(0,1) gate good_proto = BaseMap.parse('ji') * good_proto paths_gen = PathsGenerator(dim=2, div=5, hdist=1, max_cdist=1) for paths in paths_gen.generate_paths(): if paths[0].proto == good_proto: path0 = paths[0] break path0 = CurvePath(path0.proto, path0.portals) # legacy pcurve = PathFuzzyCurve.init_from_paths([path0]) estimator = Estimator(utils.ratio_l2_squared) curve = estimator.estimate_ratio(pcurve, rel_tol_inv=10000, verbose=False)['curve'] ratio = estimator.estimate_ratio(curve, rel_tol_inv=10000, use_vertex_brkline=True, verbose=False, max_depth=5) assert ratio['lo'] == (Rational(408, 73) ** 2)
def test_55_ratio(self): good_proto = Proto(dim=2, div=5, cubes=[ (0, 0), (0, 1), (1, 1), (1, 0), (2, 0), (2, 1), (2, 2), (1, 2), (0, 2), (0, 3), (0, 4), (1, 4), (1, 3), (2, 3), (2, 4), (3, 4), (4, 4), (4, 3), (3, 3), (3, 2), (4, 2), (4, 1), (3, 1), (3, 0), (4, 0), ]) # in new version we have (0,0)->(0,1) gate good_proto = BaseMap.from_basis('ji') * good_proto paths_gen = PathsGenerator(dim=2, div=5, hdist=1, max_cdist=1, verbose=1) for paths in paths_gen.generate_paths(): if paths[0].proto == good_proto: path0 = paths[0] break pcurve = PathFuzzyCurve.init_from_paths([path0]) estimator = Estimator(utils.ratio_l2_squared) curve = estimator.estimate_ratio(pcurve, rel_tol_inv=10000, verbose=False)['curve'] ratio = estimator.estimate_ratio(curve, rel_tol_inv=10000, use_vertex_brkline=True, verbose=False) assert ratio['lo'] == (FastFraction(408, 73)**2)
def test_polycurve_ratio(self): known_bounds = [ { 'curve': get_beta_omega_curve(), 'ratio': { 'l2': 5, 'l1': 9, 'linf': 5}, }, { 'curve': get_neptunus_curve(), 'ratio': { 'l2': [18.2, 18.4], 'linf': [9.44, 9.46]}, }, ] for data in known_bounds: curve = data['curve'] for metric, ratio in data['ratio'].items(): if isinstance(ratio, list): ratio_lo, ratio_up = ratio else: ratio_lo = ratio * 0.999 ratio_up = ratio * 1.001 if metric == 'l2': func = utils.ratio_l2_squared ratio_lo, ratio_up = ratio_lo**2, ratio_up**2 elif metric == 'l1': func = utils.ratio_l1 elif metric == 'linf': func = utils.ratio_linf res = Estimator(func).estimate_ratio(curve, rel_tol_inv=10**4) assert float(res['up']) <= ratio_up, 'metric {} up failed: {} > {}'.format(metric, res['up'], ratio_up) assert float(res['lo']) >= ratio_lo, 'metric {} lo failed: {} < {}'.format(metric, res['lo'], ratio_lo)
def main(): curve_gen = paths.PathsGenerator(dim=2, div=5, hdist=1, max_cdist=1, verbose=1) pcurves = list( PathFuzzyCurve.init_from_paths([path]) for path in curve_gen.generate_paths(uniq=True)) estimator = Estimator(ratio_l2_squared) res = estimator.estimate_ratio_sequence( pcurves, rel_tol_inv=1000000, rel_tol_inv_mult=2, sat_strategy={ 'type': 'geometric', 'multiplier': 1.5 }, ) print(res) print(estimator.stats) process = psutil.Process(os.getpid()) print('RSS:', process.memory_info().rss) # in bytes
def meta_perebor(dim, div, pattern_count, ratio_func, rel_tol_inv, rel_tol_inv_mult): estimator = Estimator(ratio_func, cache_max_size=2**16) result = {} for gates in gen_possible_gates(dim=dim, div=div, pattern_count=pattern_count): paths_gen = PathsGenerator(dim=dim, div=div, gates=gates) paths_list = list(paths_gen.generate_paths(uniq=True)) logging.warning('gates: %s', [str(g) for g in gates]) logging.warning('paths: %d', len(paths_list)) pcurves = (PathFuzzyCurve.init_from_paths(paths) for paths in paths_list) res = estimator.estimate_ratio_sequence( pcurves, rel_tol_inv=rel_tol_inv, rel_tol_inv_mult=rel_tol_inv_mult, sat_strategy={'type': 'geometric', 'multiplier': 1.3}, ) result[tuple(gates)] = {'paths': paths_list, 'estimate': res} for gates in sorted(result.keys()): gates_result = result[gates] print('Result for gates:', [str(g) for g in gates]) print('paths:', len(gates_result['paths'])) print('lower bound:', float(gates_result['estimate']['lo'])) print('upper bound:', float(gates_result['estimate']['up'])) print('')
def test_curve_ratio(self): known_bounds = [ { 'curve': get_hilbert_curve(), 'ratio': { 'l2': 6, 'l1': 9, 'linf': 6}, }, { 'curve': get_peano_curve(), 'ratio': {'l2': 8, 'l1': 32/3, 'linf': 8}, }, { 'curve': get_tokarev_curve(), 'ratio': {'l1': [98.2, 98.4], 'l2': [26.1, 26.3], 'linf': [24.1, 24.3]}, }, { 'curve': get_scepin_bauman_curve(), 'ratio': {'l1': (10 + 2/3), 'l2': (5 + 2/3), 'linf': (5 + 1/3)}, }, { 'curve': get_meurthe_curve(), 'ratio': {'l1': (10 + 2/3), 'l2': (5 + 2/3), 'linf': (5 + 1/3)}, }, { 'curve': get_serpentine_curve(), 'ratio': {'l1': 10, 'l2': 6.25, 'linf': 5.625}, }, { 'curve': get_coil_curve(), 'ratio': {'l1': (10 + 2/3), 'l2': (6 + 2/3), 'linf': (6 + 2/3)}, }, { 'curve': get_r_curve(), 'ratio': {'l1': (10 + 2/3), 'l2': (6 + 2/3), 'linf': (6 + 2/3)}, }, { 'curve': get_haverkort_curve_a26(), 'ratio': {'l1': (99 + 5/9), 'l2': [22.7,22.9], 'linf': (12 + 4/9)}, }, { 'curve': get_haverkort_curve_f(), 'ratio': {'l1': [89.7, 89.8], 'l2': [18,19], 'linf': 14}, }, { 'curve': get_ye_curve(), 'ratio': {'l2': [5.588, 5.59]}, }, { 'curve': get_17_curve(), 'ratio': {'l2': [16.9, 17.0]}, }, ] for data in known_bounds: curve = data['curve'] ratio_dict = data['ratio'] for metric in sorted(ratio_dict.keys()): ratio = ratio_dict[metric] if isinstance(ratio, list): ratio_lo, ratio_up = ratio else: ratio_lo = ratio * 0.999 ratio_up = ratio * 1.001 if metric == 'l2': func = utils.ratio_l2_squared ratio_lo, ratio_up = ratio_lo**2, ratio_up**2 elif metric == 'l1': func = utils.ratio_l1 elif metric == 'linf': func = utils.ratio_linf res = Estimator(func).estimate_ratio(curve, rel_tol_inv=10**5, verbose=False) print(res) assert float(res['up']) <= ratio_up, 'metric {} up failed: {} > {}'.format(metric, res['up'], ratio_up) assert float(res['lo']) >= ratio_lo, 'metric {} lo failed: {} < {}'.format(metric, res['lo'], ratio_lo)
def run_estimator( dim, div, pattern_count, ratio_func=None, rel_tol_inv=None, rel_tol_inv_mult=None, gate_list=None, hyper=False, max_cdist=None, upper_bound=None, output_gates=False, output_stats=False, shuffle=False, ): if gate_list is not None: gates_generator = gate_list else: gates_generator = GatesGenerator(dim, div, pattern_count, hyper=hyper).gen_gates() def gen_pcurves(): for gates_idx, gates in enumerate(gates_generator): if output_gates: yield gates continue logging.info('processing gates: %d', gates_idx + 1) paths_gen = PathsGenerator(dim=dim, div=div, portals=gates, max_cdist=max_cdist) if output_stats: counts = [] for gate in gates: gcnt = len( list( paths_gen.generate_paths_generic(portal=gate, std=True))) counts.append(gcnt) yield counts continue paths_list = list(paths_gen.generate_paths(std=True)) logging.warning('gates: %s', [str(g) for g in gates]) logging.warning('paths: %d', len(paths_list)) for paths_idx, paths in enumerate(paths_list): logging.info('processing gate_paths: %d of %d', paths_idx + 1, len(paths_list)) paths = tuple( CurvePath(path.proto, path.portals) for path in paths) yield PathFuzzyCurve.init_from_paths(paths) pcurves_generator = gen_pcurves() if output_stats: scnt = 0 for counts in pcurves_generator: prod = 1 for cnt in counts: prod *= cnt print(prod) scnt += prod print('TOTAL:', scnt) return if output_gates: for gates in pcurves_generator: print(' | '.join([str(gate) for gate in gates])) return if shuffle: pcurves_generator = list(pcurves_generator) random.shuffle(pcurves_generator) estimator = Estimator(ratio_func, cache_max_size=2**16) result = estimator.estimate_ratio_sequence( pcurves_generator, rel_tol_inv=rel_tol_inv, rel_tol_inv_mult=rel_tol_inv_mult, sat_strategy={ 'type': 'geometric', 'multiplier': 1.3 }, upper_bound=upper_bound, ) print(result) print('======') print('lower bound:', float(result['lo'])) print('upper bound:', float(result['up']))
def perebor(conf, start_idx=None, end_idx=None): logging.warning('CONF: %s', conf) funcs = { 'l1': utils.ratio_l1, 'l2': utils.ratio_l2, 'l2_squared': utils.ratio_l2_squared, 'linf': utils.ratio_linf, } ratio_func = funcs[conf['ratio_func_name']] dim, div = conf['dim'], conf['div'] gates = None if 'gate_strs' in conf: gates = [get_gate(g) for g in conf['gate_strs']] elif 'gates' in conf: gates = conf['gates'] paths_gen = PathsGenerator( dim=dim, div=div, hdist=conf.get('hdist'), gates=gates, max_cdist=conf.get('max_cdist'), ) paths_list = list(paths_gen.generate_paths(uniq=True)) logging.warning('paths: %d', len(paths_list)) if end_idx is not None: # should be checked first! paths = list(paths) paths = paths[:end_idx] if start_idx is not None: paths = list(paths) paths = paths[start_idx:] estimator = Estimator(ratio_func, cache_max_size=2**16) #logging.warning('sort by paths ratio ...') #path_ratio = {path: estimator.estimate_path(path) for path in paths} #paths.sort(key=lambda path: path_ratio[path]) pcurves = (PathFuzzyCurve.init_from_paths(paths) for paths in paths_list) res = estimator.estimate_ratio_sequence( pcurves, rel_tol_inv=conf['rel_tol_inv'], rel_tol_inv_mult=conf.get('rel_tol_inv_mult', 2), sat_strategy={ 'type': 'geometric', 'multiplier': 1.3 }, upper_bound=conf.get('upper_bound'), ) if res is None: res = {'lo': 0, 'up': float('inf')} res['paths_count'] = len(paths_list) res['lo_float'] = float(res['lo']) res['up_float'] = float(res['up']) print('CONFIG:', conf) print('BOUNDS: {:.6f} <= r <= {:.6f}'.format(res['lo_float'], res['up_float'])) print('RESULT:', res, flush=True)
def run_estimator( dim, div, pcount, finish_max_count=None, ratio_func=None, rel_tol_inv=None, rel_tol_inv_mult=None, gate_list=None, hyper=False, max_cdist=None, upper_bound=None, group_by_gates=False, output_gates=False, output_stats=False, output_examples=None, ): if gate_list is not None: gates_generator = gate_list else: gates_generator = GatesGenerator(dim, div, pcount, hyper=hyper).gen_gates() def gen_pcurves(gates_iterable): for gates_idx, gates in enumerate(gates_iterable): if output_gates: yield gates continue logging.info('processing gates: %d', gates_idx + 1) paths_gen = PathsGenerator(dim=dim, div=div, portals=gates, max_cdist=max_cdist) if output_stats: counts = [] for gate in gates: gcnt = len( list( paths_gen.generate_paths_generic(portal=gate, std=True))) counts.append(gcnt) yield counts continue kw = {} if finish_max_count is not None: kw['finish_max_count'] = finish_max_count paths_list = list(paths_gen.generate_paths(std=True, **kw)) logging.warning('gates: %s', [str(g) for g in gates]) logging.warning('paths: %d', len(paths_list)) for paths_idx, paths in enumerate(paths_list): logging.info('processing gate_paths: %d of %d', paths_idx + 1, len(paths_list)) paths = tuple( CurvePath(path.proto, path.portals) for path in paths) yield PathFuzzyCurve.init_from_paths(paths) if output_stats: scnt = 0 for counts in gen_pcurves(gates_generator): prod = 1 for cnt in counts: prod *= cnt print(prod) scnt += prod print('TOTAL:', scnt) return if output_gates: for gates in gates_generator: print(' | '.join([str(gate) for gate in gates])) return estimator = Estimator(ratio_func, cache_max_size=2**16) if group_by_gates: pcurve_gens = [(gates, gen_pcurves([gates])) for gates in gates_generator] else: pcurve_generator = gen_pcurves(gates_generator) pcurve_gens = [('all_gates', pcurve_generator)] for gen_id, pcurves_generator in pcurve_gens: result = estimator.estimate_ratio_sequence( pcurves_generator, rel_tol_inv=rel_tol_inv, rel_tol_inv_mult=rel_tol_inv_mult, sat_strategy={ 'type': 'geometric', 'multiplier': 1.3 }, upper_bound=upper_bound, ) print('======') print('GENERATOR:', gen_id) if not result: print('NOT FOUND!') else: print(result) print('lower bound:', float(result['lo'])) print('upper bound:', float(result['up'])) if output_examples: for curve in result['examples']: print(curve) print('') print('', flush=True)