# Path: emolga/layers/core.py
# class Layer(object):
#     def __init__(self):
#         self.params  = []
#         self.layers  = []
#         self.monitor = {}
#         self.watchlist = []
# 
#     def init_updates(self):
#         self.updates = []
# 
#     def _monitoring(self):
#         # add monitoring variables
#         for l in self.layers:
#             for v in l.monitor:
#                 name = v + '@' + l.name
#                 print(name)
#                 self.monitor[name] = l.monitor[v]
# 
#     def __call__(self, X, *args, **kwargs):
#         return X
# 
#     def _add(self, layer):
#         if layer:
#             self.layers.append(layer)
#             self.params += layer.params
# 
#     def supports_masked_input(self):
#         ''' Whether or not this layer respects the output mask of its previous layer in its calculations. If you try
#         to attach a layer that does *not* support masked_input to a layer that gives a non-None output_mask() that is
#         an error'''
#         return False
# 
#     def get_output_mask(self, train=None):
#         '''
#         For some models (such as RNNs) you want a way of being able to mark some output data-points as
#         "masked", so they are not used in future calculations. In such a model, get_output_mask() should return a mask
#         of one less dimension than get_output() (so if get_output is (nb_samples, nb_timesteps, nb_dimensions), then the mask
#         is (nb_samples, nb_timesteps), with a one for every unmasked datapoint, and a zero for every masked one.
# 
#         If there is *no* masking then it shall return None. For instance if you attach an Activation layer (they support masking)
#         to a layer with an output_mask, then that Activation shall also have an output_mask. If you attach it to a layer with no
#         such mask, then the Activation's get_output_mask shall return None.
# 
#         Some emolga have an output_mask even if their input is unmasked, notably Embedding which can turn the entry "0" into
#         a mask.
#         '''
#         return None
# 
#     def set_weights(self, weights):
#         for p, w in zip(self.params, weights):
#             if p.eval().shape != w.shape:
#                 raise Exception("Layer shape %s not compatible with weight shape %s." % (p.eval().shape, w.shape))
#             p.set_value(floatX(w))
# 
#     def get_weights(self):
#         weights = []
#         for p in self.params:
#             weights.append(p.get_value())
#         return weights
# 
#     def get_params(self):
#         return self.params
# 
#     def set_name(self, name):
#         for i in range(len(self.params)):
#             if self.params[i].name is None:
#                 self.params[i].name = '%s_p%d' % (name, i)
#             else:
#                 self.params[i].name = name + '_' + self.params[i].name
#         self.name = name


from .core import Layer
from emolga.utils.theano_utils import *
import emolga.basic.initializations as initializations
            assert context.ndim == 3
            flag  = False
            if X.ndim == 1:
                flag = True
                X = X[:, None]

            b_size = context.shape[0]

            EMB = T.repeat(self.W[None, :, :], b_size, axis=0)
            EMB = T.concatenate([EMB, context], axis=1)

            m_size = EMB.shape[1]
            e_size = EMB.shape[2]
            maxlen = X.shape[1]

            EMB = EMB.reshape((b_size * m_size, e_size))
            Z   = (T.arange(b_size)[:, None] * m_size + X).reshape((b_size * maxlen,))
            out = EMB[Z]  # (b_size * maxlen, e_size)

            if not flag:
                out = out.reshape((b_size, maxlen, e_size))
            else:
                out = out.reshape((b_size, e_size))

        if mask_zero:
            return out, T.cast(self.get_output_mask(X), dtype='float32')
        else:
            return out



# Path: emolga/layers/core.py
# class Layer(object):
#     def __init__(self):
#         self.params  = []
#         self.layers  = []
#         self.monitor = {}
#         self.watchlist = []
# 
#     def init_updates(self):
#         self.updates = []
# 
#     def _monitoring(self):
#         # add monitoring variables
#         for l in self.layers:
#             for v in l.monitor:
#                 name = v + '@' + l.name
#                 print(name)
#                 self.monitor[name] = l.monitor[v]
# 
#     def __call__(self, X, *args, **kwargs):
#         return X
# 
#     def _add(self, layer):
#         if layer:
#             self.layers.append(layer)
#             self.params += layer.params
# 
#     def supports_masked_input(self):
#         ''' Whether or not this layer respects the output mask of its previous layer in its calculations. If you try
#         to attach a layer that does *not* support masked_input to a layer that gives a non-None output_mask() that is
#         an error'''
#         return False
# 
#     def get_output_mask(self, train=None):
#         '''
#         For some models (such as RNNs) you want a way of being able to mark some output data-points as
#         "masked", so they are not used in future calculations. In such a model, get_output_mask() should return a mask
#         of one less dimension than get_output() (so if get_output is (nb_samples, nb_timesteps, nb_dimensions), then the mask
#         is (nb_samples, nb_timesteps), with a one for every unmasked datapoint, and a zero for every masked one.
# 
#         If there is *no* masking then it shall return None. For instance if you attach an Activation layer (they support masking)
#         to a layer with an output_mask, then that Activation shall also have an output_mask. If you attach it to a layer with no
#         such mask, then the Activation's get_output_mask shall return None.
# 
#         Some emolga have an output_mask even if their input is unmasked, notably Embedding which can turn the entry "0" into
#         a mask.
#         '''
#         return None
# 
#     def set_weights(self, weights):
#         for p, w in zip(self.params, weights):
#             if p.eval().shape != w.shape:
#                 raise Exception("Layer shape %s not compatible with weight shape %s." % (p.eval().shape, w.shape))
#             p.set_value(floatX(w))
# 
#     def get_weights(self):
#         weights = []
#         for p in self.params:
#             weights.append(p.get_value())
#         return weights
# 
#     def get_params(self):
#         return self.params
# 
#     def set_name(self, name):
#         for i in range(len(self.params)):
#             if self.params[i].name is None:
#                 self.params[i].name = '%s_p%d' % (name, i)
#             else:
#                 self.params[i].name = name + '_' + self.params[i].name
#         self.name = name


# Path: emolga/layers/embeddings.py
from .core import Layer
from emolga.utils.theano_utils import *
import emolga.basic.initializations as initializations

            assert context.ndim == 3
            flag  = False
            if X.ndim == 1:
                flag = True
                X = X[:, None]

            b_size = context.shape[0]

            EMB = T.repeat(self.W[None, :, :], b_size, axis=0)
            EMB = T.concatenate([EMB, context], axis=1)

            m_size = EMB.shape[1]
            e_size = EMB.shape[2]
            maxlen = X.shape[1]

            EMB = EMB.reshape((b_size * m_size, e_size))
            Z   = (T.arange(b_size)[:, None] * m_size + X).reshape((b_size * maxlen,))
            out = EMB[Z]  # (b_size * maxlen, e_size)

            if not flag:
                out = out.reshape((b_size, maxlen, e_size))
            else:
                out = out.reshape((b_size, e_size))

        if mask_zero:
            return out, T.cast(self.get_output_mask(X), dtype='float32')
        else:
            return out



class Zero(Layer):