/// <summary>
        /// Calculate the current error.
        /// </summary>
        public void CalcError()
        {
            BackpropagationLayer next = this.backpropagation
                                        .GetBackpropagationLayer(this.layer.Next);

            for (int i = 0; i < this.layer.Next.NeuronCount; i++)
            {
                for (int j = 0; j < this.layer.NeuronCount; j++)
                {
                    AccumulateMatrixDelta(j, i, next.GetErrorDelta(i)
                                          * this.layer.GetFire(j));
                    SetError(j, GetError(j) + this.layer.LayerMatrix[j, i]
                             * next.GetErrorDelta(i));
                }
                AccumulateThresholdDelta(i, next.GetErrorDelta(i));
            }

            if (this.layer.IsHidden())
            {
                // hidden layer deltas
                for (int i = 0; i < this.layer.NeuronCount; i++)
                {
                    SetErrorDelta(i, BoundNumbers.Bound(CalculateDelta(i)));
                }
            }
        }
        /// <summary>
        /// Get the BackpropagationLayer that corresponds to the specified layer.
        /// </summary>
        /// <param name="layer">The specified layer.</param>
        /// <returns>The BackpropagationLayer that corresponds to the specified layer.</returns>
        public BackpropagationLayer GetBackpropagationLayer(
            FeedforwardLayer layer)
        {
            BackpropagationLayer result = this.layerMap[layer];

            if (result == null)
            {
                throw new NeuralNetworkError(
                          "Layer unknown to backpropagation trainer, was a layer added after training begain?");
            }

            return(result);
        }
        /// <summary>
        /// The rate at which the weight matrix will be adjusted based on
        /// learning.
        /// </summary>
        /// <param name="network">The neural network to be trained.</param>
        /// <param name="input">The input values to the neural network.</param>
        /// <param name="ideal">The ideal values expected from the neural network.</param>
        /// <param name="learnRate">The learning rate, how fast to modify neural network values.</param>
        /// <param name="momentum">The momentum, how much to use the previous training iteration for the current.</param>
        public Backpropagation(FeedforwardNetwork network,
                 double[][] input, double[][] ideal,
                 double learnRate, double momentum)
        {
            this.network = network;
            this.learnRate = learnRate;
            this.momentum = momentum;
            this.input = input;
            this.ideal = ideal;

            foreach (FeedforwardLayer layer in network.Layers)
            {
                BackpropagationLayer bpl = new BackpropagationLayer(this,
                       layer);
                this.layerMap.Add(layer, bpl);
            }
        }
        /// <summary>
        /// The rate at which the weight matrix will be adjusted based on
        /// learning.
        /// </summary>
        /// <param name="network">The neural network to be trained.</param>
        /// <param name="input">The input values to the neural network.</param>
        /// <param name="ideal">The ideal values expected from the neural network.</param>
        /// <param name="learnRate">The learning rate, how fast to modify neural network values.</param>
        /// <param name="momentum">The momentum, how much to use the previous training iteration for the current.</param>
        public Backpropagation(FeedforwardNetwork network,
                               double[][] input, double[][] ideal,
                               double learnRate, double momentum)
        {
            this.network   = network;
            this.learnRate = learnRate;
            this.momentum  = momentum;
            this.input     = input;
            this.ideal     = ideal;

            foreach (FeedforwardLayer layer in network.Layers)
            {
                BackpropagationLayer bpl = new BackpropagationLayer(this,
                                                                    layer);
                this.layerMap.Add(layer, bpl);
            }
        }