/// <summary>
        /// Samples a function equidistant within the provided interval.
        /// </summary>
        /// <param name="function">The real-domain function to sample.</param>
        /// <param name="intervalBegin">The real domain interval begin where to start sampling.</param>
        /// <param name="intervalEnd">The real domain interval end where to stop sampling.</param>
        /// <param name="sampleCount">The number of samples to generate.</param>
        /// <param name="samplePoints">The real domain points where the samples are taken at.</param>
        /// <typeparam name="T">The value type of the function to sample.</typeparam>
        /// <returns>The generated sample vector.</returns>
        /// <exception cref="ArgumentNullException" />
        /// <exception cref="ArgumentOutOfRangeException" />
        public static T[] EquidistantInterval <T>(Func <double, T> function, double intervalBegin, double intervalEnd, int sampleCount,
                                                  out double[] samplePoints)
        {
            function.ShouldNotBeNull("function");
            sampleCount.ShouldBePositiveOrZero("sampleCount");

            if (sampleCount == 0)
            {
                samplePoints = new double[0];

                return(new T[0]);
            }

            if (sampleCount == 1)
            {
                samplePoints = new double[] { (intervalBegin + intervalEnd) / 2.0 };
                return(new T[] { function(samplePoints[0]) });
            }

            var step = (intervalEnd - intervalBegin) / (sampleCount - 1);

            samplePoints = PLinqTool.Generate(sampleCount, i => intervalBegin + i * step).ToArray();
            samplePoints[samplePoints.Length - 1] = intervalEnd;

            var result =
                samplePoints
                .AsParallel()
                .AsOrdered()
                .Select(x => function(x))
                .ToArray();

            result[result.Length - 1] = function(intervalEnd);

            return(result);
        }
        /// <summary>
        /// Samples a function equidistant starting from the provided location with a fixed step length.
        /// </summary>
        /// <param name="function">The real-domain function to sample.</param>
        /// <param name="start">The real domain location offset where to start sampling.</param>
        /// <param name="step">The real domain step length between the equidistant samples.</param>
        /// <param name="sampleCount">The number of samples to generate.</param>
        /// <param name="samplePoints">The real domain points where the samples are taken at.</param>
        /// <typeparam name="T">The value type of the function to sample.</typeparam>
        /// <returns>The generated sample vector.</returns>
        /// <exception cref="ArgumentNullException" />
        /// <exception cref="ArgumentOutOfRangeException"/>
        public static T[] EquidistantStartingAt <T>(Func <double, T> function, double start, double step, int sampleCount,
                                                    out double[] samplePoints)
        {
            function.ShouldNotBeNull("function");
            sampleCount.ShouldBePositiveOrZero("sampleCount");


            samplePoints = PLinqTool.Generate(start, step, sampleCount, x => x).ToArray();

            return
                (samplePoints
                 .AsParallel()
                 .AsOrdered()
                 .Select(x => function(x))
                 .ToArray());
        }
        /// <summary>
        /// Samples a periodic function equidistant within one period, but omits the last sample such that the sequence
        /// can be concatenated together.
        /// </summary>
        /// <param name="function">The real-domain function to sample.</param>
        /// <param name="periodLength">The real domain full period length.</param>
        /// <param name="periodOffset">The real domain offset where to start the sampling period.</param>
        /// <param name="sampleCount">The number of samples to generate.</param>
        /// <param name="samplePoints">The real domain points where the samples are taken at.</param>
        /// <typeparam name="T">The value type of the function to sample.</typeparam>
        /// <returns>The generated sample vector.</returns>
        /// <exception cref="ArgumentNullException" />
        /// <exception cref="ArgumentOutOfRangeException"/>
        public static T[] EquidistantPeriodic <T>(Func <double, T> function, double periodLength, double periodOffset, int sampleCount,
                                                  out double[] samplePoints)
        {
            function.ShouldNotBeNull("function");
            sampleCount.ShouldBePositive("sampleCount");

            var step = periodLength / sampleCount;

            samplePoints = PLinqTool.Generate(sampleCount, i => periodOffset + i * step).ToArray();

            return
                (samplePoints
                 .AsParallel()
                 .AsOrdered()
                 .Select(x => function(x))
                 .ToArray());
        }