def profiles_to_lattices(uniq_corner_arang, stencils): stencil_ind = [] for s in stencils: filled_ind = np.array(np.where(np.array(s) == 1)).T # relocate to corner filled_ind_reloc = filled_ind - 1 # flip vertically filled_ind_flpd = np.flip(filled_ind_reloc, 0).astype(int) stencil_ind.append(filled_ind_flpd) # print(stencil_ind) ###################### # generate mini-lattices to represent the geometrical equivalent of unique corner arrangments base_zero = np.zeros((2, 2, 2), dtype=np.int8) corner_neigh_lattices = [] corner_loc_lattices = [] # for each unique arangement, create a representation for uca in uniq_corner_arang: corner_arang = np.copy(base_zero) corner_loc = np.copy(base_zero) corner_loc[0, 0, 0] = 1 shift = np.zeros(3) # for each list of indices of each stencil for i, s_inds in enumerate(stencil_ind): # for each index for j, s_i in enumerate(s_inds): # check if the sum is big enough to mark this index if uca[i] > j: # check if the index is positive if s_i.sum() >= 0: # mark as one corner_arang[tuple(s_i)] = 1 # if the index is negative else: # mark as one corner_arang[tuple(s_i)] = 1 # record the index as a shift shift += s_i # roll neighbourhood and locations corner_arang = np.roll(corner_arang, tuple(shift.astype(int)), (0, 1, 2)) corner_loc = np.roll(corner_loc, tuple(shift.astype(int)), (0, 1, 2)) # convert to lattice corner_lat = tg.to_lattice(corner_arang, np.zeros(3)) corner_neigh_lattices.append(corner_lat) corner_loc_lat = tg.to_lattice(corner_loc, np.zeros(3)) corner_loc_lattices.append(corner_loc_lat) return (corner_loc_lattices, corner_neigh_lattices)
def bhv_find_neighbour(self, stencil_name: str, env: environment, return_counts=False, return_neigh_ind=False): all_neighs = env.neigh_matrices[stencil_name] agn_neighs = all_neighs[np.where(np.array( self.occ_lattice).flatten())].flatten() neighbourhood_flat = self.occ_lattice.flatten() * 0 # all_neighbours = env.neigh_matrix[np.where(np.array(self.occ_lattice).flatten())].reshape(tuple([-1] + list(self.occ_lattice.shape))).sum(0) if return_counts: unq_neighs, unq_counts = np.unique(agn_neighs, return_counts=True) neighbourhood_flat[unq_neighs] = unq_counts else: neighbourhood_flat[agn_neighs] = 1 neighbourhood = tg.to_lattice( neighbourhood_flat.reshape(self.occ_lattice.shape), self.occ_lattice) if return_neigh_ind: if return_neigh_ind == "1D": indices_1d = np.argwhere(neighbourhood_flat > 0) return (neighbourhood, indices_1d) elif return_neigh_ind == "3D": indices_3d = np.argwhere(neighbourhood > 0) return (neighbourhood, indices_3d) else: return neighbourhood
def evaluation(self, env: environment): eval_lattice = tg.to_lattice(np.ones(env.avail_lattice.shape), env.avail_lattice.shape) for lat_name, lat in env.lattices.items(): eval_lattice *= lat.astype( float)**self.preferences[lat_name]["weight"] self.eval_lat = eval_lattice
def bi_cube_lattices(): # create all possible configurations l_bis = [] for i in range(2**8): bi = np.array(list(np.binary_repr(i, width=8))).astype(int).reshape( (2, 2, 2)) l_bi = tg.to_lattice(bi, [0, 0, 0]) l_bis.append(l_bi) return l_bis
def save_design_templates(corner_loc_lattices, corner_neigh_lattices, templates_path): interior_zero = tg.to_lattice(np.zeros((2, 2, 2), dtype=np.int8), [0, 0, 0]) border_pad = np.pad(interior_zero, (1, 1), 'constant', constant_values=(1)) base_zero = tg.to_lattice(np.zeros((4, 4, 4), dtype=np.int8), [0, 0, 0]) s = tg.create_stencil("von_neumann", 1, 1) s.set_index([0, 0, 0], 0) for i, core, neigh in zip(range(len(corner_loc_lattices)), corner_loc_lattices, corner_neigh_lattices): # construct saving paths core_path = os.path.join(templates_path, 'core_' + f'{i:02}' + '.csv') neigh_path = os.path.join(templates_path, 'neighs_' + f'{i:02}' + '.csv') e_neigh_path = os.path.join(templates_path, 'e_neighs_' + f'{i:02}' + '.csv') # aggregate neighbours neigh = tg.to_lattice( np.pad(neigh, (1, 1), 'constant', constant_values=(0)), [0, 0, 0]) # construct the padded core core_pad = tg.to_lattice( np.pad(core, (1, 1), 'constant', constant_values=(0)), [0, 0, 0]) # extract the outer neighbours of the core core_3ind = np.array(np.where(core_pad == 1)).flatten() pals = base_zero.find_neighbours_masked(s, loc=core_3ind) extra_neighs = np.copy(base_zero).flatten() # set the extra neighbours as the current state of the core extra_neighs[pals] = neigh[tuple(core_3ind)] extra_neighs = tg.to_lattice(extra_neighs.reshape((4, 4, 4)), [0, 0, 0]) # remove interior pals extra_neighs *= border_pad # save to csv to_csv(core_pad, core_path) to_csv(neigh, neigh_path) to_csv(extra_neighs, e_neigh_path)
def reshape_and_store_to_lattice(values_list, envelope_lattice): env_all_vox_id = envelope_lattice.indices.flatten() env_all_vox = envelope_lattice.flatten() # envelope inclusion condition: True-False env_in_vox_id = env_all_vox_id[env_all_vox] # keep in-envelope voxels (True) # initialize array values_array = np.full(env_all_vox.shape, 0.0) # store values for the in-envelope voxels values_array[env_in_vox_id] = values_list # reshape to lattice shape values_array_3d = values_array.reshape(envelope_lattice.shape) # convert to lattice values_lattice = tg.to_lattice(values_array_3d, envelope_lattice) return values_lattice
def lattice_from_csv(file_path): # read metadata meta_df = pd.read_csv(file_path, nrows=3) shape = np.array(meta_df['shape']) unit = np.array(meta_df['unit']) minbound = np.array(meta_df['minbound']) # read lattice lattice_df = pd.read_csv(file_path, skiprows=5) print(lattice_df) # create the buffer buffer = np.array(lattice_df['value']).reshape(shape) # create the lattice l = tg.to_lattice(buffer, minbound=minbound, unit=unit) return l
for a in self.agents: a.walk(self) # update the agent states in environment self.update_agents() # construct a dummy value field ############################### # create a series of sin values for 0 to pi sin_a = np.sin(np.arange(lattice_size+1) / float(lattice_size) * np.pi).astype(np.float16) # compute the outer product of the series with itself to create a radial value field myvalue_2d_field = np.outer(sin_a,sin_a) # add extra dimension to array to make it comaptible with lattices myvalue_field = myvalue_2d_field[:, :, None] * sin_a[None, None, :] # construct the lattice myvalue_lattice = tg.to_lattice(myvalue_field, np.array([0,0,0])) # initiate the environment env_lattices = {"availibility": avail_lattice, "myvalue": myvalue_lattice} env = environment(env_lattices, agents) # main simulation agent_history = [] for i in range(max_iteration): # print(env.availibility) # print(env.agent_origin) agn_org = [a.origin for a in env.agents] agent_history.append(np.array(agn_org).tolist()) env.walk_agents()
import topogenesis as tg lattices = [] # normalization loop for values in lattice_values: # convert to numpy array a_values = np.array(values) # normalization of values max_values = np.max(a_values) min_values = np.min(a_values) normalized_values = (a_values - min_values) / (max_values - min_values) # convert to lattice norm_shaped_values = normalized_values.reshape(lattice_shape) lattice = tg.to_lattice(norm_shaped_values, np.array([0, 0, 0])) lattices.append(lattice) # normalize weights weights = np.array(lattice_weights) weights /= np.sum(weights) ''' The aggregation algorithm is based on Fuzzy Logics framework that is introduced, and generalized in Pirouz Nourian dissertation: section 5.7.3, pp. 201-208, eq. 57 you can refer to it like this: P. Nourian, “Configraphics: Graph Theoretical Methods for Design and Analysis of Spatial Configurations,” Doi.Org, vol. 6, no. 14. pp. 1–348, 2016, url. ISBN-13 15) 978-94-6186-720-9 ''' # initialize the aggregated lattice agg_lattice = lattices[0] * 0 + 1
[[[0 0 0] [0 1 0] [0 0 0]] [[0 1 0] [1 1 1] [0 1 0]] [[0 0 0] [0 1 0] [0 0 0]]] """ # initialize a 2d lattice with random values r = np.random.rand(1, 5, 5) l_vals = tg.to_lattice(r, [0, 0, 0]) """ print(l_vals) [[[0.5488135 0.71518937 0.60276338 0.54488318 0.4236548 ] [0.64589411 0.43758721 0.891773 0.96366276 0.38344152] [0.79172504 0.52889492 0.56804456 0.92559664 0.07103606] [0.0871293 0.0202184 0.83261985 0.77815675 0.87001215] [0.97861834 0.79915856 0.46147936 0.78052918 0.11827443]]] """ # initialize walkers lattice z = np.zeros((1, 5, 5)) l_walk = tg.to_lattice(z, [0, 0, 0]) l_walk[0, 2, 2] += 1 """ print(l_walk)