/// <summary>
        ///   Computes the area under the integral for the given function, in the given 
        ///   integration interval, using the Infinite Adaptive Gauss Kronrod algorithm.
        /// </summary>
        /// 
        /// <param name="f">The unidimensional function whose integral should be computed.</param>
        /// <param name="a">The beginning of the integration interval.</param>
        /// <param name="b">The ending of the integration interval.</param>
        /// 
        /// <returns>The integral's value in the current interval.</returns>
        /// 
        public static double Integrate(Func<double, double> f, double a, double b)
        {
            var iagk = new InfiniteAdaptiveGaussKronrod(1000, f, a, b);

            iagk.Compute();

            return iagk.Area;
        }
        /// <summary>
        ///   Computes the area under the integral for the given function, in the given 
        ///   integration interval, using the Infinite Adaptive Gauss Kronrod algorithm.
        /// </summary>
        /// 
        /// <param name="f">The unidimensional function whose integral should be computed.</param>
        /// <param name="a">The beginning of the integration interval.</param>
        /// <param name="b">The ending of the integration interval.</param>
        /// <param name="tolerance">
        ///   The relative tolerance under which the solution has to be found. Default is 1e-3.</param>
        /// 
        /// <returns>The integral's value in the current interval.</returns>
        /// 
        public static double Integrate(Func<double, double> f, double a, double b, double tolerance)
        {
            var iagk = new InfiniteAdaptiveGaussKronrod(100, f, a, b)
            {
                ToleranceRelative = tolerance
            };

            iagk.Compute();

            return iagk.Area;
        }
        /// <summary>
        ///   Creates a new object that is a copy of the current instance.
        /// </summary>
        /// 
        /// <returns>
        ///   A new object that is a copy of this instance.
        /// </returns>
        /// 
        public object Clone()
        {
            var clone = new InfiniteAdaptiveGaussKronrod();

            clone.evaluations = evaluations;
            clone.iwork = (int[])iwork.Clone();
            clone.work = (double[])work.Clone();
            clone.error = error;
            clone.result = result;
            clone.ToleranceAbsolute = ToleranceAbsolute;
            clone.ToleranceRelative = ToleranceRelative;

            return clone;
        }