| 1263 | return self.eps |
| 1264 | |
| 1265 | def __call__(self, g): |
| 1266 | # Step1: PPR diffusion |
| 1267 | # (α - 1) A |
| 1268 | device = g.device |
| 1269 | eweight = (self.alpha - 1) * g.edata.get( |
| 1270 | self.eweight_name, F.ones((g.num_edges(),), F.float32, device) |
| 1271 | ) |
| 1272 | num_nodes = g.num_nodes() |
| 1273 | mat = F.zeros((num_nodes, num_nodes), F.float32, device) |
| 1274 | src, dst = g.edges() |
| 1275 | src, dst = F.astype(src, F.int64), F.astype(dst, F.int64) |
| 1276 | mat[dst, src] = eweight |
| 1277 | # I_n + (α - 1) A |
| 1278 | nids = F.astype(g.nodes(), F.int64) |
| 1279 | mat[nids, nids] = mat[nids, nids] + 1 |
| 1280 | # α (I_n + (α - 1) A)^-1 |
| 1281 | diff_mat = self.alpha * F.inverse(mat) |
| 1282 | |
| 1283 | # Step2: sparsification |
| 1284 | num_nodes = g.num_nodes() |
| 1285 | eps = self.get_eps(num_nodes, diff_mat) |
| 1286 | dst, src = (diff_mat >= eps).nonzero(as_tuple=False).t() |
| 1287 | data_dict = {g.canonical_etypes[0]: (src, dst)} |
| 1288 | new_g = update_graph_structure(g, data_dict, copy_edata=False) |
| 1289 | new_g.edata[self.eweight_name] = diff_mat[dst, src] |
| 1290 | |
| 1291 | return new_g |
| 1292 | |
| 1293 | |
| 1294 | def is_bidirected(g): |