class_docstr: A crystal graph convolutional layer from the paper
  
  > [Crystal Graph Convolutional Neural Networks for an Accurate and
  Interpretable Prediction of Material Properties](https://arxiv.org/abs/1710.10324)<br>
  > Tian Xie and Jeffrey C. Grossman
  
  **Mode**: single, disjoint, mixed.
  
  **This layer expects a sparse adjacency matrix.**
  
  This layer computes:
  $$
      \x_i' = \x_i + \sum\limits_{j \in \mathcal{N}(i)} \sigma \left( \z_{ij}
      \W^{(f)} + \b^{(f)} \right) \odot \g \left( \z_{ij} \W^{(s)} + \b^{(s)}
      \right)
  $$
  where \(\z_{ij} = \x_i \| \x_j \| \e_{ji} \), \(\sigma\) is a sigmoid
  activation, and \(g\) is the activation function (defined by the `activation`
  argument).
  
  **Input**
  
  - Node features of shape `(n_nodes, n_node_features)`;
  - Binary adjacency matrix of shape `(n_nodes, n_nodes)`.
  - Edge features of shape `(num_edges, n_edge_features)`.
  
  **Output**
  
  - Node features with the same shape of the input.
  
  **Arguments**
  
  - `activation`: activation function;
  - `use_bias`: bool, add a bias vector to the output;
  - `kernel_initializer`: initializer for the weights;
  - `bias_initializer`: initializer for the bias vector;
  - `kernel_regularizer`: regularization applied to the weights;
  - `bias_regularizer`: regularization applied to the bias vector;
  - `activity_regularizer`: regularization applied to the output;
  - `kernel_constraint`: constraint applied to the weights;
  - `bias_constraint`: constraint applied to the bias vector.
code: def message(self, x, e=None):
      x_i = self.get_targets(x)
      x_j = self.get_sources(x)
  
      to_concat = [x_i, x_j]
      if e is not None:
          to_concat += [e]
      z = K.concatenate(to_concat, axis=-1)
      output = self.dense_s(z) * self.dense_f(z)
  
      return output
  
file_path: spektral/spektral/layers/convolutional/crystal_conv.py
imports: from tensorflow.keras import backend
  from tensorflow.keras.layers import Dense
  from spektral.layers.convolutional.message_passing import MessagePassing
label_desc: Use image node_id 3 for calling the CrystalConv obj's underlying member method code with example usage: obj.message(x, e) and returns: output