//установление заголовков для отчета по отключения нейронов в xlsx файл
        public static ExcelWorksheet setNeuronsWorkBookHeaders(ExcelWorksheet QualityWorkSheet, Record[] rangeNeurons)
        {
            for (int header = 0; header < rangeNeurons.Length; header++)
            {
                QualityWorkSheet.Cells[1, header + 2].Value = rangeNeurons[header].numberLayer.ToString() + ":" + rangeNeurons[header].numberNeuron.ToString();
            }
            QualityWorkSheet.Cells[1, rangeNeurons.Length + 2].Value = "Число отключенных нейронов";
            QualityWorkSheet.Cells[1, rangeNeurons.Length + 3].Value = "ЧОН/Нейронов всего";
            QualityWorkSheet.Cells[1, rangeNeurons.Length + 4].Value = "Соотношение нейронов";

            return QualityWorkSheet;
        }
        //установление заголовков для отчета по связям нейронов в xls файл
        public static ExcelWorksheet setWeightsWorkBookHeaders(ExcelWorksheet QualityWorkSheet, Record[] rangeNeurons)
        {
            int step = 1;
            for (int header = 0; header < rangeNeurons.Length; header++)
            {

                QualityWorkSheet.Cells[1, step + 1].Value = rangeNeurons[header].numberLayer.ToString() + ":" + rangeNeurons[header].numberNeuron.ToString() + "|Вх.";
                QualityWorkSheet.Cells[1, step + 2].Value = rangeNeurons[header].numberLayer.ToString() + ":" + rangeNeurons[header].numberNeuron.ToString() + "|Исх.";
                step += 2;
            }
            return QualityWorkSheet;
        }
        /// <summary>
        /// Computes output value of neuron.
        /// </summary>
        /// 
        /// <param name="input">Input vector.</param>
        /// 
        /// <returns>Returns neuron's output value.</returns>
        /// 
        /// <remarks><para>The output value of activation neuron is equal to value
        /// of nueron's activation function, which parameter is weighted sum
        /// of its inputs plus threshold value. The output value is also stored
        /// in <see cref="Neuron.Output">Output</see> property.</para>
        /// 
        /// <para><note>The method may be called safely from multiple threads to compute neuron's
        /// output value for the specified input values. However, the value of
        /// <see cref="Neuron.Output"/> property in multi-threaded environment is not predictable,
        /// since it may hold neuron's output computed from any of the caller threads. Multi-threaded
        /// access to the method is useful in those cases when it is required to improve performance
        /// by utilizing several threads and the computation is based on the immediate return value
        /// of the method, but not on neuron's output property.</note></para>
        /// </remarks>
        /// 
        /// <exception cref="ArgumentException">Wrong length of the input vector, which is not
        /// equal to the <see cref="Neuron.InputsCount">expected value</see>.</exception>
        /// 
        public override double Compute( double[] input )
        {
            this.relationsValues = new List<Record>();
            // check for corrent input vector
            if ( input.Length != inputsCount )
                throw new ArgumentException( "Wrong length of the input vector." );

            // initial sum value
            double sum = 0.0;

            // compute weighted sum of inputs
            for ( int i = 0; i < weights.Length; i++ )
            {
                sum += weights[i] * input[i];
                Record elem = new Record();
                elem.numberWeight = i;
                elem.value = weights[i] * input[i];
                this.relationsValues.Add(elem);
            }
            sum += threshold;

            // local variable to avoid mutlithreaded conflicts
            double output = function.Function( sum );
            // assign output property as well (works correctly for single threaded usage)
            this.output = output;

            return output;
        }