示例#1
0
def test_primitive_conversion():
    for _ in supported_backends():
        assert pg.obj2id("str") == str(hash("str"))
        assert pg.sum(pg.to_array([1, 2, 3])) == 6
        assert pg.sum(pg.dot(pg.exp(pg.log(pg.to_array([4, 5]))), pg.to_array([2, 2]))) == 18
        primitive = pg.to_array([1, 2, 3])
        assert id(primitive) == id(pg.to_array(primitive, copy_array=False))
        assert id(primitive) != id(pg.to_array(primitive, copy_array=True))
示例#2
0
def test_sequential():
    graph = next(pg.load_datasets_graph(["graph5"]))
    for _ in supported_backends():
        prior = pg.to_signal(graph, {"A": 2})
        posterior1 = pg.Normalize(pg.PageRank(), "range").rank(prior)
        posterior2 = pg.Normalize("range")(pg.PageRank()(prior))
        posterior3 = pg.Sequential(pg.PageRank(),
                                   pg.Normalize("range")).rank(prior)
        assert pg.sum(pg.abs(posterior1 - posterior2)) < pg.epsilon(
        )  # TODO: investigate when not exactly zero
        assert pg.sum(pg.abs(posterior1 - posterior3)) < pg.epsilon(
        )  # TODO: investigate when not exactly zero
示例#3
0
def test_normalize():
    import networkx as nx
    graph = next(pg.load_datasets_graph(["graph5"]))
    for _ in supported_backends():
        assert float(
            pg.sum(
                pg.Normalize("range").transform(
                    pg.to_signal(nx.Graph([("A", "B")]), [2, 2])).np)) == 4
        r = pg.Normalize(pg.PageRank(), "range").rank(graph)
        assert pg.min(r.np) == 0
        assert pg.max(r.np) == 1
        r = pg.Normalize(pg.PageRank(), "sum").rank(graph)
        assert abs(pg.sum(r.np) - 1) < pg.epsilon()
        with pytest.raises(Exception):
            pg.Normalize(pg.PageRank(), "unknown").rank(graph)
示例#4
0
 def _transform(self, ranks: pg.GraphSignal, **kwargs):
     if ranks.graph not in self.known_ranks or not self.assume_immutability:
         with pg.Backend("numpy"):
             A = pg.preprocessor(normalization=self.normalization)(
                 ranks.graph)
             D = pg.degrees(
                 pg.preprocessor(normalization="none")(ranks.graph))
             s = pg.sum(
                 D)**0.5 / 2 if self.sparsity is None else self.sparsity
             D = (D / pg.max(D))**self.beta
             S = scipy.sparse.random(
                 self.dims,
                 A.shape[0],
                 density=1. / s,
                 data_rvs=lambda l: np.random.choice([-1, 1], size=l),
                 format="csc")
             S = S @ scipy.sparse.spdiags(D, 0, *A.shape)
         self.embeddigns[ranks.graph] = pg.scipy_sparse_to_backend(S.T)
         self.known_ranks[ranks.graph] = [
         ]  # we know that the first term is zero and avoid direct embedding comparison
         for _ in range(len(self.weights)):
             S = S @ A
             self.known_ranks[ranks.graph].append(
                 pg.scipy_sparse_to_backend(S))
     ret = 0
     on = pg.conv(ranks.np, self.embeddigns[ranks.graph])
     for weight, S in zip(self.weights, self.known_ranks[ranks.graph]):
         uv = pg.conv(on, S)
         ret = ret + weight * uv
     return pg.to_signal(ranks, ret)
示例#5
0
def test_norm_maintain():
    # TODO: investigate that 2.5*epsilon is truly something to be expected
    graph = next(pg.load_datasets_graph(["graph5"]))
    for _ in supported_backends():
        prior = pg.to_signal(graph, {"A": 2})
        posterior = pg.MabsMaintain(pg.Normalize(pg.PageRank(),
                                                 "range")).rank(prior)
        assert abs(pg.sum(pg.abs(posterior.np)) - 2) < 2.5 * pg.epsilon()
示例#6
0
def test_separate_and_combine():
    for _ in supported_backends():
        table = pg.to_primitive([[1, 2, 3], [4, 5, 6]])
        cols = pg.separate_cols(table)
        assert len(cols) == 3
        for col in cols:
            assert pg.length(col) == 2
        new_table = pg.combine_cols(cols)
        assert pg.sum(pg.abs(table - new_table)) == 0
示例#7
0
def test_transform():
    import math
    graph = next(pg.load_datasets_graph(["graph5"]))
    for _ in supported_backends():
        r1 = pg.Normalize(pg.PageRank(), "sum").rank(graph)
        r2 = pg.Transformer(pg.PageRank(), lambda x: x / pg.sum(x)).rank(graph)
        assert pg.Mabs(r1)(r2) < pg.epsilon()
        r1 = pg.Transformer(math.exp).transform(pg.PageRank()(graph))
        r2 = pg.Transformer(pg.PageRank(), pg.exp).rank(graph)
        assert pg.Mabs(r1)(r2) < pg.epsilon()
示例#8
0
def test_preprocessor_types():
    def test_graph():
        return next(pg.load_datasets_graph(["graph5"]))
    for _ in supported_backends():
        from random import random
        graph = test_graph()
        signal = pg.to_signal(graph, {v: random() for v in graph})
        laplacian = pg.preprocessor(normalization="laplacian")(graph)
        symmetric = pg.preprocessor(normalization="symmetric")(graph)
        assert pg.abs(pg.sum(pg.conv(signal, laplacian) + pg.conv(signal, symmetric) - signal)) <= pg.epsilon()
示例#9
0
 def rank(self,
          graph: pg.GraphSignalGraph = None,
          personalization: pg.GraphSignalData = None,
          **kwargs):
     personalization = pg.to_signal(graph, personalization)
     graph = personalization.graph
     ranks = self.ranker(personalization)
     ret = 0
     total_sum = pg.sum(ranks)
     accum_sum = 0
     for threshold in sorted(ranks.values()):
         accum_sum += threshold
         if accum_sum > total_sum * 0.1:
             break
     for i, v in enumerate(ranks):
         pg.utils.log(f"{i}/{len(ranks)}")
         if ranks[v] >= threshold:
             partial = ranks >> pg.Threshold(ranks[v],
                                             inclusive=True) >> self.ranker
             ret = partial * ranks[v] + ret
     return ret
示例#10
0
def test_fastgraph():
    for graph_api in [pg.fastgraph, nx]:
        graph = next(pg.load_datasets_graph(["graph5"], graph_api=graph_api))
        assert graph.has_edge("A", "B")
        assert not graph.has_edge("A", "E")
        graph.add_edge("A", "E")
        assert graph.has_edge("A", "E")
        assert graph.has_edge(
            "E", "A")  # checks that undirected is the default mode
        prev_count = graph.number_of_edges()
        graph.remove_edge("A", "E")
        assert graph.number_of_edges() == prev_count - 1
        sparse = graph.to_scipy_sparse_array() if isinstance(
            graph, pg.Graph) else nx.to_scipy_sparse_matrix(
                graph, weight="weight", dtype=float)
        assert pg.sum(sparse) == 14
        assert not graph.has_edge("A", "E")
        assert not graph.has_edge("E", "A")
        graph.add_edge("A", "E")
        assert graph.has_edge("A", "E")
        graph.add_edge("Y", "Z")
        assert graph.has_edge("Y", "Z")
示例#11
0
def test_krylov_space():
    graph = next(pg.load_datasets_graph(["bigraph"]))
    nodes = list(graph)
    for _ in supported_backends():
        personalization = pg.to_signal(graph, {nodes[0]: 1, nodes[1]: 1})
        M = pg.preprocessor(normalization="symmetric")(graph)
        krylov_dims = 5
        krylov_result = pg.eye(int(krylov_dims))
        krylov_base, H = pg.krylov_base(M, personalization.np,
                                        int(krylov_dims))
        error_bound = pg.krylov_error_bound(krylov_base, H, M,
                                            personalization.np)
        assert pg.sum(pg.krylov2original(0, H, krylov_dims)) == 0
        assert error_bound < 0.01
        for _ in range(100):
            krylov_result = krylov_result @ H
            personalization.np = pg.conv(personalization.np, M)
            # print(pg.Mabs(personalization.np)(pg.krylov2original(krylov_base, krylov_result, int(krylov_dims))))
            assert pg.Mabs(personalization.np)(pg.krylov2original(
                krylov_base, krylov_result, int(krylov_dims))) <= error_bound
            assert pg.krylov2original(
                krylov_base, krylov_result,
                int(krylov_dims)).shape == personalization.np.shape
示例#12
0
def test_zero_personalization():
    assert pg.sum(pg.PageRank()(next(pg.load_datasets_graph(["graph9"])),
                                {}).np) == 0
示例#13
0
def test_signal_direct_operations():
    for _ in supported_backends():
        graph = nx.DiGraph([(1, 2), (2, 3)])
        signal = pg.to_signal(graph, [1., 2., 3.])
        assert pg.sum(signal) == 6
        assert pg.sum(signal + 1) == 9
        assert pg.sum(1 + signal) == 9
        assert pg.sum(signal**2) == 14
        assert pg.sum(signal - pg.to_signal(graph, [1, 2, 2])) == 1
        assert pg.sum(-1 + signal) == 3
        assert pg.sum(signal / pg.to_signal(graph, [1., 2., 3.])) == 3
        assert pg.sum(3**signal) == 3 + 9 + 27
        signal **= 2
        assert pg.sum(signal) == 14
        signal.np = pg.to_signal(graph, [4, 4, 4])
        assert pg.sum(signal) == 12
        assert pg.sum(+signal) == 12
        assert pg.sum(-signal) == -12
        assert pg.sum(-signal / 2) == -6
        #assert pg.sum(-signal//2) == -6
        assert pg.sum(2 / signal) == 1.5
        #assert pg.sum(2//signal) == 0
        signal += 1
        assert pg.sum(signal) == 15
        signal -= 1
        assert pg.sum(signal) == 12
        signal /= 2
        assert pg.sum(signal) == 6
        signal /= 2  # //= 2
        assert pg.sum(signal) == 3
        signal *= 4
        assert pg.sum(signal) == 12
        with pytest.raises(Exception):
            signal + pg.to_signal(graph.copy(), [1., 2., 3.])