private double CalculateError(double[] desiredOutput)
{
// current and the next layers
Layer layer, layerNext;
// current and the next errors arrays
double[] errors, errorsNext;
// error values
double error = 0, e, sum;
// neuron's output value
double output;
// layers count
int layersCount = network.Layers.Length;
// assume, that all neurons of the network have the same activation function
IActivationFunction function = (network.Layers[0].Neurons[0] as ActivationNeuron).ActivationFunction;
// calculate error values for the last layer first
layer = network.Layers[layersCount - 1];
errors = neuronErrors[layersCount - 1];
for (int i = 0; i < layer.Neurons.Length; i++)
{
output = layer.Neurons[i].Output;
// error of the neuron
e = desiredOutput[i] - output;
// error multiplied with activation function's derivative
errors[i] = e * function.Derivative2(output);
// squre the error and sum it
error += (e * e);
}
// calculate error values for other layers
for (int j = layersCount - 2; j >= 0; j--)
{
layer = network.Layers[j];
layerNext = network.Layers[j + 1];
errors = neuronErrors[j];
errorsNext = neuronErrors[j + 1];
// for all neurons of the layer
for (int i = 0; i < layer.Neurons.Length; i++)
{
sum = 0.0;
// for all neurons of the next layer
for (int k = 0; k < layerNext.Neurons.Length; k++)
{
sum += errorsNext[k] * layerNext.Neurons[k].Weights[i];
}
errors[i] = sum * function.Derivative2(layer.Neurons[i].Output);
}
}
// return squared error of the last layer divided by 2
return error / 2.0;
}