'Gated recurrent unit (GRU) function.
Args:
inputs: A 2D batch x input_dim tensor of inputs.
state: The previous state from the last time step.
scope (optional): TF variable scope for defined GRU variables.
Returns:
A tuple (state, state), where state is the newly computed state at time t.
It is returned twice to respect an interface that works for LSTMs.'

def __call__(self, inputs, state, scope=None):

    x = inputs
    h = state
    with tf.variable_scope((scope or type(self).__name__)):
        with tf.variable_scope('Gates'):
            r_x = u_x = 0.0
            if (x is not None):
                (r_x, u_x) = tf.split(axis=1, num_or_size_splits=2, value=linear(x, (2 * self._num_units), alpha=self._input_weight_scale, do_bias=False, name='x_2_ru', normalized=False, collections=self._input_collections))
            (r_h, u_h) = tf.split(axis=1, num_or_size_splits=2, value=linear(h, (2 * self._num_units), do_bias=True, alpha=self._rec_weight_scale, name='h_2_ru', collections=self._rec_collections))
            r = (r_x + r_h)
            u = (u_x + u_h)
            (r, u) = (tf.sigmoid(r), tf.sigmoid((u + self._forget_bias)))
        with tf.variable_scope('Candidate'):
            c_x = 0.0
            if (x is not None):
                c_x = linear(x, self._num_units, name='x_2_c', do_bias=False, alpha=self._input_weight_scale, normalized=False, collections=self._input_collections)
            c_rh = linear((r * h), self._num_units, name='rh_2_c', do_bias=True, alpha=self._rec_weight_scale, collections=self._rec_collections)
            c = tf.tanh((c_x + c_rh))
        new_h = ((u * h) + ((1 - u) * c))
        new_h = tf.clip_by_value(new_h, (- self._clip_value), self._clip_value)
    return (new_h, new_h)
