final int toLayerIndex = this.layerIndex[currentLevel];
final int fromLayerSize = this.layerCounts[currentLevel + 1];
final int toLayerSize = this.layerFeedCounts[currentLevel];
final int index = this.weightIndex[currentLevel];
final ActivationFunction activation = this.network
.getActivationFunctions()[currentLevel];
final double currentFlatSpot = this.flatSpot[currentLevel + 1];
// handle weights
// array references are made method local to avoid one indirection
final double[] layerDelta = this.layerDelta;
final double[] weights = this.weights;
final double[] gradients = this.gradients;
final double[] layerOutput = this.layerOutput;
final double[] layerSums = this.layerSums;
int yi = fromLayerIndex;
for (int y = 0; y < fromLayerSize; y++) {
final double output = layerOutput[yi];
double sum = 0;
int wi = index + y;
final int loopEnd = toLayerIndex+toLayerSize;
for (int xi = toLayerIndex; xi < loopEnd; xi++, wi += fromLayerSize) {
gradients[wi] += output * layerDelta[xi];
sum += weights[wi] * layerDelta[xi];
}
layerDelta[yi] = sum
* (activation.derivativeFunction(layerSums[yi], layerOutput[yi])+currentFlatSpot);
yi++;
}
}