# Path: reid/models/block.py
# class Block(object):
#     """Abstract base class for neural network layers and models"""
# 
#     def __init__(self):
#         self._params = []
# 
#     @property
#     def parameters(self):
#         return self._params
# 
#     @parameters.setter
#     def parameters(self, value):
#         self._params = value
# 
#     def get_output(self, x):
#         raise NotImplementedError
# 
#     def get_regularization(self, l):
#         return 0
# 
# Path: reid/models/active_functions.py
# def identity(x):
# def rectifier(x):
# 
# Path: reid/utils/math_utils.py
# def cell(default, *args):


import numpy
import theano
import theano.tensor as T
from reid.models.block import Block
from reid.models import active_functions as actfuncs
from reid.utils.math_utils import numpy_rng
                 image_shape=None, active_func=None,
                 flatten=False, through=False):
        """Initialize the convolutional and max-pooling layer

        Args:
            filter_shape: 4D-tensor, (n_filters, n_channels, n_rows, n_cols)
            pool_shape: 2D-tensor, (n_rows, n_cols)
            image_shape: None if the input is always 4D-tensor, (n_images,
                n_channels, n_rows, n_cols). If the input images are represented
                as vectors, then a 3D-tensor, (n_channels, n_rows, n_cols) is
                required.
            active_func: Active function of this layer
            flatten: True if the output image should be flattened as a vector
            through: True if the output should be passed through
        """

        super(ConvPoolLayer, self).__init__()

        self._filter_shape = filter_shape
        self._pool_shape = pool_shape
        self._image_shape = image_shape
        self._active_func = active_func
        self._flatten = flatten
        self._through = through

        fan_in = numpy.prod(filter_shape[1:])
        fan_out = filter_shape[0] * numpy.prod(filter_shape[2:]) / numpy.prod(pool_shape)

        W_bound = numpy.sqrt(6.0 / (fan_in + fan_out))


# Path: reid/models/block.py
# class Block(object):
#     """Abstract base class for neural network layers and models"""
# 
#     def __init__(self):
#         self._params = []
# 
#     @property
#     def parameters(self):
#         return self._params
# 
#     @parameters.setter
#     def parameters(self, value):
#         self._params = value
# 
#     def get_output(self, x):
#         raise NotImplementedError
# 
#     def get_regularization(self, l):
#         return 0
# 
# Path: reid/models/active_functions.py
# def identity(x):
# def rectifier(x):
# 
# Path: reid/utils/math_utils.py
# def cell(default, *args):


# Path: reid/models/layers.py
import numpy
import theano
import theano.tensor as T
from reid.models.block import Block
from reid.models import active_functions as actfuncs
from reid.utils.math_utils import numpy_rng

                 image_shape=None, active_func=None,
                 flatten=False, through=False):
        """Initialize the convolutional and max-pooling layer

        Args:
            filter_shape: 4D-tensor, (n_filters, n_channels, n_rows, n_cols)
            pool_shape: 2D-tensor, (n_rows, n_cols)
            image_shape: None if the input is always 4D-tensor, (n_images,
                n_channels, n_rows, n_cols). If the input images are represented
                as vectors, then a 3D-tensor, (n_channels, n_rows, n_cols) is
                required.
            active_func: Active function of this layer
            flatten: True if the output image should be flattened as a vector
            through: True if the output should be passed through
        """

        super(ConvPoolLayer, self).__init__()

        self._filter_shape = filter_shape
        self._pool_shape = pool_shape
        self._image_shape = image_shape
        self._active_func = active_func
        self._flatten = flatten
        self._through = through

        fan_in = numpy.prod(filter_shape[1:])
        fan_out = filter_shape[0] * numpy.prod(filter_shape[2:]) / numpy.prod(pool_shape)

        W_bound = numpy.sqrt(6.0 / (fan_in + fan_out))


        if active_func == actfuncs.sigmoid: W_bound *= 4