def grow_bundles(self): """ Update an estimate of co-activity between all cables. """ # Incrementally accumulate agglomeration energy. nb.agglomeration_energy_gather( self.bundle_activities, self.cable_activities, self.n_bundles, self.agglomeration_energy, self.agglomeration_mask, ) max_energy, i_bundle, i_cable = nb.max_2d(self.agglomeration_energy) # Add a new bundle if appropriate if max_energy > self.agglomeration_threshold: # Add the new bundle to the end of the list. i_new_bundle = self.n_bundles self.increment_n_bundles() # Make a copy of the growing bundle. self.mapping[:, i_new_bundle] = self.mapping[:, i_bundle] # self.bundle_to_cable_mapping.append( # self.bundle_to_cable_mapping[i_bundle]) # Add in the new cable. # self.bundle_to_cable_mapping[i_new_bundle].append(i_cable) self.mapping[i_cable, i_bundle] = 1 # Update the contributing cables. # for i_cable in self.bundle_to_cable_mapping[i_new_bundle]: # self.cable_to_bundle_mapping[i_cable].append(i_new_bundle) # Reset the accumulated nucleation and agglomeration energy # for the two cables involved. self.nucleation_energy[i_cable, :] = 0 self.nucleation_energy[i_cable, :] = 0 self.nucleation_energy[:, i_cable] = 0 self.nucleation_energy[:, i_cable] = 0 self.agglomeration_energy[:, i_cable] = 0 self.agglomeration_energy[i_bundle, :] = 0 # Update agglomeration_mask to account for the new bundle. # The new bundle should not accumulate agglomeration energy with # 1) the cables that its constituent cable # are blocked from nucleating with or # 2) the cables that its constituent bundle # are blocked from agglomerating with. blocked_cable = np.where(self.nucleation_mask[i_cable, :] == 0) blocked_bundle = np.where( self.agglomeration_mask[i_bundle, :] == 0) blocked = np.union1d(blocked_cable[0], blocked_bundle[0]) self.agglomeration_mask[i_new_bundle, blocked] = 0 # if self.debug: if False: logger.debug(' '.join([ ' ', self.name, 'bundle', str(i_new_bundle), 'added: bundle', str(i_bundle), 'and cable', str(i_cable) ]))
def _grow_bundles(self, masked_cable_activities): """ Update an estimate of co-activity between all cables. """ # Incrementally accumulate agglomeration energy. #nb.agglomeration_energy_gather(self.bundle_activities, # self.nonbundle_activities, # self.num_bundles, # self.agglomeration_energy) #nb.agglomeration_energy_gather(self.bundle_activities, # self.cable_activities, # self.num_bundles, # self.agglomeration_energy) nb.agglomeration_energy_gather(self.bundle_activities, masked_cable_activities, self.num_bundles, self.agglomeration_energy) # Don't accumulate agglomeration energy between cables already # in the same bundle val = 0. if self.n_map_entries > 0: nb.set_dense_val(self.agglomeration_energy, self.bundle_map_rows[:self.n_map_entries], self.bundle_map_cols[:self.n_map_entries], val) results = -np.ones(3) nb.max_dense(self.agglomeration_energy, results) max_energy = results[0] cable_index = int(results[2]) bundle_index = int(results[1]) # Add a new bundle if appropriate if max_energy > self.agglomeration_threshold: # Find which cables are in the new bundle. cables = [cable_index] for i in range(self.n_map_entries): if self.bundle_map_rows[i] == bundle_index: cables.append(self.bundle_map_cols[i]) # Check whether the agglomeration is already in the bundle map. candidate_bundles = np.arange(self.num_bundles) for cable in cables: matches = np.where(self.bundle_map_cols == cable)[0] candidate_bundles = np.intersect1d( candidate_bundles, self.bundle_map_rows[matches], assume_unique=True) if candidate_bundles.size != 0: # The agglomeration has already been used to create a # bundle. Ignore and reset they count. This can happen # under normal circumstances, because of how nonbundle # activities are calculated. self.agglomeration_energy[bundle_index, cable_index] = 0. return # Make a copy of the growing bundle. for i in range(self.n_map_entries): if self.bundle_map_rows[i] == bundle_index: self.bundle_map_rows[self.n_map_entries] = self.num_bundles self.bundle_map_cols[self.n_map_entries] = ( self.bundle_map_cols[i]) self.increment_n_map_entries() # Add in the new cable. self.bundle_map_rows[self.n_map_entries] = self.num_bundles self.bundle_map_cols[self.n_map_entries] = cable_index self.increment_n_map_entries() self.num_bundles += 1 if self.debug: print(' '.join([ ' ', self.name, 'bundle', str(self.num_bundles), 'added: bundle', str(bundle_index), 'and cable', str(cable_index) ])) # Check whether the Ziptie's capacity has been reached. if self.num_bundles == self.max_num_bundles: self.bundles_full = True # Reset the accumulated nucleation and agglomeration energy # for the two cables involved. self.nucleation_energy[cable_index, :] = 0. self.nucleation_energy[cable_index, :] = 0. self.nucleation_energy[:, cable_index] = 0. self.nucleation_energy[:, cable_index] = 0. self.agglomeration_energy[:, cable_index] = 0. self.agglomeration_energy[bundle_index, :] = 0.
def _grow_bundles(self): """ Update an estimate of co-activity between all cables. """ # Incrementally accumulate agglomeration energy. nb.agglomeration_energy_gather(self.bundle_activities, self.nonbundle_activities, self.num_bundles, self.agglomeration_energy) # Don't accumulate agglomeration energy between cables already # in the same bundle val = 0. if self.n_map_entries > 0: nb.set_dense_val(self.agglomeration_energy, self.bundle_map_rows[:self.n_map_entries], self.bundle_map_cols[:self.n_map_entries], val) results = -np.ones(3) nb.max_dense(self.agglomeration_energy, results) max_energy = results[0] cable_index = int(results[2]) bundle_index = int(results[1]) # Add a new bundle if appropriate if max_energy > self.agglomeration_threshold: # Find which cables are in the new bundle. cables = [cable_index] for i in range(self.n_map_entries): if self.bundle_map_rows[i] == bundle_index: cables.append(self.bundle_map_cols[i]) # Check whether the agglomeration is already in the bundle map. candidate_bundles = np.arange(self.num_bundles) for cable in cables: matches = np.where(self.bundle_map_cols == cable)[0] candidate_bundles = np.intersect1d( candidate_bundles, self.bundle_map_rows[matches], assume_unique=True) if candidate_bundles.size != 0: # The agglomeration has already been used to create a # bundle. Ignore and reset they count. This can happen # under normal circumstances, because of how nonbundle # activities are calculated. self.agglomeration_energy[bundle_index, cable_index] = 0. return # Make a copy of the growing bundle. for i in range(self.n_map_entries): if self.bundle_map_rows[i] == bundle_index: self.bundle_map_rows[self.n_map_entries] = self.num_bundles self.bundle_map_cols[self.n_map_entries] = ( self.bundle_map_cols[i]) self.increment_n_map_entries() # Add in the new cable. self.bundle_map_rows[self.n_map_entries] = self.num_bundles self.bundle_map_cols[self.n_map_entries] = cable_index self.increment_n_map_entries() self.num_bundles += 1 print(' '.join([' ', self.name, 'bundle', str(self.num_bundles), 'added: bundle', str(bundle_index), 'and cable', str(cable_index)])) # Check whether the ``ZipTie``'s capacity has been reached. if self.num_bundles == self.max_num_bundles: self.bundles_full = True # Reset the accumulated nucleation and agglomeration energy # for the two cables involved. self.nucleation_energy[cable_index, :] = 0. self.nucleation_energy[cable_index, :] = 0. self.nucleation_energy[:, cable_index] = 0. self.nucleation_energy[:, cable_index] = 0. self.agglomeration_energy[:, cable_index] = 0. self.agglomeration_energy[bundle_index, :] = 0.