def test_tree_accumulator(self): tree = TestTreeAccumulators.get_tree() input_array = np.asarray((1, 1, 1, 1, 1, 1, 1, 1)) res1 = hg.accumulate_parallel(tree, input_array, hg.Accumulators.sum) ref1 = np.asarray((0, 0, 0, 0, 0, 2, 3, 2)) self.assertTrue(np.allclose(ref1, res1)) leaf_data = np.asarray((1, 1, 1, 1, 1)) res2 = hg.accumulate_sequential(tree, leaf_data, hg.Accumulators.sum) ref2 = np.asarray((1, 1, 1, 1, 1, 2, 3, 5)) self.assertTrue(np.allclose(ref2, res2)) res3 = hg.accumulate_and_add_sequential(tree, input_array, leaf_data, hg.Accumulators.max) ref3 = np.asarray((1, 1, 1, 1, 1, 2, 2, 3)) self.assertTrue(np.allclose(ref3, res3)) input_array = np.asarray((1, 2, 1, 2, 1, 1, 4, 5)) res4 = hg.accumulate_and_max_sequential(tree, input_array, leaf_data, hg.Accumulators.sum) ref4 = np.asarray((1, 1, 1, 1, 1, 2, 4, 6)) self.assertTrue(np.allclose(ref4, res4)) input_array = np.asarray((1, 2, 1, 2, 1, 2, 3, 1)) res5 = hg.accumulate_and_multiply_sequential(tree, input_array, leaf_data, hg.Accumulators.sum) ref5 = np.asarray((1, 1, 1, 1, 1, 4, 9, 13)) self.assertTrue(np.allclose(ref5, res5)) input_array = np.asarray((1, 2, 1, 2, 1, 4, 2, 10)) res6 = hg.accumulate_and_min_sequential(tree, input_array, leaf_data, hg.Accumulators.sum) ref6 = np.asarray((1, 1, 1, 1, 1, 2, 2, 4)) self.assertTrue(np.allclose(ref6, res6))
def test_tree_accumulatorVec(self): tree = TestTreeAccumulators.get_tree() input_array = np.asarray(((1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7))) res1 = hg.accumulate_parallel(tree, input_array, hg.Accumulators.sum) ref1 = np.asarray(((0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (2, 1), (3, 9), (2, 11))) self.assertTrue(np.allclose(ref1, res1)) leaf_data = np.asarray(((1, 0), (1, 1), (1, 2), (1, 3), (1, 4))) res2 = hg.accumulate_sequential(tree, leaf_data, hg.Accumulators.sum) ref2 = np.asarray(((1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (3, 9), (5, 10))) self.assertTrue(np.allclose(ref2, res2)) res3 = hg.accumulate_and_add_sequential(tree, input_array, leaf_data, hg.Accumulators.sum) ref3 = np.asarray(((1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (3, 6), (4, 15), (8, 28))) self.assertTrue(np.allclose(ref3, res3))
def loss_cluster_size(graph, edge_weights, ultrametric, hierarchy, top_nodes=0, dtype=tc.float64): """ Cluster size regularization: .. math:: loss = \\frac{1}{|E|}\sum_{e_{xy}\in E}\\frac{ultrametric(e_{xy})}{\min\{|c|\, | \, c\in Children(lca(x,y))\}} :param graph: input graph (``higra.UndirectedGraph``) :param edge_weights: edge weights of the input graph (``torch.Tensor``, autograd is supported) :param ultrametric; ultrametric on the input graph (``torch.Tensor``, autograd is supported) :param hierarchy: optional, if provided must be a tuple ``(tree, altitudes)`` corresponding to the result of ``higra.bpt_canonical`` on the input edge weighted graph :param top_nodes: if different from 0, only the top ``top_nodes`` of the hiearchy are taken into account in the cluster size regularization :return: loss value as a pytorch scalar """ tree, altitudes = hierarchy lca_map = hg.attribute_lca_map(tree) if top_nodes <= 0: top_nodes = tree.num_vertices() top_nodes = max(tree.num_vertices() - top_nodes, tree.num_leaves()) top_edges, = np.nonzero(lca_map >= top_nodes) area = hg.attribute_area(tree) min_area = hg.accumulate_parallel(tree, area, hg.Accumulators.min) min_area = min_area[lca_map[top_edges]] min_area = tc.tensor(min_area, dtype=dtype) cluster_size_loss = ultrametric[top_edges] / min_area return cluster_size_loss.mean()
def non_relevant_functor(tree, _): area = hg.attribute_area(tree) return hg.accumulate_parallel(tree, area, hg.Accumulators.min) < size_threshold
def functor(tree, altitudes): area = hg.attribute_area(tree) area_min_children = hg.accumulate_parallel(tree, area, hg.Accumulators.min) return area_min_children < 3