コード例 #1
0
 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
コード例 #2
0
 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
コード例 #3
0
 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
コード例 #4
0
    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
コード例 #5
0
 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
コード例 #6
0
    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