/// <summary>
        /// Calculates the back1.
        /// </summary>
        /// <param name="function">The function.</param>
        /// <param name="stepSize">Size of the step.</param>
        /// <param name="point">The point.</param>
        /// <param name="i">The i.</param>
        /// <returns>System.Double.</returns>
        private double calcBack1(IOptFunction function, double stepSize, double[] point, int i)
        {
            var backStep = (double[])point.Clone();

            backStep[i] -= stepSize;
            return((calculate(function, point) - calculate(function, backStep)) / stepSize);
        }
        /// <summary>
        /// Calculates the forward1.
        /// </summary>
        /// <param name="function">The function.</param>
        /// <param name="stepSize">Size of the step.</param>
        /// <param name="point">The point.</param>
        /// <param name="i">The i.</param>
        /// <returns>System.Double.</returns>
        private double calcForward1(IOptFunction function, double stepSize, double[] point, int i)
        {
            var forStep = (double[])point.Clone();

            forStep[i] += stepSize;
            return((calculate(function, forStep) - calculate(function, point)) / stepSize);
        }
        /// <summary>
        /// Calculates the derivative with respect to variable xi
        /// for the specified function.
        /// </summary>
        /// <param name="function">The function.</param>
        /// <param name="point">The point.</param>
        /// <param name="i">The index of the variable in x.</param>
        /// <returns>System.Double.</returns>
        public double deriv_wrt_xi(IOptFunction function, double[] point, int i)
        {
            switch (functionData[function].findDerivBy)
            {
            case differentiate.Analytic:
                return(((IDifferentiable)function).deriv_wrt_xi(point, i));

            case differentiate.Back1:
                return(calcBack1(function, functionData[function].finiteDiffStepSize, point, i));

            case differentiate.Forward1:
                return(calcForward1(function, functionData[function].finiteDiffStepSize, point, i));

            case differentiate.Central2:
                return(calcCentral2(function, functionData[function].finiteDiffStepSize, point, i));

            case differentiate.Back2:
                return(calcBack2(function, functionData[function].finiteDiffStepSize, point, i));

            case differentiate.Forward2:
                return(calcForward2(function, functionData[function].finiteDiffStepSize, point, i));

            case differentiate.Central4:
                return(calcCentral4(function, functionData[function].finiteDiffStepSize, point, i));
            }
            return(double.NaN);
        }
        /// <summary>
        /// Calculates the central2.
        /// </summary>
        /// <param name="function">The function.</param>
        /// <param name="stepSize">Size of the step.</param>
        /// <param name="point">The point.</param>
        /// <param name="i">The i.</param>
        /// <returns>System.Double.</returns>
        private double calcCentral2(IOptFunction function, double stepSize, double[] point, int i)
        {
            var forStep  = (double[])point.Clone();
            var backStep = (double[])point.Clone();

            forStep[i]  += stepSize;
            backStep[i] -= stepSize;
            return((calculate(function, forStep) - calculate(function, backStep)) / (2 * stepSize));
        }
        /// <summary>
        /// Calculates the forward2.
        /// </summary>
        /// <param name="function">The function.</param>
        /// <param name="stepSize">Size of the step.</param>
        /// <param name="point">The point.</param>
        /// <param name="i">The i.</param>
        /// <returns>System.Double.</returns>
        private double calcForward2(IOptFunction function, double stepSize, double[] point, int i)
        {
            var forStep1 = (double[])point.Clone();

            forStep1[i] += stepSize;

            var forStep2 = (double[])point.Clone();

            forStep2[i] += 2 * stepSize;
            return((-3 * calculate(function, point) + 4 * calculate(function, forStep1) - calculate(function, forStep2))
                   / (2 * stepSize));
        }
        /// <summary>
        /// Calculates the back2.
        /// </summary>
        /// <param name="function">The function.</param>
        /// <param name="stepSize">Size of the step.</param>
        /// <param name="point">The point.</param>
        /// <param name="i">The i.</param>
        /// <returns>System.Double.</returns>
        private double calcBack2(IOptFunction function, double stepSize, double[] point, int i)
        {
            var backStep1 = (double[])point.Clone();

            backStep1[i] -= stepSize;

            var backStep2 = (double[])point.Clone();

            backStep2[i] -= 2 * stepSize;
            return((calculate(function, backStep2) - 4 * calculate(function, backStep1) + 3 * calculate(function, point))
                   / (2 * stepSize));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="RecentFunctionEvalStore"/> class.
 /// </summary>
 /// <param name="function">The function.</param>
 /// <param name="comparer">The comparer.</param>
 /// <param name="finiteDiffStepSize">Size of the finite difference step.</param>
 /// <param name="findDerivBy">The find deriv by.</param>
 internal RecentFunctionEvalStore(IOptFunction function, IEqualityComparer <double[]> comparer,
                                  double finiteDiffStepSize, differentiate findDerivBy)
 {
     if (function is IDifferentiable)
     {
         this.findDerivBy = differentiate.Analytic;
     }
     else
     {
         this.finiteDiffStepSize = finiteDiffStepSize;
         this.findDerivBy        = findDerivBy;
     }
     oldEvaluations = new Dictionary <double[], double>(comparer);
     queue          = new Queue <double[]>();
 }
        /// <summary>
        /// Calculates the central4.
        /// </summary>
        /// <param name="function">The function.</param>
        /// <param name="stepSize">Size of the step.</param>
        /// <param name="point">The point.</param>
        /// <param name="i">The i.</param>
        /// <returns>System.Double.</returns>
        private double calcCentral4(IOptFunction function, double stepSize, double[] point, int i)
        {
            var forStep1 = (double[])point.Clone();

            forStep1[i] += stepSize;
            var forStep2 = (double[])point.Clone();

            forStep2[i] += 2 * stepSize;
            var backStep1 = (double[])point.Clone();

            backStep1[i] -= stepSize;
            var backStep2 = (double[])point.Clone();

            backStep2[i] -= 2 * stepSize;
            return((calculate(function, backStep2) - 8 * calculate(function, backStep1)
                    + 8 * calculate(function, forStep1) - calculate(function, forStep2)) / (12 * stepSize));
        }
        /// <summary>
        /// Calculates the specified function.
        /// </summary>
        /// <param name="function">The function.</param>
        /// <param name="point">The point.</param>
        /// <returns>System.Double.</returns>
        internal double calculate(IOptFunction function, double[] point)
        {
            double fValue;
            var    pointClone = (double[])point.Clone();

            SearchIO.output("evaluating x =" + point.MakePrintString(), 4);
            if (functionData[function].TryGetValue(pointClone, out fValue))
            {
                SearchIO.output("f =" + fValue + " (from store).", 4);
                return(fValue);
            }
            calc_dependent_Analysis(point);
            /**************************************************/
            /*** This is the only function that should call ***/
            /**********IOptFunction.calculate(x)***************/
            fValue = function.calculate(point);
            /**************************************************/
            functionData[function].Add(pointClone, fValue);
            functionData[function].numEvals++;
            SearchIO.output("f =" + fValue + " (f'n eval #" + numEvals + ")", 4);
            return(fValue);
        }
 internal double calculate(IOptFunction function, double[] point)
 {
     return(function.calculate(point));
 }
 /// <summary>
 /// Calculates the derivative with respect to variable xi
 /// for the specified function.
 /// </summary>
 /// <param name="function">The function.</param>
 /// <param name="point">The point.</param>
 /// <param name="i">The index of the variable in x.</param>
 /// <returns></returns>
 internal double deriv_wrt_xi(IOptFunction function, double[] point, int i)
 {
     return(function.deriv_wrt_xi(point, i));
 }