class_docstr: Spatial GRU layer.
  
  :param units: Number of SpatialGRU units.
  :param activation: Activation function to use. Default:
      hyperbolic tangent (`tanh`). If you pass `None`, no
      activation is applied (ie. "linear" activation: `a(x) = x`).
  :param recurrent_activation: Activation function to use for
      the recurrent step. Default: sigmoid (`sigmoid`).
      If you pass `None`, no activation is applied (ie. "linear"
      activation: `a(x) = x`).
  :param kernel_initializer: Initializer for the `kernel` weights
      matrix, used for the linear transformation of the inputs.
  :param recurrent_initializer: Initializer for the `recurrent_kernel`
      weights matrix, used for the linear transformation of the
      recurrent state.
  :param direction: Scanning direction. `lt` (i.e., left top)
      indicates the scanning from left top to right bottom, and
      `rb` (i.e., right bottom) indicates the scanning from
      right bottom to left top.
  :param kwargs: Standard layer keyword arguments.
  
  Examples:
      >>> import matchzoo as mz
      >>> layer = mz.contrib.layers.SpatialGRU(units=10,
      ...                                      direction='lt')
      >>> num_batch, channel, left_len, right_len = 5, 5, 3, 2
      >>> layer.build([num_batch, channel, left_len, right_len])
class_docstr_tok: ["Spatial","GRU","layer",".",":","param","units",":","Number","of","SpatialGRU","units",".",":","param","activation",":","Activation","function","to","use",".","Default",":","hyperbolic","tangent","(","`","tanh","`",")",".","If","you","pass","`","None","`",",","no","activation","is","applied","(","ie",".","``","linear","''","activation",":","`","a","(","x",")","=","x","`",")",".",":","param","recurrent_activation",":","Activation","function","to","use","for","the","recurrent","step",".","Default",":","sigmoid","(","`","sigmoid","`",")",".","If","you","pass","`","None","`",",","no","activation","is","applied","(","ie",".","``","linear","''","activation",":","`","a","(","x",")","=","x","`",")",".",":","param","kernel_initializer",":","Initializer","for","the","`","kernel","`","weights","matrix",",","used","for","the","linear","transformation","of","the","inputs",".",":","param","recurrent_initializer",":","Initializer","for","the","`","recurrent_kernel","`","weights","matrix",",","used","for","the","linear","transformation","of","the","recurrent","state",".",":","param","direction",":","Scanning","direction",".","`","lt","`","(","i.e.",",","left","top",")","indicates","the","scanning","from","left","top","to","right","bottom",",","and","`","rb","`","(","i.e.",",","right","bottom",")","indicates","the","scanning","from","right","bottom","to","left","top",".",":","param","kwargs",":","Standard","layer","keyword","arguments",".","Examples",":",">",">",">","import","matchzoo","as","mz",">",">",">","layer","=","mz.contrib.layers.SpatialGRU","(","units=10",",","...","direction='lt","'",")",">",">",">","num_batch",",","channel",",","left_len",",","right_len","=","5",",","5",",","3",",","2",">",">",">","layer.build","(","[","num_batch",",","channel",",","left_len",",","right_len","]",")"]
docstr: Calculate recurrent unit.
  
  :param inputs: A TensorArray which contains interaction
      between left text and right text.
  :param states: A TensorArray which stores the hidden state
      of every step.
  :param step: Recurrent step.
  :param h: Hidden state from last operation.
docstr_tok: ["Calculate","recurrent","unit",".",":","param","inputs",":","A","TensorArray","which","contains","interaction","between","left","text","and","right","text",".",":","param","states",":","A","TensorArray","which","stores","the","hidden","state","of","every","step",".",":","param","step",":","Recurrent","step",".",":","param","h",":","Hidden","state","from","last","operation","."]
code: def calculate_recurrent_unit(
      self,
      inputs: typing.Any,
      states: typing.Any,
      step: int,
      h: typing.Any,
  ) -> tuple:
      """
      Calculate recurrent unit.
  
      :param inputs: A TensorArray which contains interaction
          between left text and right text.
      :param states: A TensorArray which stores the hidden state
          of every step.
      :param step: Recurrent step.
      :param h: Hidden state from last operation.
      """
      # Get index i, j
      i = tf.math.floordiv(step, tf.constant(self._text2_maxlen))
      j = tf.math.mod(step, tf.constant(self._text2_maxlen))
  
      # Get hidden state h_diag, h_top, h_left
      # h_diag, h_top, h_left = [B, U]
      h_diag = states.read(i * (self._text2_maxlen + 1) + j)
      h_top = states.read(i * (self._text2_maxlen + 1) + j + 1)
      h_left = states.read((i + 1) * (self._text2_maxlen + 1) + j)
  
      # Get interaction between word i, j: s_ij
      # s_ij = [B, C]
      s_ij = inputs.read(step)
  
      # Concatenate h_top, h_left, h_diag, s_ij
      # q = [B, 3*U+C]
      q = tf.concat(
          [tf.concat([h_top, h_left], 1), tf.concat([h_diag, s_ij], 1)],
          1,
      )
  
      # Calculate reset gate
      # r = [B, 3*U]
      r = self._recurrent_activation(
          self._time_distributed_dense(self._wr, q, self._br)
      )
  
      # Calculate updating gate
      # z: [B, 4*U]
      z = self._time_distributed_dense(self._wz, q, self._bz)
  
      # Perform softmax
      # zi, zl, zt, zd: [B, U]
      zi, zl, zt, zd = self.softmax_by_row(z)
  
      # Get h_ij_
      # h_ij_ = [B, U]
      h_ij_l = self._time_distributed_dense(
          self._w_ij, s_ij, self._b_ij
      )
      h_ij_r = K.dot(
          r * (tf.concat([h_left, h_top, h_diag], 1)), self._U
      )
      h_ij_ = self._activation(h_ij_l + h_ij_r)
  
      # Calculate h_ij
      # h_ij = [B, U]
      h_ij = zl * h_left + zt * h_top + zd * h_diag + zi * h_ij_
  
      # Write h_ij to states
      states = states.write(
          ((i + 1) * (self._text2_maxlen + 1) + j + 1), h_ij
      )
      h_ij.set_shape(h_top.get_shape())
  
      return inputs, states, step + 1, h_ij
  
file_path: MatchZoo/matchzoo/contrib/layers/spatial_gru.py
imports: import typing
  import tensorflow
  from keras import backend
  from keras.engine import Layer
  from keras.layers import Permute
  from keras.layers import Reshape
  from keras import activations
  from keras import initializers
label_desc: Use image node_id 4 for calling the SpatialGRU obj's underlying member method code with example usage: obj.calculate_recurrent_unit(inputs, states, step, h) and returns: inputs,  states,  unknown,  h_ij