def _deep_copy_element(self, element, variable, current_depth, max_depth): if current_depth >= max_depth: if variable in element.prime.vtree.variables: copied_element = AndGate( self._deep_copy_node(element.prime, variable, current_depth, max_depth), element.sub, copy.deepcopy(element.parameter), ) elif variable in element.sub.vtree.variables: copied_element = AndGate( element.prime, self._deep_copy_node(element.sub, variable, current_depth, max_depth), copy.deepcopy(element.parameter), ) else: copied_element = AndGate(element.prime, element.sub, copy.deepcopy(element.parameter)) else: copied_element = AndGate( self._deep_copy_node(element.prime, variable, current_depth, max_depth), self._deep_copy_node(element.sub, variable, current_depth, max_depth), copy.deepcopy(element.parameter), ) copied_element.splittable_variables = copy.deepcopy( element.splittable_variables) return copied_element
def _copy_and_modify_element_for_split(self, original_element, variable, current_depth, max_depth): original_element.flag = True original_element.remove_splittable_variable(variable) original_prime = original_element.prime original_sub = original_element.sub if current_depth >= max_depth: if variable in original_prime.vtree.variables: original_prime, copied_prime = self._copy_and_modify_node_for_split( original_prime, variable, current_depth, max_depth) copied_sub = original_sub elif variable in original_sub.vtree.variables: original_sub, copied_sub = self._copy_and_modify_node_for_split( original_sub, variable, current_depth, max_depth) copied_prime = original_prime else: copied_prime = original_prime copied_sub = original_sub else: original_prime, copied_prime = self._copy_and_modify_node_for_split( original_prime, variable, current_depth, max_depth) original_sub, copied_sub = self._copy_and_modify_node_for_split( original_sub, variable, current_depth, max_depth) if copied_prime is not None and copied_sub is not None: copied_element = AndGate(copied_prime, copied_sub, copy.deepcopy(original_element.parameter)) copied_element.splittable_variables = copy.deepcopy( original_element.splittable_variables) else: copied_element = None if original_prime is not None and original_sub is not None: original_element.prime = original_prime original_element.sub = original_sub else: original_element = None return original_element, copied_element
def _new_logistic_psdd(self, vtree) -> CircuitNode: left_vtree = vtree.left right_vtree = vtree.right prime_variable = left_vtree.var sub_variable = right_vtree.var if left_vtree.is_leaf(): left_node = self._precreated_terminal_nodes[prime_variable - 1] else: left_node = self._new_logistic_psdd(left_vtree) if right_vtree.is_leaf(): right_node = self._precreated_terminal_nodes[sub_variable - 1] else: right_node = self._new_logistic_psdd(right_vtree) elements = [ AndGate(left_node, right_node, np.random.random_sample(size=(self._num_classes, ))) ] elements[0].splittable_variables = copy.deepcopy(vtree.variables) root = OrGate(self._largest_index, vtree, elements) self._largest_index += 1 return root
def load(self, f): # read the format at the beginning line = f.readline() while line[0] == "c": line = f.readline() # serialize the vtree vtree_nodes = dict() unvisited_vtree_nodes = deque() unvisited_vtree_nodes.append(self._vtree) while len(unvisited_vtree_nodes): node = unvisited_vtree_nodes.popleft() vtree_nodes[node.index] = node if not node.is_leaf(): unvisited_vtree_nodes.append(node.left) unvisited_vtree_nodes.append(node.right) # extract the saved logistic circuit nodes = dict() line = f.readline() while line[0] == "T" or line[0] == "F" or line[0] == "S": line_as_list = line.strip().split(" ") literal_type, var = line_as_list[0], int(line_as_list[3]) index, vtree_index = int(line_as_list[1]), int(line_as_list[2]) parameters = [] for i in range(self._num_classes): parameters.append(float(line_as_list[4 + i])) parameters = np.array(parameters, dtype=np.float64) if literal_type == "T": self._precreated_terminal_nodes[self._num_variables + var - 1].parameter = parameters nodes[index] = ( self._precreated_terminal_nodes[self._num_variables + var - 1], {var}) elif literal_type == "F": self._precreated_terminal_nodes[2 * self._num_variables + var - 1].parameter = parameters nodes[index] = ( self._precreated_terminal_nodes[2 * self._num_variables + var - 1], {-var}) else: self._precreated_terminal_nodes[var - 1].parameter = parameters nodes[index] = (self._precreated_terminal_nodes[var - 1], {-var}) self._largest_index = max(self._largest_index, index) line = f.readline() self._terminal_nodes = [x[0] for x in nodes.values()] root = None while line[0] == "D": line_as_list = line.strip().split(" ") index, vtree_index, num_elements = int(line_as_list[1]), int( line_as_list[2]), int(line_as_list[3]) elements = [] variables = set() for i in range(num_elements): prime_index = int(line_as_list[i * (self._num_classes + 2) + 4].strip("(")) sub_index = int(line_as_list[i * (self._num_classes + 2) + 5]) element_variables = nodes[prime_index][1].union( nodes[sub_index][1]) variables = variables.union(element_variables) splittable_variables = set() for variable in element_variables: if -variable in element_variables: splittable_variables.add(abs(variable)) parameters = [] for j in range(self._num_classes): parameters.append( float(line_as_list[i * (self._num_classes + 2) + 6 + j].strip(")"))) parameters = np.array(parameters, dtype=np.float64) elements.append( AndGate(nodes[prime_index][0], nodes[sub_index][0], parameters)) elements[-1].splittable_variables = splittable_variables nodes[index] = (OrGate(index, vtree_nodes[vtree_index], elements), variables) root = nodes[index][0] self._largest_index = max(self._largest_index, index) line = f.readline() if line[0] != "B": raise ValueError( "The last line in a circuit file must record the bias parameters." ) self._bias = np.array([float(x) for x in line.strip().split(" ")[1:]], dtype=np.float64) gc.collect() return root
def _new_logistic_psdd(self, vtree) -> CircuitNode: left_vtree = vtree.left right_vtree = vtree.right prime_variable = left_vtree.var sub_variable = right_vtree.var elements = list() if left_vtree.is_leaf() and right_vtree.is_leaf(): elements.append( AndGate( self._terminal_nodes[prime_variable - 1], self._terminal_nodes[sub_variable - 1], self.rand_gen.random_sample(size=(self._num_classes, )), )) elements.append( AndGate( self._terminal_nodes[prime_variable - 1], self._terminal_nodes[self._num_variables + sub_variable - 1], self.rand_gen.random_sample(size=(self._num_classes, )), )) elements.append( AndGate( self._terminal_nodes[self._num_variables + prime_variable - 1], self._terminal_nodes[sub_variable - 1], self.rand_gen.random_sample(size=(self._num_classes, )), )) elements.append( AndGate( self._terminal_nodes[self._num_variables + prime_variable - 1], self._terminal_nodes[self._num_variables + sub_variable - 1], self.rand_gen.random_sample(size=(self._num_classes, )), )) elif left_vtree.is_leaf(): elements.append( AndGate( self._terminal_nodes[prime_variable - 1], self._new_logistic_psdd(right_vtree), self.rand_gen.random_sample(size=(self._num_classes, )), )) elements.append( AndGate( self._terminal_nodes[self._num_variables + prime_variable - 1], self._new_logistic_psdd(right_vtree), self.rand_gen.random_sample(size=(self._num_classes, )), )) for element in elements: element.splittable_variables = copy.deepcopy( right_vtree.variables) elif right_vtree.is_leaf(): elements.append( AndGate( self._new_logistic_psdd(left_vtree), self._terminal_nodes[sub_variable - 1], self.rand_gen.random_sample(size=(self._num_classes, )), )) elements.append( AndGate( self._new_logistic_psdd(left_vtree), self._terminal_nodes[self._num_variables + sub_variable - 1], self.rand_gen.random_sample(size=(self._num_classes, )), )) for element in elements: element.splittable_variables = copy.deepcopy( left_vtree.variables) else: elements.append( AndGate( self._new_logistic_psdd(left_vtree), self._new_logistic_psdd(right_vtree), self.rand_gen.random_sample(size=(self._num_classes, )), )) elements[0].splittable_variables = copy.deepcopy(vtree.variables) root = OrGate(self._largest_index, vtree, elements) self._largest_index += 1 return root
def load(self, f): # read the format at the beginning line = f.readline() while line[0] == "c": line = f.readline() # serialize the vtree vtree_nodes = dict() unvisited_vtree_nodes = deque() unvisited_vtree_nodes.append(self._vtree) while len(unvisited_vtree_nodes): node = unvisited_vtree_nodes.popleft() vtree_nodes[node.index] = node if not node.is_leaf(): unvisited_vtree_nodes.append(node.left) unvisited_vtree_nodes.append(node.right) # extract the saved logistic circuit nodes = dict() line = f.readline() while line[0] == "T" or line[0] == "F": line_as_list = line.strip().split(" ") positive_literal, var = (line_as_list[0] == "T"), int( line_as_list[3]) index, vtree_index = int(line_as_list[1]), int(line_as_list[2]) parameters = [] for i in range(self._num_classes): parameters.append(float(line_as_list[4 + i])) parameters = np.array(parameters, dtype=np.float64) if positive_literal: nodes[index] = (CircuitTerminal(index, vtree_nodes[vtree_index], var, LITERAL_IS_TRUE, parameters), {var}) else: nodes[index] = (CircuitTerminal(index, vtree_nodes[vtree_index], var, LITERAL_IS_FALSE, parameters), {-var}) self._largest_index = max(self._largest_index, index) line = f.readline() self._terminal_nodes = [x[0] for x in nodes.values()] self._terminal_nodes.sort(key=lambda x: (-x.var_value, x.var_index)) if len(self._terminal_nodes) != 2 * self._num_variables: raise ValueError( "Number of terminal nodes recorded in the circuit file " "does not match 2 * number of variables in the provided vtree." ) root = None while line[0] == "D": line_as_list = line.strip().split(" ") index, vtree_index, num_elements = int(line_as_list[1]), int( line_as_list[2]), int(line_as_list[3]) elements = [] variables = set() for i in range(num_elements): prime_index = int(line_as_list[i * (self._num_classes + 2) + 4].strip("(")) sub_index = int(line_as_list[i * (self._num_classes + 2) + 5]) element_variables = nodes[prime_index][1].union( nodes[sub_index][1]) variables = variables.union(element_variables) splittable_variables = set() for variable in element_variables: if -variable in element_variables: splittable_variables.add(abs(variable)) parameters = [] for j in range(self._num_classes): parameters.append( float(line_as_list[i * (self._num_classes + 2) + 6 + j].strip(")"))) parameters = np.array(parameters, dtype=np.float64) elements.append( AndGate(nodes[prime_index][0], nodes[sub_index][0], parameters)) elements[-1].splittable_variables = splittable_variables nodes[index] = (OrGate(index, vtree_nodes[vtree_index], elements), variables) root = nodes[index][0] self._largest_index = max(self._largest_index, index) line = f.readline() if line[0] != "B": raise ValueError( "The last line in a circuit file must record the bias parameters." ) self._bias = np.array([float(x) for x in line.strip().split(" ")[1:]], dtype=np.float64) gc.collect() return root