def __init__(self, w, h, state): self.state = state BaseMap.__init__(self, w, h) self.tiles = {} self.needs_update = True self.edges = {} self.edge_tile_map = BorderEdgeTileMap(self)
def bauman(): proto = ((0, 0), (0, 1), (0, 2), (1, 2), (1, 1), (1, 0), (2, 0), (2, 1), (2, 2)) base_maps = [ BaseMap(perm=[1, 0], flip=[False, False]), BaseMap(perm=[1, 0], flip=[True, False]), BaseMap.id_map(dim=2), BaseMap(perm=[1, 0], flip=[False, True]), BaseMap(perm=[1, 0], flip=[True, True]), BaseMap(perm=[0, 1], flip=[False, True]), BaseMap(perm=[1, 0], flip=[False, False]), BaseMap(perm=[1, 0], flip=[True, False]), BaseMap.id_map(dim=2), ] bauman = FractalCurve(dim=2, div=3, proto=proto, base_maps=base_maps) bauman.estimate_ratio_vertex_brkline(ratio_l2, 3) #good.estimate_ratio(ratio, rel_tol=0.002, verbose=1) bauman = bauman.get_subdivision(1) pcurve = bauman.forget() pcurve = pcurve.changed(allow_time_rev=True) pcurve.estimate_ratio(ratio_l2, lower_bound=32.2, upper_bound=32.1, sat_pack=1000, find_model=True)
def get_hilbert_curve(): """Example of fractal curve due to D.Hilbert.""" return FractalCurve( proto=[(0, 0), (0, 1), (1, 1), (1, 0)], base_maps=[ BaseMap([1, 0], [False, False]), # (x,y)->(y,x) BaseMap.id_map(2), # (x,y)->(x,y) BaseMap.id_map(2), # (x,y)->(x,y) BaseMap([1, 0], [True, True]), # (x,y)->(1-y,1-x) ], )
def get_rev3_curve(): """Curve with time reversal at last cube.""" return FractalCurve( proto=[(0, 0), (0, 1), (1, 1), (1, 0)], base_maps=[ BaseMap([1, 0], [False, False]), # (x,y)->(y,x) BaseMap.id_map(2), # (x,y)->(x,y) BaseMap.id_map(2), # (x,y)->(x,y) BaseMap([1, 0], [True, False], time_rev=True), # (x,y)->(1-y,x), t->1-t ], )
def get_peano_curve(): """Example of fractal curve due to G.Peano.""" id_map = BaseMap.id_map(2) x_map = BaseMap([0, 1], [True, False]) # (x,y)->(1-x,y) y_map = BaseMap([0, 1], [False, True]) # (x,y)->(x,1-y) xy_map = BaseMap([0, 1], [True, True]) # (x,y)->(1-x,1-y) return FractalCurve( proto=[(0, 0), (0, 1), (0, 2), (1, 2), (1, 1), (1, 0), (2, 0), (2, 1), (2, 2)], base_maps=[ id_map, x_map, id_map, y_map, xy_map, y_map, id_map, x_map, id_map, ], )
def get_edge_touch(self, edge): """Find moment of first edge touch. Edge is a tuple of {0,1,None} defining a set {(x_0,...,x_{d-1}): x_i==0 if e[i]==0, x_i==1 if e[i]==1, or arbitrary x[i] if e[i] is None. E.g., tuples (0,0,0) or (0,1,1) define vertices """ curve = self cur_map = BaseMap.id_map(self.dim) # curve = cur_map * self cnums = [] index = {} while True: cnum = curve._get_edge_cnum(edge) bm = curve.base_maps[cnum] cnums.append(cnum) index[cur_map] = len(cnums) - 1 cur_map = bm * cur_map if cur_map in index: period_start = index[cur_map] break curve = curve.apply_base_map(bm) return self._get_time_limit(cnums[0:period_start], cnums[period_start:])
def divide(self): curve = self.curve dim, G = curve.dim, curve.genus # определим ориентацию предпоследнего кусочка # в последнем кубе ориентация не задана! prev_map = BaseMap.id_map(dim) for cnum in self.pos.cnums[:-1]: cnum = prev_map.apply_cnum(G, cnum) prev_map = prev_map * curve.base_maps[ cnum] # именно в таком порядке! prev_curve = curve.apply_base_map(prev_map) active_cnum = self.pos.cnums[-1] # кубик, где всё происходит spec_cnum = prev_map.apply_cnum(G, active_cnum) # делим for bm in prev_curve.gen_allowed_maps(active_cnum): # сопряжение, как в apply: # для prev_curve.base_maps[active_cnum] = bm => orig_curve.base_maps[spec_cnum] = ... new_map = prev_map.inverse() * bm * prev_map specified_curve = curve.specify(spec_cnum, new_map) last_curve = prev_curve.apply_base_map(bm) for cnum, cube in enumerate(last_curve.proto): new_pos = self.pos.specify(cnum, cube) new_piece = CurvePiece(specified_curve, new_pos) yield new_piece
def setUp(self): self.pm_examples = [ PieceMap( base_map=BaseMap([3,2,1,0],[True,False,False,False]), shift=(-1,-2,-3,-4), scale=3, time_shift=-10, time_scale=1, ), PieceMap( base_map=BaseMap([4,0,1,3,2],[True,False,False,True,True]), shift=(-Fraction(1, 2), Fraction(1, 2), Fraction(1, 3), Fraction(1, 5), Fraction(1, 7)), scale=Fraction(1, 11), time_shift=0, time_scale=1, ), ]
def load_map(cls, filename): asset_path = ''.join((os.path.dirname(__file__), '\\..\\..\\assets\\maps\\', filename, '.txt')) f = open(asset_path, 'r') map_lines = [] for line in f: if line.strip() == '': continue map_lines.append(list(line.rstrip())) f.close() h = len(map_lines) w = len(map_lines[0]) map = [[map_lines[y][x] for y in range(h)] for x in range(w)] new = BaseMap(w, h) new.set_map(map) # temp - modify block map pre real map generator algo cls.add_blocks(new) return new
def get_peano5_curve(): id_map = BaseMap.id_map(2) x_map = BaseMap([0, 1], [True, False]) # (x,y)->(1-x,y) y_map = BaseMap([0, 1], [False, True]) # (x,y)->(x,1-y) xy_map = BaseMap([0, 1], [True, True]) # (x,y)->(1-x,1-y) return FractalCurve( dim=2, div=5, proto=[ (0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 4), (1, 3), (1, 2), (1, 1), (1, 0), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 4), (3, 3), (3, 2), (3, 1), (3, 0), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), ], base_maps=[ id_map, x_map, id_map, x_map, id_map, y_map, xy_map, y_map, xy_map, y_map, id_map, x_map, id_map, x_map, id_map, y_map, xy_map, y_map, xy_map, y_map, id_map, x_map, id_map, x_map, id_map, ], )
def get_scepin_bauman_curve(): proto = ( (0, 0), (0, 1), (0, 2), (1, 2), (1, 1), (1, 0), (2, 0), (2, 1), (2, 2), ) base_maps = [ BaseMap.id_map(dim=2), BaseMap([1,0],[True,False]), # rot(90) BaseMap([1,0],[False,False]), # (x,y)->(y,x) BaseMap([0,1],[False,True]), # (x,y)->(x,1-y) BaseMap([1,0],[True,True]), # (x,y)->(1-y,1-x) BaseMap([1,0],[False,True]), # rot(-90) BaseMap.id_map(dim=2), BaseMap(perm=[1,0],flip=[True,False]), # rot(90) BaseMap(perm=[1,0],flip=[False,False]), # (x,y)->(y,x) ] return FractalCurve(dim=2, div=3, proto=proto, base_maps=base_maps)
def get_haverkort_curve_A26(): """3-D curve with time reversal.""" proto = [(0,0,0), (0,0,1), (0,1,1), (0,1,0), (1,1,0), (1,1,1), (1,0,1), (1,0,0)] base_maps = [ BaseMap([2, 1, 0], [False, False, False]), BaseMap([2, 0, 1], [False, False, False]), BaseMap([2, 0, 1], [False, True, False], time_rev=True), BaseMap([0, 2, 1], [False, True, True]), BaseMap([0, 2, 1], [True, True, True], time_rev=True), BaseMap([2, 0, 1], [True, True, False]), BaseMap([2, 0, 1], [True, False, False], time_rev=True), BaseMap([1, 2, 0], [True, False, False], time_rev=True), ] return FractalCurve( proto=proto, base_maps=base_maps, )
def _get_cubes(self, cnum): # находим последовательность вложенных кубов, которая получится, если в каждой фракции брать куб с номером cnum # возвращает пару (непериодическая часть, периодическая часть) cur_map = BaseMap.id_map(self.dim) # current curve = cur_map * self cubes = [] index = {} while True: cur_curve = self.apply_base_map(cur_map) cube = cur_curve.proto[cnum] cubes.append(cube) index[cur_map] = len(cubes) - 1 cur_map = cur_curve.base_maps[cnum] * cur_map if cur_map in index: idx = index[cur_map] return cubes[0:idx], cubes[idx:]
def bmstr2base_map(bmstr): if '1-t' in bmstr: time_rev = True else: time_rev = False match = re.match('\(x,y\)->\((.*),(.*)\)', bmstr) if not match: print('@@@', bmstr) g1, g2 = match.groups() if 'x' in g1: perm = [0, 1] else: perm = [1, 0] flip = [False] * 2 flip[0] = ('1-' in g1) flip[1] = ('1-' in g2) return BaseMap(perm, flip, time_rev)
def basis2base_map(basis): dim = len(basis) - 1 if basis[-1] in ['0', '1'] else len(basis) letters = 'ijklmn' assert dim <= 6 l2i = {l: i for i, l in enumerate(letters)} perm = [None] * dim flip = [None] * dim time_rev = True if basis[-1] == '1' else False basis = basis[:-1] if basis[-1] in ['0', '1'] else basis for k, l in enumerate(basis): lk = l.lower() perm[k] = l2i[lk] flip[k] = (l != lk) return BaseMap(perm, flip, time_rev)
def __init__(self, w, h, river): self.river = river BaseMap.__init__(self, w, h)
return Variable(mask) # ----------------------------------------------------------------------------- encoder = GenericMap( [1,1], [r_dim], siamese_input=False, num_hidden_layers=2, hidden_dim=40, siamese_output=False, act='relu', deterministic=True, use_bn=use_bn ) encoder_optim = Adam(encoder.parameters(), lr=encoder_lr) base_map = BaseMap( z_dim, [1], [1], siamese_input=False, num_hidden_layers=2, hidden_dim=40, siamese_output=False, act='relu', deterministic=True, use_bn=use_bn ) base_map_optim = Adam(base_map.parameters(), lr=base_map_lr) r_to_z_map = GenericMap( [r_dim], [z_dim], siamese_input=False, num_hidden_layers=2, hidden_dim=40, siamese_output=False, act='relu', deterministic=False, use_bn=use_bn ) r_to_z_map_optim = Adam(r_to_z_map.parameters(), lr=r_to_z_map_lr) neural_process = NeuralProcessV1(
out = lin_out + z_out out = F.relu(out) lin_out = self.lin_mod_list[-1](out) z_out = torch.matmul(out.view(out.size(0), 1, out.size(-1)), z_Ws[-1]) z_out = z_out.view(-1, z_out.size(-1)) out = lin_out + z_out return out # for lin in self.lin_mod_list(): # out = torch.matmul(out, ) base_map = BaseMap() encoder_optim = Adam(encoder.parameters(), lr=encoder_lr) r_to_z_map_optim = Adam(r_to_z_map.parameters(), lr=r_to_z_map_lr) base_map_optim = Adam(base_map.parameters(), lr=base_map_lr) # ----------------------------------------------------------------------------- test_elbos = defaultdict(list) test_log_likelihoods = defaultdict(list) for iter_num in range(max_iters): task_batch_idxs = choice(len(all_tasks), size=num_tasks_per_batch, replace=replace) num_samples_per_task = array( [num_per_task_high for _ in range(num_tasks_per_batch)]) max_num = num_per_task_high
def __init__(self, w, h, moisture_map): BaseMap.__init__(self, w, h) self.moisture_map = moisture_map
def estimate_ratio(self, ratio_func, junctions=None, upper_bound=None, max_iter=None, rel_tol=None, find_argmax=False, verbose=0): """Estimate ratio of a curve for given junctions. Params: ratio_func generic function for ratio; args: d, delta_v, delta_t we assume it is d-homogeneous junctions list of junctions (None for all junctions, [None] for self reduced ratio) upper_bound apriori upper bound for ratio; we stop if higher ratio is found max_iter subj rel_tol relative error tolerance verbose print every iteration find_argmax subj Returns dict with keys: lower_bound bounds for ratio upper_bound argmax dict with keys {v1,t1,v2,t2,junc}, describing ratio argmax (if options find_argmax is set) stats counter with some statistics """ # Алгоритм работы: # сравниваем пары фракций: # 1) оцениваем отношение снизу (через вершины, например) # если отношение больше текущей верхней оценки - выходим # 2) оцениваем отношение сверху (по прототипу) # - если меньше текущей нижней оценки - останавливаемся, не подразбиваем # - иначе, подразбиваем обе фракции if any(bm.time_rev for bm in self.base_maps): raise Exception("Not implemented for curves with time reversal!") if max_iter is None and rel_tol is None: raise Exception("Define max_iter or rel_tol!") if junctions is None: junctions = set(self.gen_junctions()) junctions.add(None) d = self.dim N = self.div G = self.genus # тут можно использовать другие ломаные self_brkline = self.get_vertex_brkline() # приводим ломаную к целым числам; множители lcm_x, lcm_t применим лишь в самом конце вычислений denoms = [] for v, t in self_brkline: denoms.append(t.denominator) denoms += [x.denominator for x in v] lcm_x = get_lcm(denoms) lcm_t = lcm_x**d int_brkline = [] for v, t in self_brkline: new_t = int(t * lcm_t) new_v = tuple(int(x * lcm_x) for x in v) int_brkline.append((new_v, new_t)) argmax = None stats = Counter() curr_lower_bound = FastFraction(0, 1) curr_upper_bound = None rich_pairs = [] # пары кривых с доп. информацией entry_count = 0 for junc in junctions: if junc is None: delta_x = (0, ) * d delta_t = 0 junc_base_map = BaseMap.id_map(self.dim) else: delta_x, junc_base_map = junc.delta_x, junc.base_map delta_t = 1 start_pair = self.CurveBalancedPair( delta_x=delta_x, delta_t=delta_t, base_map=junc_base_map, compare=0, ) if find_argmax: start_pair.orig_map = PieceMap.id_map(d) # дробим каждую из частей (дробление только одной не уменьшает кол-во итераций) junc_pairs = [] for pair in self.divide_pair(start_pair): for sub_pair in self.divide_pair(pair): if sub_pair.delta_t <= 1: continue junc_pairs.append(sub_pair) for pair in junc_pairs: # оцениваем сверху отношение для пары, чтобы приоритезировать пары с высоким отношением up_ratio = pair.get_upper_bound(N, ratio_func) rich_pair = { 'pair': pair, 'upper_bound': up_ratio, 'max_subdivision': 1 } if find_argmax: rich_pair['junc'] = junc entry_count += 1 priority = -up_ratio heappush(rich_pairs, (priority, entry_count, rich_pair)) seen_pairs = set() while rich_pairs: stats['iter'] += 1 if max_iter is not None and stats['iter'] >= max_iter: break rich_pair = heappop(rich_pairs)[-1] pair = rich_pair['pair'] delta_x = pair.delta_x delta_t = pair.delta_t base_map = pair.base_map # учитываем, что одна из фракций "раздута" if pair.compare == 0: mx1, mx2 = 1, 1 elif pair.compare == 1: mx1, mx2 = N, 1 else: mx1, mx2 = 1, N mt1, mt2 = mx1**d, mx2**d pair_position = (delta_x, delta_t, base_map, pair.compare) if pair_position in seen_pairs: # пара уже встречалась, новых оценок нам не даст stats['seen_pair'] += 1 continue else: seen_pairs.add(pair_position) stats['max_subdivision'] = max(stats['max_subdivision'], rich_pair['max_subdivision']) if verbose: print('iter: {}; max_subdivision: {}; ratio: {} <= X <= {}'. format( stats['iter'], stats['max_subdivision'], float(curr_lower_bound), (float(curr_upper_bound) if curr_upper_bound is not None else '?'), )) # могла обновиться нижняя оценка, и пара больше не актуальна! up_ratio = rich_pair['upper_bound'] if up_ratio <= curr_lower_bound: stats['stop_early'] += 1 continue # # Обновим верхнюю границу (curr_upper_bound) # # здесь мы используем, что rich_pairs это heap по priority = (-upper_bound) curr_upper_bound = max( up_ratio, rich_pairs[0][-1]['upper_bound']) if rich_pairs else up_ratio if up_ratio <= curr_lower_bound: # нам эта пара больше не интересна! stats['stop_divide'] += 1 continue # # Обновим нижнюю оценку (curr_lower_bound) # # поскольку приводили к целым числам, нужно всё умножить на lcm_x (соотв., lcm_t) if mx1 == 1: brkline1 = int_brkline else: brkline1 = [] for v, t in int_brkline: scaled_v = tuple(v[j] * mx1 for j in range(d)) scaled_t = t * mt1 brkline1.append((scaled_v, scaled_t)) brkline2 = [] for v, t in int_brkline: # повернуть + масштабировать rot_v = base_map.apply_x2(v, lcm_x) if mx2 == 1: scaled_v = rot_v scaled_t = t else: scaled_v = tuple(rot_v[j] * mx2 for j in range(d)) scaled_t = t * mt2 brkline2.append((scaled_v, scaled_t)) # так как в ломаных уже "сидят" lcm-ы, умножаем только дельты scaled_delta_x = tuple(dx * lcm_x for dx in delta_x) scaled_delta_t = delta_t * lcm_t for v2, t2 in brkline2: v2_shifted = tuple(v2[j] + scaled_delta_x[j] for j in range(d)) t2_shifted = t2 + scaled_delta_t for v1, t1 in brkline1: dv = tuple(v2_shifted[j] - v1[j] for j in range(d)) dt = t2_shifted - t1 ratio = FastFraction(*ratio_func(d, dv, dt)) if ratio > curr_lower_bound: curr_lower_bound = ratio if find_argmax: inv = pair.orig_map.inverse() # нужно вернуться обратно # сначала уберём lcm-ы v1_frac = tuple( Fraction(v1[j], lcm_x) for j in range(d)) v2_frac = tuple( Fraction(v2_shifted[j], lcm_x) for j in range(d)) t1_frac = Fraction(t1, lcm_t) t2_frac = Fraction(t2_shifted, lcm_t) # теперь обратное преобразование (orig_v1, orig_t1) = inv.apply(v1_frac, t1_frac) (orig_v2, orig_t2) = inv.apply(v2_frac, t2_frac) # v2, t2 считаем относительно второй фракции junc = rich_pair['junc'] if junc is not None: orig_v2 = tuple(orig_v2[j] - junc.delta_x[j] for j in range(d)) orig_t2 -= 1 argmax = { 'v1': orig_v1, 't1': orig_t1, 'v2': orig_v2, 't2': orig_t2, 'junc': junc, } if upper_bound is not None and curr_lower_bound > upper_bound: break if rel_tol is not None and float(curr_upper_bound) <= ( 1 + rel_tol) * float(curr_lower_bound): break for sub_pair in self.divide_pair(pair): max_subdivision = rich_pair['max_subdivision'] if pair.compare == 0: max_subdivision += 1 # если фракции были равны, номер подразбиения увеличился up_ratio = sub_pair.get_upper_bound(N, ratio_func) if up_ratio <= curr_lower_bound: # нам эта пара больше не интересна! continue new_rich_pair = { 'pair': sub_pair, 'upper_bound': up_ratio, 'max_subdivision': max_subdivision } if 'junc' in rich_pair: new_rich_pair['junc'] = rich_pair['junc'] entry_count += 1 heappush(rich_pairs, (-up_ratio, entry_count, new_rich_pair)) return { 'lower_bound': curr_lower_bound, 'upper_bound': curr_upper_bound, 'argmax': argmax, 'stats': stats, }
def get_discontinuous_curve(): return FractalCurve( proto=[(1, 1), (0, 1), (0, 0), (1, 0), (2, 0), (2, 1), (2, 2), (1, 2), (0, 2)], base_maps=[BaseMap.id_map(2)] * 9, )
def test_mul(self): bm1 = BaseMap([0,1],[True,False]) # (1-x,y) bm2 = BaseMap([1,0],[False,False]) # (y,x) self.assertEqual(bm1 * bm2, BaseMap([1,0],[True,False])) self.assertEqual(bm2 * bm1, BaseMap([1,0],[False,True]))
def test_inv(self): bm = BaseMap(perm=[3,2,1,0], flip=[True,True,True,True]) self.assertEqual(bm * bm.inverse(), BaseMap.id_map(dim=4)) self.assertEqual(bm, bm.reverse_time().reverse_time())