class_docstr: The Efficient Graph Convolution from the `"Adaptive Filters and
  Aggregator Fusion for Efficient Graph Convolutions"
  <https://arxiv.org/abs/2104.01481>`_ paper.
  
  Its node-wise formulation is given by:
  
  .. math::
      \mathbf{x}_i^{\prime} = {\LARGE ||}_{h=1}^H \sum_{\oplus \in
      \mathcal{A}} \sum_{b = 1}^B w_{i, h, \oplus, b} \;
      \underset{j \in \mathcal{N}(i) \cup \{i\}}{\bigoplus}
      \mathbf{W}_b \mathbf{x}_{j}
  
  with :math:`\mathbf{W}_b` denoting a basis weight,
  :math:`\oplus` denoting an aggregator, and :math:`w` denoting per-vertex
  weighting coefficients across different heads, bases and aggregators.
  
  EGC retains :math:`\mathcal{O}(|\mathcal{V}|)` memory usage, making it a
  sensible alternative to :class:`~torch_geometric.nn.conv.GCNConv`,
  :class:`~torch_geometric.nn.conv.SAGEConv` or
  :class:`~torch_geometric.nn.conv.GINConv`.
  
  .. note::
      For an example of using :obj:`EGConv`, see `examples/egc.py
      <https://github.com/pyg-team/pytorch_geometric/blob/master/
      examples/egc.py>`_.
  
  Args:
      in_channels (int): Size of each input sample, or :obj:`-1` to derive
          the size from the first input(s) to the forward method.
      out_channels (int): Size of each output sample.
      aggregators (List[str], optional): Aggregators to be used.
          Supported aggregators are :obj:`"sum"`, :obj:`"mean"`,
          :obj:`"symnorm"`, :obj:`"max"`, :obj:`"min"`, :obj:`"std"`,
          :obj:`"var"`.
          Multiple aggregators can be used to improve the performance.
          (default: :obj:`["symnorm"]`)
      num_heads (int, optional): Number of heads :math:`H` to use. Must have
          :obj:`out_channels % num_heads == 0`. It is recommended to set
          :obj:`num_heads >= num_bases`. (default: :obj:`8`)
      num_bases (int, optional): Number of basis weights :math:`B` to use.
          (default: :obj:`4`)
      cached (bool, optional): If set to :obj:`True`, the layer will cache
          the computation of the edge index with added self loops on first
          execution, along with caching the calculation of the symmetric
          normalized edge weights if the :obj:`"symnorm"` aggregator is
          being used. This parameter should only be set to :obj:`True` in
          transductive learning scenarios. (default: :obj:`False`)
      add_self_loops (bool, optional): If set to :obj:`False`, will not add
          self-loops to the input graph. (default: :obj:`True`)
      bias (bool, optional): If set to :obj:`False`, the layer will not learn
          an additive bias. (default: :obj:`True`)
      **kwargs (optional): Additional arguments of
          :class:`torch_geometric.nn.conv.MessagePassing`.
  
  Shapes:
      - **input:**
        node features :math:`(|\mathcal{V}|, F_{in})`,
        edge indices :math:`(2, |\mathcal{E}|)`
      - **output:** node features :math:`(|\mathcal{V}|, F_{out})`
class_docstr_tok: ["The","Efficient","Graph","Convolution","from","the","`","``","Adaptive","Filters","and","Aggregator","Fusion","for","Efficient","Graph","Convolutions","''","<","https",":","\/\/arxiv.org\/abs\/2104.01481",">","`","_","paper",".","Its","node-wise","formulation","is","given","by",":","..","math",":",":","\\mathbf","{","x","}","_i^","{","\\prime","}","=","{","\\LARGE","||","}","_","{","h=1","}","^H","\\sum_","{","\\oplus","\\in","\\mathcal","{","A","}","}","\\sum_","{","b","=","1","}","^B","w_","{","i",",","h",",","\\oplus",",","b","}","\\",";","\\underset","{","j","\\in","\\mathcal","{","N","}","(","i",")","\\cup","\\","{","i\\","}","}","{","\\bigoplus","}","\\mathbf","{","W","}","_b","\\mathbf","{","x","}","_","{","j","}","with",":","math",":","`","\\mathbf","{","W","}","_b","`","denoting","a","basis","weight",",",":","math",":","`","\\oplus","`","denoting","an","aggregator",",","and",":","math",":","`","w","`","denoting","per-vertex","weighting","coefficients","across","different","heads",",","bases","and","aggregators",".","EGC","retains",":","math",":","`","\\mathcal","{","O","}","(","|\\mathcal","{","V","}","|",")","`","memory","usage",",","making","it","a","sensible","alternative","to",":","class",":","`","~torch_geometric.nn.conv.GCNConv","`",",",":","class",":","`","~torch_geometric.nn.conv.SAGEConv","`","or",":","class",":","`","~torch_geometric.nn.conv.GINConv","`",".","..","note",":",":","For","an","example","of","using",":","obj",":","`","EGConv","`",",","see","`","examples\/egc.py","<","https",":","\/\/github.com\/pyg-team\/pytorch_geometric\/blob\/master\/","examples\/egc.py",">","`","_",".","Args",":","in_channels","(","int",")",":","Size","of","each","input","sample",",","or",":","obj",":","`","-1","`","to","derive","the","size","from","the","first","input","(","s",")","to","the","forward","method",".","out_channels","(","int",")",":","Size","of","each","output","sample",".","aggregators","(","List","[","str","]",",","optional",")",":","Aggregators","to","be","used",".","Supported","aggregators","are",":","obj",":","`","``","sum","''","`",",",":","obj",":","`","``","mean","''","`",",",":","obj",":","`","``","symnorm","''","`",",",":","obj",":","`","``","max","''","`",",",":","obj",":","`","``","min","''","`",",",":","obj",":","`","``","std","''","`",",",":","obj",":","`","``","var","''","`",".","Multiple","aggregators","can","be","used","to","improve","the","performance",".","(","default",":",":","obj",":","`","[","``","symnorm","''","]","`",")","num_heads","(","int",",","optional",")",":","Number","of","heads",":","math",":","`","H","`","to","use",".","Must","have",":","obj",":","`","out_channels","%","num_heads","==","0","`",".","It","is","recommended","to","set",":","obj",":","`","num_heads",">","=","num_bases","`",".","(","default",":",":","obj",":","`","8","`",")","num_bases","(","int",",","optional",")",":","Number","of","basis","weights",":","math",":","`","B","`","to","use",".","(","default",":",":","obj",":","`","4","`",")","cached","(","bool",",","optional",")",":","If","set","to",":","obj",":","`","True","`",",","the","layer","will","cache","the","computation","of","the","edge","index","with","added","self","loops","on","first","execution",",","along","with","caching","the","calculation","of","the","symmetric","normalized","edge","weights","if","the",":","obj",":","`","``","symnorm","''","`","aggregator","is","being","used",".","This","parameter","should","only","be","set","to",":","obj",":","`","True","`","in","transductive","learning","scenarios",".","(","default",":",":","obj",":","`","False","`",")","add_self_loops","(","bool",",","optional",")",":","If","set","to",":","obj",":","`","False","`",",","will","not","add","self-loops","to","the","input","graph",".","(","default",":",":","obj",":","`","True","`",")","bias","(","bool",",","optional",")",":","If","set","to",":","obj",":","`","False","`",",","the","layer","will","not","learn","an","additive","bias",".","(","default",":",":","obj",":","`","True","`",")","*","*","kwargs","(","optional",")",":","Additional","arguments","of",":","class",":","`","torch_geometric.nn.conv.MessagePassing","`",".","Shapes",":","-","*","*","input",":","*","*","node","features",":","math",":","`","(","|\\mathcal","{","V","}","|",",","F_","{","in","}",")","`",",","edge","indices",":","math",":","`","(","2",",","|\\mathcal","{","E","}","|",")","`","-","*","*","output",":","*","*","node","features",":","math",":","`","(","|\\mathcal","{","V","}","|",",","F_","{","out","}",")","`"]
code: def __init__(
      self,
      in_channels: int,
      out_channels: int,
      aggregators: List[str] = ["symnorm"],
      num_heads: int = 8,
      num_bases: int = 4,
      cached: bool = False,
      add_self_loops: bool = True,
      bias: bool = True,
      **kwargs,
  ):
      super().__init__(node_dim=0, **kwargs)
  
      if out_channels % num_heads != 0:
          raise ValueError(
              f"'out_channels' (got {out_channels}) must be "
              f"divisible by the number of heads "
              f"(got {num_heads})"
          )
  
      for a in aggregators:
          if a not in [
              "sum",
              "mean",
              "symnorm",
              "min",
              "max",
              "var",
              "std",
          ]:
              raise ValueError(f"Unsupported aggregator: '{a}'")
  
      self.in_channels = in_channels
      self.out_channels = out_channels
      self.num_heads = num_heads
      self.num_bases = num_bases
      self.cached = cached
      self.add_self_loops = add_self_loops
      self.aggregators = aggregators
  
      self.bases_lin = Linear(
          in_channels,
          (out_channels // num_heads) * num_bases,
          bias=False,
          weight_initializer="glorot",
      )
      self.comb_lin = Linear(
          in_channels, num_heads * num_bases * len(aggregators)
      )
  
      if bias:
          self.bias = Parameter(torch.empty(out_channels))
      else:
          self.register_parameter("bias", None)
  
      self.reset_parameters()
  
file_path: pytorch_geometric/torch_geometric/nn/conv/eg_conv.py
imports: from typing import List, Optional, Tuple
  import torch
  from torch import Tensor
  from torch.nn import Parameter
  from torch_geometric.nn.conv import MessagePassing
  from torch_geometric.nn.conv.gcn_conv import gcn_norm
  from torch_geometric.nn.dense.linear import Linear
  from torch_geometric.nn.inits import zeros
  from torch_geometric.typing import Adj, OptTensor, SparseTensor, torch_sparse
  from torch_geometric.utils import add_remaining_self_loops, scatter, spmm
label_desc: Use image node_id 1 to create a new EGConv object from inherited base classes: MessagePassing with example: obj = EGConv(in_channels, out_channels, aggregators, num_heads, num_bases, cached, add__loops, bias)