protected void PropogateError(RectangularStep upstream, RectangularStep downstream, int weightX, int weightY, int mapNumber)
{
int weightIndex = mapNumber * Width * Height + weightY * Width + weightX;
double weight = Weight[weightIndex];
int downstreamIndex = 0;
double weightError = 0.0;
int upstreamIndex = (weightY * upstream.Width) + weightX;
double weightStepSize = WeightStepSize[weightIndex];
// This loop here is equivalent to the sigma in equation 19 in Gradient-Based Learning Applied to Document Recognition.
for (int y = 0; y < downstream.Height; y++)
{
for (int x = 0; x < downstream.Width; x++)
{
double upstreamState = upstream.Output[upstreamIndex];
double downstreamErrorDerivative = downstream.ErrorDerivative[downstreamIndex];
// Calculate inputs error gradient by taking the sum, for all outputs of
// dEk/dAj multiplied by dAj/dOj (w/sum =dEj/dOj);
double inputError = downstreamErrorDerivative * weight;
upstream.ErrorDerivative[upstreamIndex] += inputError;
// Calculate the Weight's first derivative with respect to the error
double weightErrorGradient = downstreamErrorDerivative * upstreamState;
weightError += weightErrorGradient;
downstreamIndex += 1;
upstreamIndex += 1;
}
upstreamIndex += Width - 1; // Equal to: upstream.Width - downstream.Width;
}
double deltaWeight = weightError * weightStepSize;
Weight[weightIndex] -= deltaWeight;
}