public void TestGaussian()
 {
     IRadialBasisFunction radial = new GaussianFunction(0.0, 1.0, 1.0);
     var bubble = new NeighborhoodRBF1D(radial);
     Assert.AreEqual(0.0, bubble.Function(5, 0), 0.1);
     Assert.AreEqual(1.0, bubble.Function(5, 5), 0.1);
     Assert.AreEqual(0.6, bubble.Function(5, 4), 0.1);
 }
        /// <summary>
        /// Prune one of the neurons from this layer. Remove all entries in this
        /// weight matrix and other layers. 
        /// </summary>
        /// <param name="targetLayer">The neuron to prune. Zero specifies the first neuron.</param>
        /// <param name="neuron">The neuron to prune.</param>
        public void Prune(ILayer targetLayer, int neuron)
        {
            // delete a row on this matrix
            foreach (ISynapse synapse in targetLayer.Next)
            {
                if (synapse.WeightMatrix != null)
                {
                    synapse.WeightMatrix =
                        MatrixMath.DeleteRow(synapse.WeightMatrix, neuron);
                }
            }

            // delete a column on the previous
            ICollection<ILayer> previous = this.network.Structure
                    .GetPreviousLayers(targetLayer);

            foreach (ILayer prevLayer in previous)
            {
                if (previous != null)
                {
                    foreach (ISynapse synapse in prevLayer.Next)
                    {
                        if (synapse.WeightMatrix != null)
                        {
                            synapse.WeightMatrix =
                                MatrixMath.DeleteCol(synapse.WeightMatrix,
                                    neuron);
                        }
                    }
                }
            }

            // remove the bias
            if (targetLayer.HasBias)
            {
                double[] newBias = new double[targetLayer
                        .NeuronCount - 1];

                int targetIndex = 0;
                for (int i = 0; i < targetLayer.NeuronCount; i++)
                {
                    if (i != neuron)
                    {
                        newBias[targetIndex++] = targetLayer.BiasWeights[i];
                    }
                }

                targetLayer.BiasWeights = newBias;
            }

            // adjust RBF
            if (targetLayer is RadialBasisFunctionLayer)
            {
                RadialBasisFunctionLayer rbf = (RadialBasisFunctionLayer)targetLayer;
                IRadialBasisFunction[] newRBF = new GaussianFunction[targetLayer
                        .NeuronCount - 1];

                int targetIndex = 0;
                for (int i = 0; i < targetLayer.NeuronCount; i++)
                {
                    if (i != neuron)
                    {
                        newRBF[targetIndex++] = rbf.RadialBasisFunction[i];
                    }
                }
                rbf.RadialBasisFunction = newRBF;

            }

            // update the neuron count
            targetLayer.NeuronCount -= 1;

        }
        /// <summary>
        /// Internal function to increase the neuron count. This will add a
        /// zero-weight neuron to this layer. 
        /// </summary>
        /// <param name="layer">The layer to increase.</param>
        /// <param name="neuronCount">The new neuron count.</param>
        private void IncreaseNeuronCount(ILayer layer, int neuronCount)
        {
            // adjust the bias
            double[] newBias = new double[neuronCount];
            if (layer.HasBias)
            {
                for (int i = 0; i < layer.NeuronCount; i++)
                {
                    newBias[i] = layer.BiasWeights[i];
                }

                layer.BiasWeights = newBias;
            }

            // adjust the outbound weight matrixes
            foreach (ISynapse synapse in layer.Next)
            {
                if (synapse.WeightMatrix != null)
                {
                    Matrix newMatrix = new Matrix(neuronCount, synapse
                            .ToNeuronCount);
                    // copy existing matrix to new matrix
                    for (int row = 0; row < layer.NeuronCount; row++)
                    {
                        for (int col = 0; col < synapse.ToNeuronCount; col++)
                        {
                            newMatrix[row, col] = synapse.WeightMatrix[row, col];
                        }
                    }
                    synapse.WeightMatrix = newMatrix;
                }
            }

            // adjust the inbound weight matrixes
            ICollection<ISynapse> inboundSynapses = this.network.Structure
                    .GetPreviousSynapses(layer);

            foreach (ISynapse synapse in inboundSynapses)
            {
                if (synapse.WeightMatrix != null)
                {
                    Matrix newMatrix = new Matrix(synapse.FromNeuronCount,
                            neuronCount);
                    // copy existing matrix to new matrix
                    for (int row = 0; row < synapse.FromNeuronCount; row++)
                    {
                        for (int col = 0; col < synapse.ToNeuronCount; col++)
                        {
                            newMatrix[row, col] = synapse.WeightMatrix[row, col];
                        }
                    }
                    synapse.WeightMatrix = newMatrix;
                }
            }

            // adjust the bias
            if (layer.HasBias)
            {
                double[] newBias2 = new double[neuronCount];

                for (int i = 0; i < layer.NeuronCount; i++)
                {
                    newBias2[i] = layer.BiasWeights[i];
                }
                layer.BiasWeights = newBias2;
            }

            // adjust RBF
            if (layer is RadialBasisFunctionLayer)
            {
                RadialBasisFunctionLayer rbf = (RadialBasisFunctionLayer)layer;
                IRadialBasisFunction[] newRBF = new IRadialBasisFunction[neuronCount];
                for (int i = 0; i < rbf.RadialBasisFunction.Length; i++)
                {
                    newRBF[i] = rbf.RadialBasisFunction[i];
                }

                for (int i = rbf.RadialBasisFunction.Length; i < neuronCount; i++)
                {
                    newRBF[i] = new GaussianFunction(ThreadSafeRandom.NextDouble() - 0.5,
                         ThreadSafeRandom.NextDouble(), ThreadSafeRandom.NextDouble() - 0.5);
                }

                rbf.RadialBasisFunction = newRBF;

            }

            // finally, up the neuron count
            layer.NeuronCount = neuronCount;
        }