public static DeltasFor2LayersOfNet DeltasFor(NeuralNet3LayerSigmoid net, IEnumerable <double> inputs, IEnumerable <ZeroToOne> targets)
        {
            var outputs      = net.OutputFor(inputs).ToArray();
            var outputDeltas = outputs
                               .Zip(targets, (o, target) => (target - o) * o * (1 - o))  /* see e.g. wikipedia https://en.wikipedia.org/wiki/Backpropagation#Derivation */
                               .ToArray();

            var outputWeightDeltas = new MatrixD(net.HiddenToOutput.RowCount, net.HiddenToOutput.ColumnCount);
            var hiddenDeltaParts   = new MatrixD(net.HiddenToOutput.RowCount, net.HiddenToOutput.ColumnCount);

            for (int i = 0; i < outputWeightDeltas.RowCount; i++)
            {
                for (int j = 0; j < outputWeightDeltas.ColumnCount; j++)
                {
                    outputWeightDeltas[i, j] = net.HiddenLayer[i].FiringRate * outputDeltas[j];
                    hiddenDeltaParts[i, j]   = outputDeltas[j] * (net.HiddenToOutput[i, j] + outputWeightDeltas[i, j]) * outputs[j] * (1 - outputs[j]);
                }
            }

            var hiddenDeltas       = hiddenDeltaParts.ByRows().Select(row => row.Sum()).ToArray();
            var hiddenWeightDeltas = new MatrixD(net.InputToHidden.RowCount, net.InputToHidden.ColumnCount);

            for (int i = 0; i < hiddenWeightDeltas.RowCount; i++)
            {
                for (int j = 0; j < hiddenWeightDeltas.ColumnCount; j++)
                {
                    hiddenWeightDeltas[i, j] = net.InputLayer[i].FiringRate * hiddenDeltas[j];
                }
            }
            return(new DeltasFor2LayersOfNet
            {
                OutputBiases = net.OutputLayer.Zip(outputDeltas, (neuron, delta) => neuron.Bias * delta).ToArray(),
                OutputWeights = outputWeightDeltas,
                HiddenBiases = net.HiddenLayer.Zip(hiddenDeltas, (neuron, delta) => neuron.Bias * delta).ToArray(),
                HiddenWeights = hiddenWeightDeltas
            });
        }