# Path: scripts/keras/keras/layers/core.py
# class Layer(object):
#     def __init__(self):
#         self.params = []
# 
#     def connect(self, node):
#         self.previous = node
# 
#     def get_output(self, train):
#         raise NotImplementedError
# 
#     def get_input(self, train):
#         if hasattr(self, 'previous'):
#             return self.previous.get_output(train=train)
#         else:
#             return self.input
# 
#     def set_weights(self, weights):
#         for p, w in zip(self.params, weights):
#             p.set_value(floatX(w))
# 
#     def get_weights(self):
#         weights = []
#         for p in self.params:
#             weights.append(p.get_value())
#         return weights
# 
#     def get_config(self):
#         return {"name":self.__class__.__name__}


import theano
import theano.tensor as T
import numpy as np
from .. import activations, initializations
from ..utils.theano_utils import shared_zeros, alloc_zeros_matrix
from ..layers.core import Layer
from six.moves import range
        x = T.dot(X, self.W) + self.b
        
        outputs, updates = theano.scan(
            self._step,
            sequences=x,
            outputs_info=[dict(
                initial=T.alloc(np.cast[theano.config.floatX](0.), self.depth, X.shape[1], self.output_dim), 
                taps = [(-i-1) for i in range(self.depth)]
            )],
            non_sequences=self.Us,
            truncate_gradient=self.truncate_gradient
        )
        if self.return_sequences:
            return outputs.dimshuffle((1,0,2))
        return outputs[-1]

    def get_config(self):
        return {"name":self.__class__.__name__,
            "input_dim":self.input_dim,
            "output_dim":self.output_dim,
            "depth":self.depth,
            "init":self.init.__name__,
            "inner_init":self.inner_init.__name__,
            "activation":self.activation.__name__,
            "inner_activation":self.inner_activation.__name__,
            "truncate_gradient":self.truncate_gradient,
            "return_sequences":self.return_sequences}




# Path: scripts/keras/keras/layers/core.py
# class Layer(object):
#     def __init__(self):
#         self.params = []
# 
#     def connect(self, node):
#         self.previous = node
# 
#     def get_output(self, train):
#         raise NotImplementedError
# 
#     def get_input(self, train):
#         if hasattr(self, 'previous'):
#             return self.previous.get_output(train=train)
#         else:
#             return self.input
# 
#     def set_weights(self, weights):
#         for p, w in zip(self.params, weights):
#             p.set_value(floatX(w))
# 
#     def get_weights(self):
#         weights = []
#         for p in self.params:
#             weights.append(p.get_value())
#         return weights
# 
#     def get_config(self):
#         return {"name":self.__class__.__name__}


# Path: scripts/keras/keras/layers/recurrent.py
import theano
import theano.tensor as T
import numpy as np
from .. import activations, initializations
from ..utils.theano_utils import shared_zeros, alloc_zeros_matrix
from ..layers.core import Layer
from six.moves import range

        x = T.dot(X, self.W) + self.b
        
        outputs, updates = theano.scan(
            self._step,
            sequences=x,
            outputs_info=[dict(
                initial=T.alloc(np.cast[theano.config.floatX](0.), self.depth, X.shape[1], self.output_dim), 
                taps = [(-i-1) for i in range(self.depth)]
            )],
            non_sequences=self.Us,
            truncate_gradient=self.truncate_gradient
        )
        if self.return_sequences:
            return outputs.dimshuffle((1,0,2))
        return outputs[-1]

    def get_config(self):
        return {"name":self.__class__.__name__,
            "input_dim":self.input_dim,
            "output_dim":self.output_dim,
            "depth":self.depth,
            "init":self.init.__name__,
            "inner_init":self.inner_init.__name__,
            "activation":self.activation.__name__,
            "inner_activation":self.inner_activation.__name__,
            "truncate_gradient":self.truncate_gradient,
            "return_sequences":self.return_sequences}




class GRU(Layer):