r"""Message aggregation step of ``hyperedges to vertices``. Args: ``X`` (``torch.Tensor``): Hyperedge feature matrix. Size :math:`(|\mathcal{E}|, C)`. ``aggr`` (``str``): The aggregation method. Can be ``'mean'``, ``'sum'`` and ``'softmax_then_sum'``. ``e
(
self,
X: torch.Tensor,
aggr: str = "mean",
e2v_weight: Optional[torch.Tensor] = None,
drop_rate: float = 0.0,
)
| 1509 | return X |
| 1510 | |
| 1511 | def e2v_aggregation( |
| 1512 | self, |
| 1513 | X: torch.Tensor, |
| 1514 | aggr: str = "mean", |
| 1515 | e2v_weight: Optional[torch.Tensor] = None, |
| 1516 | drop_rate: float = 0.0, |
| 1517 | ): |
| 1518 | r"""Message aggregation step of ``hyperedges to vertices``. |
| 1519 | |
| 1520 | Args: |
| 1521 | ``X`` (``torch.Tensor``): Hyperedge feature matrix. Size :math:`(|\mathcal{E}|, C)`. |
| 1522 | ``aggr`` (``str``): The aggregation method. Can be ``'mean'``, ``'sum'`` and ``'softmax_then_sum'``. |
| 1523 | ``e2v_weight`` (``torch.Tensor``, optional): The weight vector attached to connections (hyperedges point to vertices). If not specified, the function will use the weights specified in hypergraph construction. Defaults to ``None``. |
| 1524 | ``drop_rate`` (``float``): Dropout rate. Randomly dropout the connections in incidence matrix with probability ``drop_rate``. Default: ``0.0``. |
| 1525 | """ |
| 1526 | assert aggr in ["mean", "sum", "softmax_then_sum"] |
| 1527 | if self.device != X.device: |
| 1528 | self.to(X.device) |
| 1529 | if e2v_weight is None: |
| 1530 | if drop_rate > 0.0: |
| 1531 | P = sparse_dropout(self.H, drop_rate) |
| 1532 | else: |
| 1533 | P = self.H |
| 1534 | if aggr == "mean": |
| 1535 | X = torch.sparse.mm(P, X) |
| 1536 | X = torch.sparse.mm(self.D_v_neg_1, X) |
| 1537 | elif aggr == "sum": |
| 1538 | X = torch.sparse.mm(P, X) |
| 1539 | elif aggr == "softmax_then_sum": |
| 1540 | P = torch.sparse.softmax(P, dim=1) |
| 1541 | X = torch.sparse.mm(P, X) |
| 1542 | else: |
| 1543 | raise ValueError(f"Unknown aggregation method: {aggr}") |
| 1544 | else: |
| 1545 | # init message path |
| 1546 | assert ( |
| 1547 | e2v_weight.shape[0] == self.e2v_weight.shape[0] |
| 1548 | ), "The size of e2v_weight must be equal to the size of self.e2v_weight." |
| 1549 | P = torch.sparse_coo_tensor( |
| 1550 | self.H._indices(), e2v_weight, self.H.shape, device=self.device |
| 1551 | ) |
| 1552 | if drop_rate > 0.0: |
| 1553 | P = sparse_dropout(P, drop_rate) |
| 1554 | # message passing |
| 1555 | if aggr == "mean": |
| 1556 | X = torch.sparse.mm(P, X) |
| 1557 | D_v_neg_1 = torch.sparse.sum(P, dim=1).to_dense().view(-1, 1) |
| 1558 | D_v_neg_1[torch.isinf(D_v_neg_1)] = 0 |
| 1559 | X = D_v_neg_1 * X |
| 1560 | elif aggr == "sum": |
| 1561 | X = torch.sparse.mm(P, X) |
| 1562 | elif aggr == "softmax_then_sum": |
| 1563 | P = torch.sparse.softmax(P, dim=1) |
| 1564 | X = torch.sparse.mm(P, X) |
| 1565 | else: |
| 1566 | raise ValueError(f"Unknown aggregation method: {aggr}") |
| 1567 | return X |
| 1568 |
no test coverage detected