'Compute this layer\'s output function given a symbolic input variable
Parameters
inputs : list of theano.TensorType
`inputs[0]` should always be the symbolic input variable.  When
this layer has a mask input (i.e. was instantiated with
`mask_input != None`, indicating that the lengths of sequences in
each batch vary), `inputs` should have length 2, where `inputs[1]`
is the `mask`.  The `mask` should be supplied as a Theano variable
denoting whether each time step in each sequence in the batch is
part of the sequence or not.  `mask` should be a matrix of shape
``(n_batch, n_time_steps)`` where ``mask[i, j] = 1`` when ``j <=
(length of sequence i)`` and ``mask[i, j] = 0`` when ``j > (length
of sequence i)``. When the hidden state of this layer is to be
pre-filled (i.e. was set to a :class:`Layer` instance) `inputs`
should have length at least 2, and `inputs[-1]` is the hidden state
to prefill with. When the cell state of this layer is to be
pre-filled (i.e. was set to a :class:`Layer` instance) `inputs`
should have length at least 2, and `inputs[-1]` is the hidden state
to prefill with. When both the cell state and the hidden state are
being pre-filled `inputs[-2]` is the hidden state, while
`inputs[-1]` is the cell state.
Returns
layer_output : theano.TensorType
Symbolic output variable.'

def get_output_for(self, inputs, **kwargs):

    input = inputs[0]
    mask = None
    hid_init = None
    cell_init = None
    if (self.mask_incoming_index > 0):
        mask = inputs[self.mask_incoming_index]
    if (self.hid_init_incoming_index > 0):
        hid_init = inputs[self.hid_init_incoming_index]
    if (self.cell_init_incoming_index > 0):
        cell_init = inputs[self.cell_init_incoming_index]
    if (input.ndim > 3):
        input = T.flatten(input, 3)
    input = input.dimshuffle(1, 0, 2)
    (seq_len, num_batch, _) = input.shape
    W_in_stacked = T.concatenate([self.W_in_to_ingate, self.W_in_to_forgetgate, self.W_in_to_cell, self.W_in_to_outgate], axis=1)
    W_hid_stacked = T.concatenate([self.W_hid_to_ingate, self.W_hid_to_forgetgate, self.W_hid_to_cell, self.W_hid_to_outgate], axis=1)
    b_stacked = T.concatenate([self.b_ingate, self.b_forgetgate, self.b_cell, self.b_outgate], axis=0)
    if self.precompute_input:
        input = (T.dot(input, W_in_stacked) + b_stacked)
    def slice_w(x, n):
        s = x[:, (n * self.num_units):((n + 1) * self.num_units)]
        if (self.num_units == 1):
            s = T.addbroadcast(s, 1)
        return s
    def step(input_n, cell_previous, hid_previous, *args):
        if (not self.precompute_input):
            input_n = (T.dot(input_n, W_in_stacked) + b_stacked)
        gates = (input_n + T.dot(hid_previous, W_hid_stacked))
        if self.grad_clipping:
            gates = theano.gradient.grad_clip(gates, (- self.grad_clipping), self.grad_clipping)
        ingate = slice_w(gates, 0)
        forgetgate = slice_w(gates, 1)
        cell_input = slice_w(gates, 2)
        outgate = slice_w(gates, 3)
        if self.peepholes:
            ingate += (cell_previous * self.W_cell_to_ingate)
            forgetgate += (cell_previous * self.W_cell_to_forgetgate)
        ingate = self.nonlinearity_ingate(ingate)
        forgetgate = self.nonlinearity_forgetgate(forgetgate)
        cell_input = self.nonlinearity_cell(cell_input)
        cell = ((forgetgate * cell_previous) + (ingate * cell_input))
        if self.peepholes:
            outgate += (cell * self.W_cell_to_outgate)
        outgate = self.nonlinearity_outgate(outgate)
        hid = (outgate * self.nonlinearity(cell))
        return [cell, hid]
    def step_masked(input_n, mask_n, cell_previous, hid_previous, *args):
        (cell, hid) = step(input_n, cell_previous, hid_previous, *args)
        cell = T.switch(mask_n, cell, cell_previous)
        hid = T.switch(mask_n, hid, hid_previous)
        return [cell, hid]
    if (mask is not None):
        mask = mask.dimshuffle(1, 0, 'x')
        sequences = [input, mask]
        step_fun = step_masked
    else:
        sequences = input
        step_fun = step
    ones = T.ones((num_batch, 1))
    if (not isinstance(self.cell_init, Layer)):
        cell_init = T.dot(ones, self.cell_init)
    if (not isinstance(self.hid_init, Layer)):
        hid_init = T.dot(ones, self.hid_init)
    non_seqs = [W_hid_stacked]
    if self.peepholes:
        non_seqs += [self.W_cell_to_ingate, self.W_cell_to_forgetgate, self.W_cell_to_outgate]
    if (not self.precompute_input):
        non_seqs += [W_in_stacked, b_stacked]
    if self.unroll_scan:
        input_shape = self.input_shapes[0]
        (cell_out, hid_out) = unroll_scan(fn=step_fun, sequences=sequences, outputs_info=[cell_init, hid_init], go_backwards=self.backwards, non_sequences=non_seqs, n_steps=input_shape[1])
    else:
        (cell_out, hid_out) = theano.scan(fn=step_fun, sequences=sequences, outputs_info=[cell_init, hid_init], go_backwards=self.backwards, truncate_gradient=self.gradient_steps, non_sequences=non_seqs, strict=True)[0]
    if self.only_return_final:
        hid_out = hid_out[(-1)]
    else:
        hid_out = hid_out.dimshuffle(1, 0, 2)
        if self.backwards:
            hid_out = hid_out[:, ::(-1)]
    return hid_out
