MCPcopy Create free account
hub / github.com/easy-graph/Easy-Graph / from_hypergraph_hypergcn

Method from_hypergraph_hypergcn

easygraph/classes/graph.py:180–239  ·  view source on GitHub ↗
(
        hypergraph,
        feature,
        with_mediator=False,
        remove_selfloop=True,
    )

Source from the content-addressed store, hash-verified

178
179 @staticmethod
180 def from_hypergraph_hypergcn(
181 hypergraph,
182 feature,
183 with_mediator=False,
184 remove_selfloop=True,
185 ):
186 import torch
187
188 r"""Construct a graph from a hypergraph with methods proposed in `HyperGCN: A New Method of Training Graph Convolutional Networks on Hypergraphs <https://arxiv.org/pdf/1809.02589.pdf>`_ paper .
189
190 Args:
191 ``hypergraph`` (``Hypergraph``): The source hypergraph.
192 ``feature`` (``torch.Tensor``): The feature of the vertices.
193 ``with_mediator`` (``str``): Whether to use mediator to transform the hyperedges to edges in the graph. Defaults to ``False``.
194 ``remove_selfloop`` (``bool``): Whether to remove self-loop. Defaults to ``True``.
195 ``device`` (``torch.device``): The device to store the graph. Defaults to ``torch.device("cpu")``.
196 """
197 num_v = hypergraph.num_v
198 assert (
199 num_v == feature.shape[0]
200 ), "The number of vertices in hypergraph and feature.shape[0] must be equal!"
201 e_list, new_e_list, new_e_weight = hypergraph.e[0], [], []
202 rv = torch.rand((feature.shape[1], 1), device=feature.device)
203 for e in e_list:
204 num_v_in_e = len(e)
205 assert (
206 num_v_in_e >= 2
207 ), "The number of vertices in an edge must be greater than or equal to 2!"
208 p = torch.mm(feature[e, :], rv).squeeze()
209 v_a_idx, v_b_idx = torch.argmax(p), torch.argmin(p)
210 if not with_mediator:
211 new_e_list.append([e[v_a_idx], e[v_b_idx]])
212 new_e_weight.append(1.0 / num_v_in_e)
213 else:
214 w = 1.0 / (2 * num_v_in_e - 3)
215 for mid_v_idx in range(num_v_in_e):
216 if mid_v_idx != v_a_idx and mid_v_idx != v_b_idx:
217 new_e_list.append([e[v_a_idx], e[mid_v_idx]])
218 new_e_weight.append(w)
219 new_e_list.append([e[v_b_idx], e[mid_v_idx]])
220 new_e_weight.append(w)
221 # remove selfloop
222 if remove_selfloop:
223 new_e_list = torch.tensor(new_e_list, dtype=torch.long)
224 new_e_weight = torch.tensor(new_e_weight, dtype=torch.float)
225 e_mask = (new_e_list[:, 0] != new_e_list[:, 1]).bool()
226 new_e_list = new_e_list[e_mask].numpy().tolist()
227 new_e_weight = new_e_weight[e_mask].numpy().tolist()
228
229 _g = Graph()
230 _g.add_nodes(list(range(0, num_v)))
231 for (
232 e,
233 w,
234 ) in zip(new_e_list, new_e_weight):
235 if _g.has_edge(e[0], e[1]):
236 _g.add_edge(e[0], e[1], weight=(w + _g.adj[e[0]][e[1]]["weight"]))
237 else:

Callers 2

forwardMethod · 0.80
forwardMethod · 0.80

Calls 5

add_nodesMethod · 0.95
has_edgeMethod · 0.95
add_edgeMethod · 0.95
appendMethod · 0.80
GraphClass · 0.70

Tested by

no test coverage detected