Esempio n. 1
0
        /// <summary>Gets the value of the integral \int_a^b f(x) dx.
        /// </summary>
        /// <param name="lowerBound">The lower bound.</param>
        /// <param name="upperBound">The upper bound.</param>
        /// <returns>The value of \int_a^b f(x) dx.</returns>
        /// <remarks>The arguments must be elements of the domain of definition, represented by <see cref="IRealValuedCurve.LowerBound"/> and <see cref="IRealValuedCurve.UpperBound"/> of the encapsulated <see cref="ICurveDataFitting"/> object.</remarks>
        public double GetIntegral(double lowerBound, double upperBound)
        {
            if (UpdateRequested == true)
            {
                Update();
            }
            int leftGridIndex  = GridPointArguments.BinarySearch(0, GridPointCount, lowerBound);
            int rightGridIndex = GridPointArguments.BinarySearch(0, GridPointCount, upperBound);

            if ((leftGridIndex >= 0) && (rightGridIndex >= 0))
            {
                return(m_Cache[rightGridIndex] - m_Cache[leftGridIndex]);  // \int_{t_j}^{t_k} f(x) dx = \int_{t_0}^{t_k} f(x) dx - \int_{t_0}^{t_j} f(x) dx
            }
            else if (leftGridIndex < 0)
            {
                int previousLeftGridIndex = (~leftGridIndex) - 1; // previous grid point, i.e. smaller than the lower bound

                var value = CurveDataFitting.GetIntegral(lowerBound, Math.Min(upperBound, GridPointArguments[previousLeftGridIndex + 1]), previousLeftGridIndex);

                if (leftGridIndex != rightGridIndex)  // lower and upper bound are not in the same interval [t_j, t_{j+1}]
                {
                    if (rightGridIndex >= 0)
                    {
                        value += (m_Cache[rightGridIndex] - m_Cache[previousLeftGridIndex + 1]);
                    }
                    else
                    {
                        rightGridIndex = (~rightGridIndex) - 1; // previous grid point, i.e. smaller than the upper bound
                        var stepValue = CurveDataFitting.GetIntegral(Math.Max(lowerBound, GridPointArguments[rightGridIndex]), upperBound, rightGridIndex);

                        value += stepValue + (m_Cache[rightGridIndex] - m_Cache[previousLeftGridIndex + 1]);
                    }
                }
                return(value);
            }
            else  // lower bound is a grid point and the upper bound is not a grid point
            {
                rightGridIndex = (~rightGridIndex) - 1; // previous grid point, i.e. smaller than the upper bound
                var stepValue = CurveDataFitting.GetIntegral(Math.Max(lowerBound, GridPointArguments[rightGridIndex]), upperBound, rightGridIndex);

                return(stepValue + (m_Cache[rightGridIndex] - m_Cache[leftGridIndex]));
            }
        }
Esempio n. 2
0
        /// <summary>Updates the internal cache.
        /// </summary>
        private void Update()
        {
            ArrayMemory.Reallocate(ref m_Cache, GridPointCount, pufferSize: 5);

            var cumIntegralValue = m_Cache[0] = 0.0;
            var lowerBound       = GridPointArguments[0];

            for (int k = 1; k < GridPointCount; k++)
            {
                var upperBound          = GridPointArguments[k];
                var upperGridPointValue = GridPointValues[k];

                cumIntegralValue += CurveDataFitting.GetIntegral(lowerBound, upperBound, k - 1);
                m_Cache[k]        = cumIntegralValue;

                /* prepare for next loop: */
                lowerBound = upperBound;
            }
            UpdateRequested = false;
        }