public void Given__ExampleWeightsFor221Net__HasExpectedFiringRatesAndOutput(double[] inputs, double[] inputToHidden, double[] hiddenToOutput, double expectedH0, double expectedH1, double expectedOutput)
            {
                var net = NeuralNet3LayerSigmoid.FromFlatWeightArrays(2, inputToHidden, hiddenToOutput);

                //
                net.ActivateInputs(inputs);
                net.HiddenLayer[0].FiringRate.ShouldBe(expectedH0, "Hidden 0 Firing Rate");
                net.HiddenLayer[1].FiringRate.ShouldBe(expectedH1, "Hidden 1 Firing Rate");
                net.OutputLayer[0].FiringRate.ShouldBe(expectedOutput, "Output 0 Firing Rate");
                net.OutputFor(inputs).ShouldBe(new ZeroToOne[] { expectedOutput });
            }
            public void Given__a221Network(double[] inputs, double[] inputToHidden, double[] hiddenToOutput)
            {
                var net = NeuralNet3LayerSigmoid.FromFlatWeightArrays(inputs.Length, inputToHidden, hiddenToOutput);

                net.InputToHidden[0, 0].ShouldBe(inputToHidden[0], "inputToHidden[0,0]");
                net.InputToHidden[0, 1].ShouldBe(inputToHidden[1], "inputToHidden[0,1]");
                net.InputToHidden[1, 0].ShouldBe(inputToHidden[2 + 0], "inputToHidden[1,0]");
                net.InputToHidden[1, 1].ShouldBe(inputToHidden[2 + 1], "inputToHidden[1,1]");
                net.HiddenToOutput.ShouldEqualByValue(new MatrixD(new[, ] {
                    { hiddenToOutput[0] }, { hiddenToOutput[1] }
                }), "HiddenToOutput");
            }
            public void Given__a323Network(double[] inputs, double[] inputToHidden, double[] hiddenToOutput)
            {
                var net = NeuralNet3LayerSigmoid.FromFlatWeightArrays(inputs.Length, inputToHidden, hiddenToOutput);

                net.InputToHidden[0, 0].ShouldBe(inputToHidden[0]);
                net.InputToHidden[0, 1].ShouldBe(inputToHidden[1]);
                net.InputToHidden[1, 0].ShouldBe(inputToHidden[2 + 0]);
                net.InputToHidden[1, 1].ShouldBe(inputToHidden[2 + 1]);
                net.InputToHidden[2, 0].ShouldBe(inputToHidden[4 + 0]);
                net.InputToHidden[2, 1].ShouldBe(inputToHidden[4 + 1]);

                net.HiddenToOutput[0, 0].ShouldBe(hiddenToOutput[0]);
                net.HiddenToOutput[0, 1].ShouldBe(hiddenToOutput[1]);
                net.HiddenToOutput[0, 2].ShouldBe(hiddenToOutput[2]);
                net.HiddenToOutput[1, 0].ShouldBe(hiddenToOutput[3 + 0]);
                net.HiddenToOutput[1, 1].ShouldBe(hiddenToOutput[3 + 1]);
                net.HiddenToOutput[1, 2].ShouldBe(hiddenToOutput[3 + 2]);

                net.HiddenLayer.ShouldAll(n => n.Bias.ShouldBe(0));
                net.OutputLayer.ShouldAll(n => n.Bias.ShouldBe(0));
            }
            public void Given__223_SigmoidNetwork(double[] inputs, double[] inputToHiddenWeights, double[] hiddenToOutputWeights, double target)
            {
                var net              = NeuralNet3LayerSigmoid.FromFlatWeightArrays(inputs.Length, inputToHiddenWeights, hiddenToOutputWeights);
                var targets          = Enumerable.Range(0, net.OutputLayer.Length).Select(i => (ZeroToOne)target);
                var calculatedDeltas = BackPropagationWithGradientDescent.DeltasFor(net, inputs, targets);

                var exOutputDelta1 = -0.040681125112339026d;
                var exOutputDelta2 = hiddenToOutputWeights[1].Equals(0) ? 0 : exOutputDelta1;
                var exOutputDelta3 = hiddenToOutputWeights[2].Equals(0) ? 0 : exOutputDelta1;
                var expected       = new DeltasFor2LayersOfNet
                {
                    OutputBiases  = new[] { 0d, 0d, 0d },
                    OutputWeights = new MatrixD(
                        new[, ]
                    {
                        { exOutputDelta1 *net.HiddenLayer[0].FiringRate, exOutputDelta2 *net.HiddenLayer[0].FiringRate, exOutputDelta3 *net.HiddenLayer[0].FiringRate },
                        { exOutputDelta1 *net.HiddenLayer[1].FiringRate, exOutputDelta2 *net.HiddenLayer[1].FiringRate, exOutputDelta3 *net.HiddenLayer[1].FiringRate }
                    }),
                };

                calculatedDeltas.OutputWeights.ShouldEqualByValue(expected.OutputWeights);
                calculatedDeltas.OutputBiases.ShouldEqualByValue(expected.OutputBiases);
            }
            public void Given__221_SigmoidNetwork(double[] inputs, double[] inputToHiddenWeights, double[] hiddenToOutputWeights, double target)
            {
                var net              = NeuralNet3LayerSigmoid.FromFlatWeightArrays(inputs.Length, inputToHiddenWeights, hiddenToOutputWeights);
                var targets          = Enumerable.Range(0, net.OutputLayer.Length).Select(i => (ZeroToOne)target);
                var calculatedDeltas = BackPropagationWithGradientDescent.DeltasFor(net, inputs, targets);

                /*
                 * 0.680267196698649d, 0.663738697404353d, 0.690283492907644d
                 */
                var exOutputDelta = -0.040681125112339026d;
                var expected      = new DeltasFor2LayersOfNet
                {
                    OutputBiases  = new[] { 0d },
                    OutputWeights = new MatrixD(
                        new[, ]
                    {
                        { exOutputDelta *net.HiddenLayer[0].FiringRate },
                        { exOutputDelta *net.HiddenLayer[1].FiringRate }
                    }),
                };

                calculatedDeltas.OutputWeights.ShouldEqualByValue(expected.OutputWeights);
                calculatedDeltas.OutputBiases.ShouldEqualByValue(expected.OutputBiases);
            }
            public void Given__221_SigmoidNetwork(double[] inputs, double[] inputToHiddenWeights, double[] hiddenToOutputWeights, double target)
            {
                var net              = NeuralNet3LayerSigmoid.FromFlatWeightArrays(inputs.Length, inputToHiddenWeights, hiddenToOutputWeights);
                var targets          = Enumerable.Range(0, net.OutputLayer.Length).Select(i => (ZeroToOne)target);
                var calculatedDeltas = BackPropagationWithGradientDescent.DeltasFor(net, inputs, targets);

                /*
                 * 0.680267196698649d, 0.663738697404353d, 0.690283492907644d
                 */
                var outputs              = net.LastOutputs.ToArray();
                var exOutputDelta        = -0.040681125112339026d;
                var exHiddenDelta0       = -0.0023685025015371172d;
                var exHiddenDelta1       = -0.0075927347073177845d;
                var expectedOutputDeltas = new DeltasFor2LayersOfNet
                {
                    OutputBiases  = new[] { 0d },
                    OutputWeights = new MatrixD(
                        new[, ]
                    {
                        { exOutputDelta *net.HiddenLayer[0].FiringRate },
                        { exOutputDelta *net.HiddenLayer[1].FiringRate }
                    }),
                    HiddenBiases  = new [] { 0d, 0d },
                    HiddenWeights = new MatrixD(
                        new[, ]
                    {
                        {
                            exHiddenDelta0 *net.HiddenLayer[0].Inputs[0].Source.FiringRate,
                            exHiddenDelta1 *net.HiddenLayer[1].Inputs[0].Source.FiringRate
                        },
                        {
                            exHiddenDelta0 *net.HiddenLayer[0].Inputs[1].Source.FiringRate,
                            exHiddenDelta1 *net.HiddenLayer[1].Inputs[1].Source.FiringRate
                        }
                    }),
                };
                var expectedDeltaValues = new DeltasFor2LayersOfNet
                {
                    OutputBiases  = new[] { 0d },
                    OutputWeights = new MatrixD(
                        new[, ]
                    {
                        { -0.027674034938717864 },     // -0.040681125112339026d *  0.680267196698649d +/- last two d.p.s
                        { -0.027001636991007407 }      // -0.040681125112339026d *  0.663738697404353d +/- last two d.p.s
                    }),
                    HiddenBiases  = new[] { 0d, 0d },
                    HiddenWeights = new MatrixD(
                        new[, ]
                    {
                        {
                            -0.000828975875537991d,
                            -0.0026574571475612243d
                        },
                        {
                            -0.0021316522513834054d,
                            -0.0068334612365860059d
                        }
                    }),
                };

                calculatedDeltas.OutputWeights.ShouldEqualByValue(expectedOutputDeltas.OutputWeights, "OutputWeights");
                calculatedDeltas.OutputBiases.ShouldEqualByValue(expectedOutputDeltas.OutputBiases, "OutputBiases");
                calculatedDeltas.HiddenWeights.ShouldEqualByValue(expectedOutputDeltas.HiddenWeights, "HiddenWeights");
                calculatedDeltas.HiddenBiases.ShouldEqualByValue(expectedOutputDeltas.HiddenBiases, "HiddenBiases");
                //
                expectedOutputDeltas.HiddenBiases.ShouldEqualByValue(expectedDeltaValues.HiddenBiases, "HiddenBiases");
                expectedOutputDeltas.OutputBiases.ShouldEqualByValue(expectedDeltaValues.OutputBiases, "OutputBiases");
                expectedOutputDeltas.HiddenWeights.ShouldEqualByValue(expectedDeltaValues.HiddenWeights, "HiddenWeights");
                expectedOutputDeltas.OutputWeights.ShouldEqualByValue(expectedDeltaValues.OutputWeights, "OutputWeights");
            }