protected void EstimateWeightSecondDerivative(RectangularStep upstream, RectangularStep downstream, int downstreamX, int downstreamY)
{
double weight2ndDerivative = 0;
int downstreamIndex = downstreamY * downstream.Width + downstreamX;
int upstreamIndex = (downstreamY * Height * upstream.Width) + downstreamX * Width;
double downstreamSecondDerivative = downstream.ErrorDerivative[downstreamIndex];
double upstreamSecondDerivative = Weight * Weight * downstreamSecondDerivative;
// This loop here is equivalent to the sigma in equation 19 in Gradient-Based Learning Applied to Document Recognition.
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
double upstreamState = upstream.Output[upstreamIndex];
// Here we calculate (d^2)Ej/(dWij)^2 by multiplying the 2nd derivative of E with respect to the sum of inputs, Ai
// by the state of Oi, the upstream unit, squared. Refer to Equation 25 in document.
// The summing happening here is described by equation 23.
weight2ndDerivative += downstreamSecondDerivative * upstreamState * upstreamState;
// This is implementing the last sigma of Equation 27.
// This propogates error second derivatives back to previous layer, but will need to be multiplied by the second derivative
// of the activation function at the previous layer.
upstream.ErrorDerivative[upstreamIndex] = upstreamSecondDerivative;
upstreamIndex += 1;
}
upstreamIndex += upstream.Width - Width;
}
WeightStepSize += weight2ndDerivative;
}