unsafe static internal float ComputeWeightedErrorSum(ActivationLayerBackwardCompute backwardCompute, float* valueBuffer, int outputIndex)
        {
            Contract.Requires(backwardCompute != null);

            // Compute weighted error sum:
            float sum = 0.0f;

            if (backwardCompute.OutputErrorBuffer.HasValue) // This is the output layer
            {
                // External errors are set:
                int errorValueIndex = backwardCompute.OutputErrorBuffer.Value.MinValue + outputIndex;
                sum = valueBuffer[errorValueIndex];
            }

            foreach (var lowerErrorAccessItem in backwardCompute.LowerErrorValueAccessItems)
            {
                for (int outputErrorIndex = 0; outputErrorIndex < lowerErrorAccessItem.ErrorSize; outputErrorIndex++)
                {
                    int outputErrorValueIndex = lowerErrorAccessItem.ErrorBufferBeginIndex + outputErrorIndex;

                    sum += valueBuffer[outputErrorValueIndex] * valueBuffer[lowerErrorAccessItem.WeightBufferBeginIndex + WeightAccessor.GetWeightValueIndex(outputIndex, outputErrorIndex, lowerErrorAccessItem.ErrorSize)];
                }
            }
            return sum;
        }
        private static unsafe float ComputeError(ActivationLayerBackwardCompute backwardCompute, float* valueBuffer, int outputIndex)
        {
            float sum = ComputeWeightedErrorSum(backwardCompute, valueBuffer, outputIndex);

            // Compute error:
            return valueBuffer[backwardCompute.ErrorBuffer.Value.MinValue + outputIndex] =
                (sum * backwardCompute.Function.CalculateDerivate(valueBuffer[backwardCompute.ForwardCompute.OutputBuffer.MinValue + outputIndex]));
        }
 public void Initialize(ActivationLayerBackwardCompute backwardCompute)
 {
     this.backwardCompute = backwardCompute;
 }
        private static unsafe void SetGradients(ActivationLayerBackwardCompute backwardCompute, float* valueBuffer, int outputIndex, float error)
        {
            // Bias:
            valueBuffer[backwardCompute.BiasGradientValueIndex.Value] = error;
            valueBuffer[backwardCompute.BiasGradientSumValueIndex.Value] += error;

            // Inputs:
            int outputSize = backwardCompute.ForwardCompute.OutputBuffer.Size;
            int layerIndex = 0;
            fixed (IntRange* gradientBuffers = backwardCompute.GradientBuffers)
            fixed (IntRange* gradientSumBuffers = backwardCompute.GradientSumBuffers)
            {
                var gradientBuff = gradientBuffers[layerIndex];
                var gradientSumBuff = gradientSumBuffers[layerIndex];

                foreach (var inputAccess in backwardCompute.ForwardCompute.InputValueAccessItems)
                {
                    for (int inputIndex = 0; inputIndex < inputAccess.InputSize; inputIndex++)
                    {
                        int inputValueIndex = inputAccess.InputBufferBeginIndex + inputIndex;
                        float gradient = error * valueBuffer[inputValueIndex];

                        int wvIndex = WeightAccessor.GetWeightValueIndex(inputIndex, outputIndex, outputSize);
                        valueBuffer[gradientBuff.MinValue + wvIndex] = gradient;
                        valueBuffer[gradientSumBuff.MinValue + wvIndex] += gradient;
                    }

                    layerIndex++;
                }
            }
        }