public override NeuralNetDNA <T> crossover(NeuralNetDNA <T> p_crossover_object)
                {
                    //CAN optimize with another private function. CLone copies all weights then they get overriden
                    NeuralNetDNA <T> crossovered = Clone();

                    for (int i = 0; i < m_weights.Length; i++)
                    {
                        crossovered.m_weights[i] = MatrixCalc.crossover(m_weights[i], p_crossover_object.m_weights[i]);
                    }

                    return(crossovered);
                }
                public override NeuralNetDNA <T> mutate()
                {
                    NeuralNetDNA <T> mutated = Clone();

                    for (int i = 0; i < m_weights.Length; i++)
                    {
                        bool          test = BoolCalc.random();
                        Range <float> mut  = test ? m_mutation_multiplier : new Range <float>(-m_mutation_multiplier.Min, -m_mutation_multiplier.Max);
                        mutated.m_weights[i] = MatrixCalc.elementwiseRandomMultiply(m_weights[i], mut);
                    }

                    return(mutated);
                }
                public NeuralNetDNA <T> Clone()
                {
                    NeuralNetDNA <T> clone = new NeuralNetDNA <T>(m_id, m_inputs, m_outputs, m_mutation_multiplier);

                    clone.m_weights = new Matrix <float> [m_weights.Length];

                    for (int i = 0; i < m_weights.Length; i++)
                    {
                        clone.m_weights[i] = MatrixCalc.shallowClone(m_weights[i]);
                    }

                    return(clone);
                }
 public MindBodyNNDNA(int p_species_id, TraitGenesDNA p_body, NeuralNetDNA <T> p_mind)
 {
     m_species_id = p_species_id;
     m_body       = p_body.Clone();
     m_mind       = p_mind.Clone();
 }