Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
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
Пример #5
0
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('')
Пример #6
0
    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)
Пример #7
0
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']))
Пример #8
0
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)
Пример #9
0
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)