class_docstr: Predictor/score function for pairs of node representations
  
  Given a pair of node representations, :math:`h_i` and :math:`h_j`, it combines them with
  
  **dot product**
  
  .. math::
  
      h_i^{T} h_j
  
  or **cosine similarity**
  
  .. math::
  
      \frac{h_i^{T} h_j}{{\| h_i \|}_2 \cdot {\| h_j \|}_2}
  
  or **elementwise product**
  
  .. math::
  
      h_i \odot h_j
  
  or **concatenation**
  
  .. math::
  
      h_i \Vert h_j
  
  Optionally, it passes the combined results to a linear layer for the final prediction.
  
  Parameters
  ----------
  op : str
      The operation to apply. It can be 'dot', 'cos', 'ele', or 'cat',
      corresponding to the equations above in order.
  in_feats : int, optional
      The input feature size of :math:`h_i` and :math:`h_j`. It is required
      only if a linear layer is to be applied.
  out_feats : int, optional
      The output feature size. It is reuiqred only if a linear layer is to be applied.
  bias : bool, optional
      Whether to use bias for the linear layer if it applies.
  
  Examples
  --------
  >>> import dgl
  >>> import torch as th
  >>> from dgl.nn import EdgePredictor
  >>> num_nodes = 2
  >>> num_edges = 3
  >>> in_feats = 4
  >>> g = dgl.rand_graph(num_nodes=num_nodes, num_edges=num_edges)
  >>> h = th.randn(num_nodes, in_feats)
  >>> src, dst = g.edges()
  >>> h_src = h[src]
  >>> h_dst = h[dst]
  
  Case1: dot product
  
  >>> predictor = EdgePredictor('dot')
  >>> predictor(h_src, h_dst).shape
  torch.Size([3, 1])
  >>> predictor = EdgePredictor('dot', in_feats, out_feats=3)
  >>> predictor.reset_parameters()
  >>> predictor(h_src, h_dst).shape
  torch.Size([3, 3])
  
  Case2: cosine similarity
  
  >>> predictor = EdgePredictor('cos')
  >>> predictor(h_src, h_dst).shape
  torch.Size([3, 1])
  >>> predictor = EdgePredictor('cos', in_feats, out_feats=3)
  >>> predictor.reset_parameters()
  >>> predictor(h_src, h_dst).shape
  torch.Size([3, 3])
  
  Case3: elementwise product
  
  >>> predictor = EdgePredictor('ele')
  >>> predictor(h_src, h_dst).shape
  torch.Size([3, 4])
  >>> predictor = EdgePredictor('ele', in_feats, out_feats=3)
  >>> predictor.reset_parameters()
  >>> predictor(h_src, h_dst).shape
  torch.Size([3, 3])
  
  Case4: concatenation
  
  >>> predictor = EdgePredictor('cat')
  >>> predictor(h_src, h_dst).shape
  torch.Size([3, 8])
  >>> predictor = EdgePredictor('cat', in_feats, out_feats=3)
  >>> predictor.reset_parameters()
  >>> predictor(h_src, h_dst).shape
  torch.Size([3, 3])
code: def __init__(self, op, in_feats=None, out_feats=None, bias=False):
      super(EdgePredictor, self).__init__()
  
      assert op in [
          "dot",
          "cos",
          "ele",
          "cat",
      ], "Expect op to be in ['dot', 'cos', 'ele', 'cat'], got {}".format(
          op
      )
      self.op = op
      if (in_feats is not None) and (out_feats is not None):
          if op in ["dot", "cos"]:
              in_feats = 1
          elif op == "cat":
              in_feats = 2 * in_feats
          self.linear = nn.Linear(in_feats, out_feats, bias=bias)
      else:
          self.linear = None
  
file_path: dgl/python/dgl/nn/pytorch/link/edgepred.py
imports: import torch
  import torch.nn
  import torch.nn.functional
label_desc: Use image node_id 1 to create a new EdgePredictor object from inherited base classes: nn with example: obj = EdgePredictor(op, in_feats, out_feats, bias)