def generate_symbols_on_trajectory(cfg, Xs, Ys, mindist, nscales): # sample symbol location from unit sphere i = 0 denom = 20.0 coord = np.array([Xs[i], Ys[i]]) symbols = [spawn_symbol(cfg, coord, mindist/denom, nscales)] for i in range(1, len(Xs)): coord = np.array([Xs[i], Ys[i]]) _, dist = utils.get_closest_symbol(symbols, coord) if dist >= mindist: symbols.append(spawn_symbol(cfg, coord, mindist/denom, nscales)) return symbols
def main(): args = parse_args() # start and target symbols Start = np.array(uv2xyz(-.75 * np.pi, 0.4 * np.pi)).flatten() Target = np.array(uv2xyz(+np.pi / 20, 0.4 * np.pi)).flatten() # 'agent' for ground truth. simply used as integrator agent = Agent3DSphere(speed=0.01, A=Start, B=Target) # particle setup particles_json_path = 'data/particles.1M.010.json' Nsymbols = 5000 mindist = 0.10 # output setup trajectorysamples_json_path = 'data/trajectorysamples.1M.010.json' #particles_json_path = 'data/particles.1M.005.json' #Nsymbols = 10000 #mindist = 0.05 particles_args = { 'dist_type': 'euclidean', 'mindist': mindist, 'maxdist': 2.0 * 0.1, 'mindist_rnd_threshold': 0.9, 'mindist_rnd_chance': 0.1, 'alpha': 0.1, 'alpha_decay': 0.9999, 'mem': 0.9, } particles = PushPullParticleSystem(**particles_args) # load_json will also load the particle state_dict particles.load_json(particles_json_path) # plot setup fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.set_aspect('equal', 'box') ax.set_xlim(-1, 1) ax.set_ylim(-1, 1) ax.set_zlim(-1, 1) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') hide_axes(ax) vis_sphere = None vis_agent = None vis_coord = None vis_trace = None vis_particles = None draw_hidden_aspect_cube(ax) print("Computing ground truth geodesic") for timestep in range(1000): # move around agent.move(random_walk=False) dist = np.linalg.norm(agent.X - Target) if dist <= agent.speed / 2: # reached goal, or would overshoot break # get some random points on the hemisphere print("Picking symbols randomly") sym_xs, sym_ys, sym_zs = pick_npoints_on_hemisphere(N=Nsymbols) if False: ax.scatter(sym_xs, sym_ys, sym_zs, color='#7a7a7a', s=0.3) symbols = xs2symbols(sym_xs, sym_ys, sym_zs) # get indices of start and target symbols i_start_sym, _ = utils.get_closest_symbol(symbols, Start) i_target_sym, _ = utils.get_closest_symbol(symbols, Target) # create transition layer and associate it with all symbols print("Generating transition layers") layer = modules.TransitionLayer(particles_args['mindist'], -1.0, -1.0, pointgen_fn='particles', particles=particles) layer.associate(symbols, 0) # record everything!11 recorder = utils.Recorder(1) # find sequence using the layer. Note that this is not guaranteed to work if # there is no viable trajectory... print("Searching trajectory...") hits = algorithms.find_sequence_on_scale([layer], 0, symbols, i_start_sym, i_target_sym, recorder) print("Trajectory found.") # Monte Carlo Sampling: compute M sample trajectories print("Monte Carlo Sampling") M = 50 ps = [] for i in range(M): ps.append([]) p = symbols[i_target_sym] ps[i].append(p) while not (p == symbols[i_start_sym]): p = symbols[p.getRandomParent()] ps[i].append(p) # compute sample average avg_trace = [] Ns = len(ps[0]) for n in range(Ns): avg = ps[0][n].coord.copy() for m in range(1, M): avg += ps[m][n].coord avg /= np.linalg.norm(avg) avg_trace.append(avg) # draw calls clean_all(ax, vis_sphere, vis_agent, vis_coord, vis_trace) if vis_particles is not None: ax.collections.remove(vis_particles) # draw grid field centers vis_particles = draw_particles(ax, particles, color='gray', s=1) vis_sphere, _, _, _, _, _ = draw_all(ax, agent=agent, A=Start, B=Target, plot_trace=True, plot_agent=False) # draw monte carlo samples for k in range(M): for i in range(1, len(ps[k])): s = ps[k][i - 1] t = ps[k][i] v = t.coord - s.coord draw_vector(ax, s.coord, v, color=style.color.sample, lw=0.4, scale=1.0, alpha=0.5) # style.alpha.sample) # draw sample average xs = [] ys = [] zs = [] for X in avg_trace: xs.append(X[0] * 1.0001) ys.append(X[1] * 1.0001) zs.append(X[2] * 1.0001) ax.plot3D(xs, ys, zs=zs, color='black', linewidth=2.0, linestyle='--') # write all samples + symbol locations to file d = { 'M_samples': M, 'trajectory_length': len(ps[0]), 'trajectory_data': [], 'symbol_data': [] } for m in range(M): td = [] for n in range(len(ps[0])): td.append([ float(ps[m][n].coord[0]), float(ps[m][n].coord[1]), float(ps[m][n].coord[2]) ]) d['trajectory_data'].append(td) for i in range(len(sym_xs)): d['symbol_data'].append( [float(sym_xs[i]), float(sym_ys[i]), float(sym_zs[i])]) with open(trajectorysamples_json_path, 'w') as f: json.dump(d, f, indent=1) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') plt.show()
def main(args) : # get a string for this simulation and generate the directory global DEMO_NAME # grid periods to use in this demo periods = [0.2] for i in range(1, args.nscales): periods.append(periods[-1] * np.sqrt(2)) basename = os.path.basename(args.filename) dir_str = "{}/{}_{}.d".format(args.output_dir, DEMO_NAME, basename) if args.save_figures: print("Saving figures to directory {}".format(dir_str)) if not os.path.exists(dir_str): os.mkdir(dir_str) # load HDF5 print("Loading trajectory data from file '{}'".format(args.filename)) cfg, Xs, Ys = utils.load_trajectory_hdf5(args.filename, verbose=False) # generate symbols, and select start and targets print("Generating symbols along trajectory.") symbols = generate_symbols_on_trajectory(cfg, Xs, Ys, args.mindist, args.nscales) global_start, _ = utils.get_closest_symbol(symbols, np.array([Xs[0], Ys[0]])) global_target, _ = utils.get_closest_symbol(symbols, np.array([Xs[-1], Ys[-1]])) # create transition layers and associate each with all available symbols print("Generating transition layers") z = 0 layers = [] for period in periods: print("Generating layer {} of {}".format(z+1, len(periods))) layers.append(modules.TransitionLayer(period, cfg.world_radius * 2.0, cfg.world_radius * 2.0, pointgen.hex)) # this is required due to the circular world, centered at 0.0 # shift all transitions for t in layers[-1].ts: t.coord -= cfg.world_radius # remove transitions outside of the environment ts = [] for t in layers[-1].ts: dist = np.linalg.norm(t.coord) if dist <= (cfg.world_radius + 0.1): ts.append(t) layers[-1].ts = ts # compute neighborhood layers[-1].compute_neighborhoods() print("associating layer {}".format(z)) layers[-1].associate(symbols, z) z += 1 # plot that only shows the transition centers fig, axs = plotter.setup_watermaze(cfg, len(periods), ion=False) for scale in range(args.nscales): # exploit the symbol plotter here plotter.watermaze(axs[scale], cfg, Xs[0], Ys[0], plot_start_target=False) plotter.symbols(axs[scale], layers[scale].ts, range(len(layers[scale].ts))) if args.save_figures: fig.savefig("{}/transition_centers.svg".format(dir_str)) plt.show() # result plotting fig, axs = plotter.setup_watermaze(cfg, len(periods), ion=False) for ax in axs: plotter.watermaze(ax, cfg, Xs[0], Ys[0]) plotter.symbols(ax, symbols, []) plotter.trajectory(ax, Xs, Ys) plotter.start_target(ax, symbols, [global_start], [global_target]) print("Running algorithm for each layer individually.") recorder = utils.Recorder(args.nscales) for scale in range(args.nscales): # reset the symbols for this scale for s in symbols: s.reset() # # Algorithm: expansion only, then backtracking during sample computation # hits = find_sequence_on_scale(layers, scale, symbols, global_start, global_target, args, recorder) print("Scale {}: Trajectory found.".format(scale)) ts = [] # Algorithm: compute M sample trajectories for i in range(args.M): # backtracking ala Dijkstra p = symbols[global_target] ts.append(layers[scale].ts[p.t[scale]]) s = symbols[global_target] # TODO: is the following line required? I think not ts.append(layers[scale].ts[s.t[scale]]) while not (s == symbols[global_start]): rnd_p = p.getRandomParent() p = symbols[rnd_p] ts.append(layers[scale].ts[p.t[scale]]) plotter.sample_segment(axs[scale], s, p) s = p ts.append(layers[scale].ts[s.t[scale]]) ts = list(set(ts)) cols = utils.Config() cols.transition = 'gray' for t in ts: plotter.transition_domain(axs[scale], t, periods[scale]) axs[scale].axis('off') if args.save_figures: fig.savefig("{}/results.svg".format(dir_str)) plt.show()
def simulate_linear_track(symbols, grid_period, W, H, output_dir, live_plot=False): """Simulate a linear track, on which the goal is to go from start to finish""" # color configuration colors = utils.Config() colors.symbol_hit = 'black' colors.symbol_hit_alpha = 0.6 colors.symbol_miss = 'grey' colors.symbol_miss_alpha = 0.4 colors.transition_hit = '#2882cd' colors.transition_hit_alpha = 0.6 colors.transition_miss = 'grey' colors.transition_miss_alpha = 0.4 # create transition layer and associate it with all available symbols layer = modules.TransitionLayer(grid_period, W, H, pointgen.flat) layer.associate(symbols) # select some random symbol and activate it as well as all others in the area current_symbols = layer.getClosestTransition(np.array((0, 0))).domain # select the rightmost symbols as final target location target_symbol, _ = utils.get_closest_symbol(symbols, np.array([W, 0.0])) # visualization setup fig = plt.figure(figsize=(20, 3)) gs = gspec.GridSpec(1, 1) gs.update(left=0.05, right=0.95, top=0.95, bottom=0.05, wspace=0.025, hspace=0.05) ax = plt.subplot(gs[0]) if live_plot: plt.ion() plt.show() # pure retrieval to target ticks = 0 while not target_symbol in current_symbols: ax.clear() # update 'retrieval tick' -> this emulates refractory periods of place # cells, which this model predicts are significantly different than grid # cell refractory periods for s in current_symbols: symbols[s].retrieval_tick = ticks # plot all transitions for which the precondition is met ts = layer.getDefinedTransitions(current_symbols) layer.plot_with_highlight(ax, symbols, highlighted=ts, color=colors.transition_miss, color_highlight=colors.transition_hit, marker='o', markersize=10) # replot all symbols. currently active symbols will get a different color for i in range(len(symbols)): if i in current_symbols: ax.plot(symbols[i].coord[0], symbols[i].coord[1], '.', color=colors.symbol_hit, alpha=colors.symbol_hit_alpha) else: ax.plot(symbols[i].coord[0], symbols[i].coord[1], '.', color=colors.symbol_miss, alpha=colors.symbol_miss_alpha) # predict next batch of symbols, and remove currently active ones next_symbols = layer.expand(current_symbols, symbols, ticks) current_symbols = [ s for s in next_symbols if s not in current_symbols and symbols[s].retrieval_tick < 0 ] ax.set_xlim([-0.15, W + .15]) ax.set_ylim([-0.1, 0.1]) ax.set_aspect('equal') # drawing plt.title("tick %i" % (ticks)) plt.draw() if live_plot: plt.pause(0.1) fig.savefig("{}/{:03}.svg".format(output_dir, ticks)) # update tick counter ticks += 1 # draw final state ax.clear() ts = layer.getDefinedTransitions(current_symbols) layer.plot_with_highlight(ax, symbols, highlighted=ts, color=colors.transition_miss, color_highlight=colors.transition_hit, marker='o', markersize=10) # replot all symbols. currently active symbols will get a different color for i in range(len(symbols)): if i in current_symbols: ax.plot(symbols[i].coord[0], symbols[i].coord[1], '.', color=colors.symbol_hit, alpha=colors.symbol_hit_alpha) else: ax.plot(symbols[i].coord[0], symbols[i].coord[1], '.', color=colors.symbol_miss, alpha=colors.symbol_miss_alpha) ax.set_xlim([-0.15, W + .15]) ax.set_ylim([-0.1, 0.1]) ax.set_aspect('equal') plt.title("tick %i" % (ticks)) plt.draw() if live_plot: plt.pause(0.1) fig.savefig("{}/{:03}.svg".format(output_dir, ticks)) if live_plot: plt.ioff() plt.show() return ticks
def main(args): # get a string for this simulation and generate the directory global DEMO_NAME dir_str = "{}/{}_{}.d".format(args.output_dir, DEMO_NAME, args.pointgen) if args.save_figures: print("Saving figures to directory {}".format(dir_str)) if not os.path.exists(dir_str): os.mkdir(dir_str) # grid periods to use in this demo periods = [0.2] for i in range(1, args.nscales): periods.append(periods[-1] * np.sqrt(2)) # generate symbols print("Generating symbols.") nscales = len(periods) mindist = periods[0] / 4 if args.pointgen == 'hammersley': symbols = utils.gen_symbols(args.W, args.H, args.N, nscales=nscales) else: symbols = utils.gen_symbols(args.W, args.H, N=args.N, nscales=nscales, method='rmind1', mindist=mindist) # create transition layers and associate each with all available symbols print("Generating transition layers") z = 0 layers = [] for period in periods: print("Generating layer {} of {}".format(z + 1, len(periods))) layers.append( modules.TransitionLayer(period, args.W, args.H, pointgen.hex)) layers[-1].associate(symbols, len(layers) - 1) z += 1 # select desired start and target symbols global_start, _ = utils.get_closest_symbol( symbols, np.array([args.startX, args.startY])) global_target, _ = utils.get_closest_symbol( symbols, np.array([args.targetX, args.targetY])) ## ## Algorithm start ################################################################# ## print("Running algorithm.") recorder = utils.Recorder(nscales) find_sequence(layers, periods, symbols, global_start, global_target, args, recorder) print("Done.") ## ## Algorithm end ################################################################## ## # plot that only shows the transition centers fig, axs = plotter.setup(args, len(periods), ion=False) for scale in range(args.nscales): # exploit the symbol plotter here plotter.rectangular_scene(axs[scale], args.W, args.H) plotter.symbols(axs[scale], layers[scale].ts, range(len(layers[scale].ts))) plt.draw() if args.save_figures: fig.savefig("{}/transition_centers.svg".format(dir_str)) plt.show() # plotting fig, axs = plotter.setup(args, len(periods), ion=False) for ax in axs: plotter.rectangular_scene(ax, args.W, args.H) plotter.symbols(ax, symbols, []) # global start and target plotter.start_target(ax, symbols, [global_start], [global_target]) scale = nscales - 1 while scale >= 0: # select axes to plot to ax = axs[nscales - scale - 1] # subgoals plotter.subgoals(ax, symbols, recorder.searches[scale][-1].targets) ts = [] for b in recorder.backtracks[scale]: # symbol's associated transition for s in b.ss: t = utils.get_transition_obj(layers, symbols, scale, s) ts.append(t) ts = list(set(ts)) for t in ts: plotter.transition_domain(ax, t, periods[scale]) # plot initial transition area ts = [] b = recorder.backtracks[scale][-1] for s in b.ps: t = utils.get_transition_obj(layers, symbols, scale, s) ts.append(t) ts = list(set(ts)) for t in ts: # tmp_colors = utils.Config() # tmp_colors.transition = 'green' plotter.transition_domain(ax, t, periods[scale]) scale -= 1 plt.draw() if args.save_figures: fig.savefig("{}/results.svg".format(dir_str)) plt.show()
def main(args): # get a string for this simulation and generate the directory global DEMO_NAME # grid periods to use in this demo periods = [0.2] for i in range(1, args.nscales): periods.append(periods[-1] * np.sqrt(2)) dir_str = "{}/{}_{}.d".format(args.output_dir, DEMO_NAME, args.pointgen) if args.save_figures: print("Saving figures to directory {}".format(dir_str)) if not os.path.exists(dir_str): os.mkdir(dir_str) # generate symbols print("Generating symbols.") nscales = len(periods) mindist = periods[0] / 4 if args.pointgen == 'hammersley': symbols = utils.gen_symbols(args.W, args.H, args.N, nscales=nscales) else: symbols = utils.gen_symbols(args.W, args.H, N=args.N, nscales=nscales, method='rmind1', mindist=mindist) # create transition layers and associate each with all available symbols print("Generating transition layers") z = 0 layers = [] for period in periods: print("Generating layer {} of {}".format(z + 1, len(periods))) layers.append( modules.TransitionLayer(period, args.W, args.H, pointgen.hex)) layers[-1].associate(symbols, len(layers) - 1) z += 1 # select desired start and target symbols global_start, _ = utils.get_closest_symbol( symbols, np.array([args.startX, args.startY])) global_target, _ = utils.get_closest_symbol( symbols, np.array([args.targetX, args.targetY])) ## ## Algorithm start ################################################################# ## print("Running algorithm.") recorder = utils.Recorder(nscales) find_sequence(layers, periods, symbols, global_start, global_target, args, recorder) print("Done.") ## ## Algorithm end ################################################################## ## # plot that only shows the transition centers fig, axs = plotter.setup(args, len(periods), ion=False) for scale in range(args.nscales): # exploit the symbol plotter here plotter.rectangular_scene(axs[scale], args.W, args.H) plotter.symbols(axs[scale], layers[scale].ts, range(len(layers[scale].ts))) plt.draw() if args.save_figures: fig.savefig("{}/transition_centers.svg".format(dir_str)) plt.show() # plotting results fig, axs = plotter.setup(args, len(periods), ion=False) for ax in axs: plotter.rectangular_scene(ax, args.W, args.H) plotter.symbols(ax, symbols, range(len(symbols))) # global start and target plotter.start_target(ax, symbols, [global_start], [global_target]) scale = nscales - 1 while scale >= 0: col_tmp = utils.Config() col_tmp.active = 'red' ts = [] for e in recorder.expansions[scale]: plotter.symbols(axs[scale], symbols, e.active_symbols, only_active=False) for s in e.active_symbols: ts.append(layers[scale].ts[symbols[s].t[scale]]) ts = list(set(ts)) for t in ts: plotter.transition_domain(axs[scale], t, periods[scale]) scale -= 1 # find a few samples # MonteCarloSamples = [list() for n in range(nscales)] print("Monte Carlo sampling.") for i in range(args.M): # backtracking ala Dijkstra p = symbols[global_target] s = symbols[global_target] while not (s == symbols[global_start]): p = symbols[p.getRandomParent()] plotter.sample_segment(axs[-1], s, p) s = p plt.draw() if args.save_figures: fig.savefig("{}/results.svg".format(dir_str)) plt.show()
def main(args): global DEMO_NAME # get a string for this simulation and generate the directory dir_str = "{}/{}_{}_{:4.2f}.d".format(args.output_dir, DEMO_NAME, args.pointgen, args.period) if args.save_figures: print("Saving figures to directory {}".format(dir_str)) if not os.path.exists(dir_str): os.mkdir(dir_str) # generate symbols print("Generating symbols.") mindist = 0.02 if args.pointgen == 'hammersley': symbols = utils.gen_symbols(args.W, args.H, args.N) else: symbols = utils.gen_symbols(args.W, args.H, N=args.N, method='rmind1', mindist=mindist) # create transition layer and associate it with all available symbols print("Creating layer.") layers = [] layers.append( modules.TransitionLayer(args.period, args.W, args.H, pointgen.hex)) layers[0].associate(symbols) # select some random symbols start, _ = utils.get_closest_symbol(symbols, np.array([args.startX, args.startY])) target, _ = utils.get_closest_symbol( symbols, np.array([args.targetX, args.targetY])) # initialize the symbols current_symbols = [start] # plotting setup fig, ax = plotter.setup(args, 1, figsize=(4, 4)) ax = ax[0] ax.axis('off') # pure retrieval to target target_found = False tick = 0 print("Running algorithm.") while tick <= args.maxticks: ax.clear() ax.axis('off') # update 'retrieval tick' -> this emulates refractory periods of place # cells. This comes from marking symbols as "expanded" for s in current_symbols: symbols[s].retrieval_tick = tick # plotting plotter.everything(args, ax, symbols, current_symbols, start, target) if args.save_figures: fig.savefig("{}/{:03}.svg".format(dir_str, tick)) # predict next batch of symbols, and remove currently active ones next_symbols = layers[0].expand(current_symbols, symbols, tick) current_symbols = [ s for s in next_symbols if s not in current_symbols and symbols[s].retrieval_tick < 0 ] # update time tick += 1 # check to see if we reached the destination target_found = target in current_symbols if target_found: break print("Done.") if not target_found: print("EE: Target not found") plotter.everything(args, ax, symbols, current_symbols, start, target) plt.draw() if target_found: print("Generating Monte Carlo samples") # get some monte carlo samples for i in range(args.M): # backtracking ala Dijkstra p = symbols[target] s = symbols[target] while not (s == symbols[start]): p = symbols[p.getRandomParent()] plotter.sample_segment(ax, s, p) s = p # plot the transition regions using a backtracking sample ala Dijkstra ts = [] p = symbols[target] s = symbols[target] ts.append(layers[0].ts[p.t[0]]) while not (s == symbols[start]): p = symbols[p.getRandomParent()] ts.append(layers[0].ts[p.t[0]]) s = p for t in ts: plotter.transition_domain(ax, t, args.period) plt.ioff() if args.save_figures: fig.savefig("{}/{:03}.svg".format(dir_str, tick)) plt.show()