public PoolingLayer(LayerConnection inputConnection, Filter mask, int stride, PoolingMethod method)
        {
            model     = new MatrixModel(inputConnection.length, stride);
            this.mask = mask;

            nodes = new DepthList <PoolingNode>(inputConnection.depth);

            int filterOutputsCount = model.filterOutputsCount(mask);
            int filterLineCount    = model.filterLineCount(mask);

            for (int d = 0; d < inputConnection.depth; d++)
            {
                for (int i = 0; i < filterOutputsCount; i++)
                {
                    List <Unit> inputUnits = new List <Unit>();

                    for (int x = 0; x < mask.count; x++)
                    {
                        int inner = x % mask.size + x / mask.size * model.size;
                        int outer = i % filterLineCount + i / filterLineCount * model.size;

                        inputUnits.Add(inputConnection[inner + outer, d]);
                    }

                    nodes.Add(new PoolingNode(inputUnits, method));
                }
            }

            input = new PoolingLayerConnection(nodes);
        }
        public ConvolutionalLayer(LayerConnection inputConnection, Filter filter, int filtersAmount, int stride,
                                  ActivationFunction activationFunction)
        {
            kernels = new List <List <Filter> >();
            model   = new MatrixModel(inputConnection.length, stride);

            for (int f = 0; f < filtersAmount; f++)
            {
                kernels.Add(new List <Filter>());

                for (int d = 0; d < inputConnection.depth; d++)
                {
                    kernels[f].Add((Filter)filter.Clone());
                }
            }

            neurons = new DepthList <ConvolutionalNeuron>(filtersAmount * inputConnection.depth);

            for (int f = 0; f < filtersAmount; f++)
            {
                for (int d = 0; d < inputConnection.depth; d++)
                {
                    for (int o = 0; o < model.filterOutputsCount(filter); o++)
                    {
                        List <int> indexes = new List <int>();

                        for (int x = 0; x < filter.count; x++)
                        {
                            int inner = x % filter.size + x / filter.size * model.size;
                            int outer = o % model.filterLineCount(filter) + o / model.filterLineCount(filter) * model.size;

                            indexes.Add(inner + outer);
                        }

                        List <Unit> inputUnits = new List <Unit>(inputConnection.length);

                        for (int i = inputConnection.depth * inputConnection.length;
                             i < (inputConnection.depth + 1) * inputConnection.length; i++)
                        {
                            inputUnits.Add(inputConnection[i]);
                        }

                        neurons.Add(new ConvolutionalNeuron(inputUnits, kernels[f][d], indexes, activationFunction));
                    }
                }
            }

            input = new ConvolutionalLayerConnection(neurons);
        }