r"""Add self-loops for each node in the graph and return a new graph. For heterogeneous graphs, self-loops are added only for edge types with same source and destination node types. Parameters ---------- allow_duplicate : bool, optional If False, it will first remove se
| 508 | |
| 509 | |
| 510 | class AddSelfLoop(BaseTransform): |
| 511 | r"""Add self-loops for each node in the graph and return a new graph. |
| 512 | |
| 513 | For heterogeneous graphs, self-loops are added only for edge types with same |
| 514 | source and destination node types. |
| 515 | |
| 516 | Parameters |
| 517 | ---------- |
| 518 | allow_duplicate : bool, optional |
| 519 | If False, it will first remove self-loops to prevent duplicate self-loops. |
| 520 | new_etypes : bool, optional |
| 521 | If True, it will add an edge type 'self' per node type, which holds self-loops. |
| 522 | edge_feat_names : list[str], optional |
| 523 | The names of the self-loop features to apply `fill_data`. If None, it |
| 524 | will apply `fill_data` to all self-loop features. Default: None. |
| 525 | fill_data : int, float or str, optional |
| 526 | The value to fill the self-loop features. Default: 1. |
| 527 | |
| 528 | * If ``fill_data`` is ``int`` or ``float``, self-loop features will be directly given by |
| 529 | ``fill_data``. |
| 530 | * if ``fill_data`` is ``str``, self-loop features will be generated by aggregating the |
| 531 | features of the incoming edges of the corresponding nodes. The supported aggregation are: |
| 532 | ``'mean'``, ``'sum'``, ``'max'``, ``'min'``. |
| 533 | |
| 534 | Example |
| 535 | ------- |
| 536 | |
| 537 | >>> import dgl |
| 538 | >>> from dgl import AddSelfLoop |
| 539 | |
| 540 | Case1: Add self-loops for a homogeneous graph |
| 541 | |
| 542 | >>> transform = AddSelfLoop(fill_data='sum') |
| 543 | >>> g = dgl.graph(([0, 0, 2], [2, 1, 0])) |
| 544 | >>> g.edata['he'] = torch.arange(3).float().reshape(-1, 1) |
| 545 | >>> new_g = transform(g) |
| 546 | >>> print(new_g.edges()) |
| 547 | (tensor([0, 0, 2, 0, 1, 2]), tensor([2, 1, 0, 0, 1, 2])) |
| 548 | >>> print(new_g.edata('he')) |
| 549 | tensor([[0.], |
| 550 | [1.], |
| 551 | [2.], |
| 552 | [2.], |
| 553 | [1.], |
| 554 | [0.]]) |
| 555 | |
| 556 | Case2: Add self-loops for a heterogeneous graph |
| 557 | |
| 558 | >>> transform = AddSelfLoop(fill_data='sum') |
| 559 | >>> g = dgl.heterograph({ |
| 560 | ... ('user', 'follows', 'user'): (torch.tensor([1, 2]), |
| 561 | ... torch.tensor([0, 1])), |
| 562 | ... ('user', 'plays', 'game'): (torch.tensor([0, 1]), |
| 563 | ... torch.tensor([0, 1]))}) |
| 564 | >>> g.edata['feat'] = {('user', 'follows', 'user'): torch.randn(2, 5), |
| 565 | ... ('user', 'plays', 'game'): torch.randn(2, 5)} |
| 566 | >>> g.edata['feat1'] = {('user', 'follows', 'user'): torch.randn(2, 15), |
| 567 | ... ('user', 'plays', 'game'): torch.randn(2, 15)} |
no outgoing calls