def run(self): self.p = self.init_p self.theta = self.init_theta self.pidx_vect = np.zeros((self.walk_steps), dtype=np.int32) progress_clock = clock() snap_idx = 0 num_snaps = 2000 delta_snap = self.walk_steps / num_snaps self.speed_vect = np.zeros(num_snaps) for step_idx in xrange(self.walk_steps): if self.variable_speed is True: self.update_speed() self.update_position() if np.remainder(step_idx, delta_snap) == 0: if snap_idx < num_snaps: self.speed_vect[snap_idx] = self.current_speed print_progress(snap_idx, num_snaps, progress_clock) snap_idx += 1 pidx = get_pos_idx(self.p, self.pos) self.pidx_vect[step_idx] = pidx
def gen_inputs_bvc(self): """ Generates Boundary Vector Cell inputs """ d_ran=np.linspace(0.1,self.L/2.,num=self.n,endpoint=False) phi_ran=np.linspace(0,2*np.pi,num=self.n,endpoint=False) # standard deviation of the gaussian as a function of distance sigma_rad = lambda d: (d/self.beta+1)*self.sigma_rad_0 # boundary vector field, i.e., the blob bvf= lambda p_dist,p_ang,d,phi: np.exp(-(p_dist-d)**2/(2*sigma_rad(d)**2))/(np.sqrt(2*np.pi)*sigma_rad(d)) *\ np.exp(-(np.remainder((p_ang-phi),2*np.pi)-np.pi)**2/(2*self.sigma_ang**2))/(np.sqrt(2*np.pi)*self.sigma_ang) # position of the walls east_wall=np.where(self.pos[:,0]==self.X.min())[0] west_wall=np.where(self.pos[:,0]==self.X.max())[0] north_wall=np.where(self.pos[:,1]==self.Y.max())[0] south_wall=np.where(self.pos[:,1]==self.Y.min())[0] wall_pos=np.hstack([east_wall,west_wall,north_wall,south_wall]) num_walls=4 pos_shift=self.pos[np.newaxis,:,:] p_wall_shift=self.pos[wall_pos,:][:,np.newaxis,:]-pos_shift p_wall_shift=p_wall_shift.reshape(self.nx*num_walls*self.nx**2,2) p_wall_dist=np.sqrt(np.sum(p_wall_shift**2,axis=1)) p_wall_ang=np.arctan2(p_wall_shift[:,1],p_wall_shift[:,0]) #p_dist=sqrt(np.sum(self.pos**2,axis=1)) #p_ang=arctan2(self.pos[:,1],self.pos[:,0]) self.inputs_flat=np.zeros((self.nx**2,self.N),dtype=np.float32) #self.blobs_flat=zeros((self.nx**2,self.N),dtype=float32) start_clock=clock() idx=0 for d in d_ran: for phi in phi_ran: print_progress(idx,self.N,start_clock=start_clock) self.inputs_flat[:,idx]=np.mean(bvf(p_wall_dist,p_wall_ang,d,phi).reshape(self.nx*num_walls,self.nx**2),axis=0) #self.blobs_flat[:,idx]=bvf(p_dist,p_ang,d,phi) idx+=1 # scale to fixed mean self.input_scalings=self.input_mean/np.mean(self.inputs_flat,axis=0) self.inputs_flat*=self.input_scalings
def run(self): self.p = self.init_p #print self.p if self.sweep: self.p = np.array([-self.L / 2., self.L / 2.]) self.sweep_end = False elif self.run_in_circle: self.circle_angle = 0. self.p = np.array([self.circle_radius, 0.]) self.theta = self.init_theta self.pidx_vect = np.zeros((self.walk_steps), dtype=np.int32) progress_clock = time.time() snap_idx = 0 num_snaps = 100 delta_snap = self.walk_steps / num_snaps self.speed_vect = np.zeros(num_snaps) for step_idx in xrange(self.walk_steps): if self.variable_speed is True: self.update_speed() if self.sweep is True: if self.sweep_end: break else: self.update_position_sweep() elif self.run_in_circle is True: self.update_position_circle() else: self.update_position() if np.remainder(step_idx, delta_snap) == 0: if snap_idx < num_snaps: self.speed_vect[snap_idx] = self.current_speed print_progress(snap_idx, num_snaps, progress_clock) snap_idx += 1 pidx = get_pos_idx(self.p, self.pos) self.pidx_vect[step_idx] = pidx
def gridness_evo(M, dx, num_steps=50): """ Compute gridness evolution """ scores = [] spacings = [] assert (len(M.shape) == 3) num_snaps = M.shape[2] print 'Computing scores...' for idx in xrange(num_snaps): score, best_outr, orientation, spacing = gridness(M[:, :, idx], dx, computeAngle=False, doPlot=False, num_steps=num_steps) scores.append(score) spacings.append(spacing) print_progress(idx, num_snaps) return scores, spacings
def compute_scores_evo(J_vect, n, L, num_steps=50): """ Computes gridness scores for a matrix at different time points J_vect = N x num_snaps """ num_snaps = J_vect.shape[1] assert (J_vect.shape[0] == n**2) start_clock = clock() best_score = -1 scores = np.zeros(num_snaps) spacings = np.zeros(num_snaps) angles = np.zeros(num_snaps) phases = np.zeros((2, num_snaps)) for snap_idx in xrange(num_snaps): print_progress(snap_idx, num_snaps, start_clock=start_clock) J = J_vect[:, snap_idx] score, spacing, angle, phase = get_grid_params(J.reshape(n, n), L, n, num_steps=num_steps) best_score = max(best_score, score) scores[snap_idx] = score spacings[snap_idx] = spacing angles[snap_idx] = angle phases[:, snap_idx] = phase score_string = 'final_score: %.2f best_score: %.2f mean_score: %.2f\n' % ( score, best_score, np.mean(scores)) print score_string return scores, spacings, angles, phases
def run(self, do_print=False): # learning constants (k notation) self.k1 = self.B self.k2 = self.gamma * self.input_mean self.k3 = self.a # load correlation matrix corr = GridCorrSpace(self.initParamMap, do_print=do_print, force_gen_inputs=self.force_gen_inputs, force_gen_corr=self.force_gen_corr) self.C = corr.CC_teo self.m = diag(np.ones(self.N)) self.M = np.ones((self.N, self.N)) # dynamical system matrix self.A = self.C - self.m * self.k3 - self.M * self.k2 self.snap_idx = 0 self.r_out = self.r0 self.rout_av = self.r0 self.J = deepcopy(self.J0) self.dJ = np.zeros_like(self.J) self.J_vect = np.zeros((self.N, self.num_snaps)) self.dJ_vect = np.zeros((self.N, self.num_snaps)) self.r_out_vect = np.zeros(self.num_snaps) #### --------------- code to correct boundary effects code -------------- if self.correct_border_effects is True: centers = GridInputs(self.initParamMap).centers cx = centers[:, 0] cy = centers[:, 1] # distance to the center from x and y border dbx = self.L / 2 - np.array( [np.abs(cx - self.L / 2), np.abs(cx + self.L / 2)]).min(axis=0) dby = self.L / 2 - np.array( [np.abs(cy - self.L / 2), np.abs(cy + self.L / 2)]).min(axis=0) border_edge_smooth_fun = lambda x: np.cos(2 * np.pi * x / (4 * ( self.L / 2 - self.L / 2 * self.border_size_perc))) border_edge_sharp_fun = lambda x: 0. if self.border_edge_type is 'smooth': border_edge_fun = border_edge_smooth_fun else: border_edge_fun = border_edge_sharp_fun border_fun = np.vectorize( lambda x: 1. if x <= self.L / 2. * self.border_size_perc else border_edge_fun(x - self.L / 2. * self.border_size_perc)) self.border_envelope = border_fun(dbx).reshape( self.n, self.n) * border_fun(dby).reshape(self.n, self.n) self.border_envelope_flat = self.border_envelope.reshape(self.n**2) #--------------------------------------------- t = 0. # run the simulation for step_idx in xrange(self.num_sim_steps): t += self.dt # save variables if np.remainder(step_idx, self.delta_snap) == 0: print_progress(self.snap_idx, self.num_snaps, self.startClock) self.J_vect[:, self.snap_idx] = self.J self.dJ_vect[:, self.snap_idx] = self.dJ self.snap_idx += 1 self.dJ = (np.dot(self.A, self.J) + self.k1) if self.correct_border_effects is True: self.J += self.dt * self.eta * self.dJ * self.border_envelope_flat else: self.J += self.dt * self.eta * self.dJ self.J = np.clip(self.J, 0, self.up_bound)
def run(self): # initialize CC matrix CC_teo = np.zeros((self.N, self.N)) # analytical computation for periodic gaussians if self.compute_analytically is True: # choose the K filter function depending on the filter type (input or equivalent output) if self.filter_type == FilterType.FILTER_INPUT: K_t_fun = lambda t: K_t(self.b1, self.b2, self.b3, self.mu1, self.mu2, self.mu3, t) elif self.filter_type == FilterType.FILTER_OUTPUT: K_t_fun = lambda t: K_outeq_t(self.b_in, self.b_out, self. mu_out, t) # shorthand for the analytical correlation function corr_rate_short = lambda tau, u: corr_rate(K_t_fun, self.speed, self.sigma, tau, u) # compyute distance matrix CC_dist = np.zeros_like(CC_teo) if self.periodic_inputs is True: get_dist = get_periodic_dist else: get_dist = get_non_periodic_dist for i in xrange(self.N): for j in xrange(self.N): CC_dist[i, j] = get_dist(self.centers[i, :], self.centers[j, :], self.L) # fill in correlation value for each distance all_dist = np.unique(CC_dist.ravel()) for dist in all_dist: corr = np.pi * self.amp**2 * self.sigma**2 / self.L**2 * quad( corr_rate_short, 0., 2., args=(dist))[0] CC_teo[CC_dist == dist] = corr # numerical calculation for general inputs else: #pyfftw.interfaces.cache.enable() # compute DFTs #inputs_mat=pyfftw.empty_aligned((self.nx,self.nx,self.N), dtype='float32') #inputs_mat[:]=self.inputs_flat.reshape(self.nx,self.nx,self.N) inputs_mat = self.inputs_flat.reshape(self.nx, self.nx, self.N) inputs_dfts = fft2(inputs_mat, axes=[0, 1]) # binning for line integral center = np.array([self.nx, self.nx]) / 2 yr, xr = np.indices(([self.nx, self.nx])) r = np.around(np.sqrt((xr - center[0])**2 + (yr - center[1])**2)).astype(int) nr = np.bincount(r.ravel()) snap_idx = 0 prog_clock = clock() num_snaps = self.N * (self.N + 1) / 2 # loop over matric elements for i in xrange(self.N): input_i_dft = inputs_dfts[:, :, i] for j in xrange(i, self.N): print_progress(snap_idx, num_snaps, start_clock=prog_clock, step=num_snaps / 100) # get j-input input_j_dft = inputs_dfts[:, :, j] # inputs correlation dft_prod = input_i_dft * np.conj(input_j_dft) #dft_prod=pyfftw.empty_aligned((self.nx,self.nx), dtype='complex64') #dft_prod[:]=input_i_dft*np.conj(input_j_dft) input_corr = fftshift(np.real( ifft2(dft_prod))) * self.dx**2 # integral on a circle of radius tau count = np.bincount(r.ravel(), input_corr.ravel()) / nr corr_prof_teo = np.zeros(len(self.tau_ran)) corr_prof_teo[:self.nx / 2] = count[:self.nx / 2] # convolution with the filter CC_teo[i, j] = romb(self.K_samp * corr_prof_teo, dx=self.dx) snap_idx += 1 # normalize and fill upper triangle CC_teo /= self.L**2 CC_teo = CC_teo + CC_teo.T CC_teo[np.diag(np.ones(self.N).astype(bool))] *= 0.5 # normalize correlation matrix to equal mean at the boundary (additive approach) if self.periodic_inputs is False and hasattr( self, 'norm_bound_add') and self.norm_bound_add is True: print 'Correlation matrix boundary normalization (additive)' C4d = CC_teo.reshape(self.n, self.n, self.n, self.n) C4d_norm = np.zeros_like(C4d) mean_C = C4d.mean(axis=3).mean(axis=2) for i in xrange(self.n): for j in xrange(self.n): C4d_norm[i, j, :, :] = C4d[i, j, :, :] - mean_C[ i, j] + mean_C.min() C_norm = C4d_norm.reshape(self.N, self.N) CC_teo = C_norm # normalize correlation matrix to equal mean at the boundary (multiplicative approach) if self.periodic_inputs is False and hasattr( self, 'norm_bound_mul') and self.norm_bound_mul is True: print 'Correlation matrix boundary normalization (multiplicative)' C4d = CC_teo.reshape(self.n, self.n, self.n, self.n) C4d_norm = np.zeros_like(C4d) mean_C = C4d.mean(axis=3).mean(axis=2) for i in xrange(self.n): for j in xrange(self.n): C4d_norm[i, j, :, :] = C4d[i, j, :, :] / mean_C[ i, j] * mean_C.min() C_norm = C4d_norm.reshape(self.N, self.N) CC_teo = C_norm self.CC_teo = CC_teo self.eigs = eigvals(self.CC_teo)
def inner_run(self, num_steps, record=False, plastic=True): progress_clock = clock() t = 0 # run the simulation for step_idx in xrange(num_steps): t += self.dt # read out input activities at this time step if np.remainder(step_idx, self.position_dt_scale) == 0: # if we are at the end of the walk we start again if self.walk_step_idx >= self.walk_steps: self.walk_step_idx = 0 # read inputs at this walk step self.cur_pos_idx = self.pidx_vect[self.walk_step_idx] self.gg = self.inputs_flat[self.cur_pos_idx, :] # scale input to keep mean input constant when close to the boundaries #self.gg=self.gg/self.gg.mean()*self.input_mean self.walk_step_idx += 1 # total input and filtering self.h = np.dot(self.J, self.gg) self.r1 += self.b1 * self.dt * (self.mu1 * self.h - self.r1) self.r2 += self.b2 * self.dt * (self.mu2 * self.h - self.r2) self.r3 += self.b3 * self.dt * (self.mu3 * self.h - self.r3) self.r_out = self.r0 + self.r1 + self.r2 + self.r3 - self.gamma * self.J.sum( ) + self.boundary_input_flat[self.cur_pos_idx] if self.clip_out_rate is True: self.r_out = np.clip(self.r_out, 0, 1000) # in the last 4 snaps of the simulation record spatial rout if self.snap_idx >= self.num_snaps - 4: self.final_space_r_out[self.cur_pos_idx] += self.r_out self.final_space_visits[self.cur_pos_idx] += 1 # save variables if np.remainder(step_idx, self.delta_snap) == 0 and record is True: print_progress(self.snap_idx, self.num_snaps, progress_clock) self.J_vect[:, self.snap_idx] = self.J self.dJ_vect[:, self.snap_idx] = self.dJ self.r_out_vect[self.snap_idx] = self.r_out #self.tot_input_vect[self.snap_idx]=self.gg.mean() # save debugging variables if self.debug_vars is True: self.h_act_vect[self.snap_idx] = self.h_act self.h_inact_vect[self.snap_idx] = self.h_inact self.gg_vect[:, self.snap_idx] = self.gg self.snap_idx += 1 if plastic is True: # update weights self.dJ = self.gg * (self.r_out + self.beta - self.alpha * self.J) #self.dJ=self.r_out*(self.gg-self.r_out*self.J) # oja's rule self.J += self.dt * self.eta * self.dJ # clip weights if self.clip_weights is True: np.clip(self.J, 0., self.up_bound, out=self.J)
def __merge_and_save(self, outputs_to_merge, merge_functions={}, suffix='data'): """ outputs_to_merge is a list of attributes to be merged in a single output map Each output must be saved in the simulation results or a specific function for its computation must be provided in the merge_functions map (key is the output to compute, value is the function). The merge function takes as input the results data dictionary and outputs the value to be saved in the merged batch file. """ ############################################################################# ##### MERGE DATA ############################################################################# print 'Merging data...\n' sys.stdout.flush() data_list = [] start_clock = time.time() for idx, (chash, par_values) in enumerate( zip(self.hashes, self.all_par_values)): #print '%d/%d '%(idx,len(self.all_par_values)) sl.print_progress(idx, len(self.all_par_values), start_clock=start_clock, step=len(self.all_par_values) / 20.) sys.stdout.flush() try: dataPath = os.path.join( self.sim_class.results_path, '%s_%s_%s.npz' % (self.sim_class.__name__, chash, suffix)) data = np.load(dataPath, mmap_mode='r', allow_pickle=True) print 'Loading %s', dataPath except Exception: print 'error in loading: %s %s' % (str(par_values), chash) import traceback traceback.print_exc() return # construct a data record for the current combination of parameters record = {} ## add paramter values for idx, param_name in enumerate(self.batch_override_map.keys()): record[param_name] = par_values[idx] ## add output data to merge for output_name in outputs_to_merge: if output_name in data.keys(): record[output_name] = data[output_name] elif output_name in merge_functions.keys(): record[output_name] = merge_functions[output_name](data) else: raise Exception( 'Output to merge non present in archive and merge function not found.' ) data_list.append(record) # create data frame self.df = pd.DataFrame(data_list) # save sl.logSim(self.batch_hash, self.batch_override_str, self.startTimeStr, self.endTimeStr, self.elapsedTime, self.batch_default_map, self.batch_params_path, doPrint=False) self.save_dataframe()
def post_run(self): ############################################################################# ##### MERGE DATA ############################################################################# print print 'SIMULATIONS COMPLETED' print print 'Merging data...' sys.stdout.flush() initial_weights_map = {} final_weights_map = {} final_weight_score_map = {} final_weight_angle_map = {} final_weight_spacing_map = {} final_weight_phase_map = {} final_weight_cx_map = {} evo_weight_scores_map = {} final_rates_map = {} final_rate_score_map = {} final_rate_angle_map = {} final_rate_spacing_map = {} final_rate_phase_map = {} final_rate_cx_map = {} evo_weight_profiles_map = {} start_clock = time.time() # load/compute data to show for each combination of parameter_values idx = -1 for chash, par_values in zip(self.hashes, self.all_par_values): idx += 1 print_progress(idx, len(self.all_par_values), start_clock=start_clock) sys.stdout.flush() dataPath = os.path.join(self.sim_class.results_path, '%s_data.npz' % chash) try: data = np.load(dataPath, mmap_mode='r') except Exception: print 'This file is corrupted: %s' % dataPath initial_weights_map[par_values] = data['J0'] final_weights_map[par_values] = data['final_weights'] final_weight_score_map[par_values] = data['final_weight_score'] final_weight_angle_map[par_values] = data['final_weight_angle'] final_weight_spacing_map[par_values] = data['final_weight_spacing'] final_weight_phase_map[par_values] = data['final_weight_phase'] final_weight_cx_map[par_values] = data['final_weight_cx'] if 'scores' in data.keys(): evo_weight_scores_map[par_values] = data['scores'] final_rates_map[par_values] = data['final_rates'] final_rate_score_map[par_values] = data['final_rate_score'] final_rate_angle_map[par_values] = data['final_rate_angle'] final_rate_spacing_map[par_values] = data['final_rate_spacing'] final_rate_phase_map[par_values] = data['final_rate_phase'] final_rate_cx_map[par_values] = data['final_rate_cx'] # fourier profiles over time import gridlib as gl L = data['paramMap'][()]['L'] n = data['paramMap'][()]['n'] num_snaps = self.batch_default_map['num_snaps'] J_mat = data['J_vect'].reshape(n, n, num_snaps) weights_dft, weights_freqs, weigths_allfreqs = gl.dft2d_num( J_mat, L, n) weights_dft_profiles = gl.dft2d_profiles(weights_dft) evo_weight_profiles_map[par_values] = weights_dft_profiles mergedDataMap = { 'initial_weights_map': initial_weights_map, 'final_weights_map': final_weights_map, 'final_weight_score_map': final_weight_score_map, 'final_weight_angle_map': final_weight_angle_map, 'final_weight_spacing_map': final_weight_spacing_map, 'final_weight_phase_map': final_weight_phase_map, 'final_weight_cx_map': final_weight_cx_map, 'evo_weight_scores_map': evo_weight_scores_map, 'final_rates_map': final_rates_map, 'final_rate_score_map': final_rate_score_map, 'final_rate_angle_map': final_rate_angle_map, 'final_rate_spacing_map': final_rate_spacing_map, 'final_rate_phase_map': final_rate_phase_map, 'final_rate_cx_map': final_rate_cx_map, 'evo_weight_profiles_map': evo_weight_profiles_map, 'weights_freqs': weights_freqs } self.toSaveMap = map_merge(self.toSaveMap, mergedDataMap) # save ensureParentDir(self.batch_data_path) logSim(self.batch_hash, self.batch_override_str, self.startTimeStr, self.endTimeStr, self.elapsedTime, self.batch_default_map, self.batch_params_path, doPrint=False) print print 'BATCH HASH: %s' % self.batch_hash np.savez(self.batch_data_path, **self.toSaveMap) print print 'Batch data saved in: %s\n' % self.batch_data_path print