/// <summary>Gets a value of the surface at a specified (x,y) coordinate.
            /// </summary>
            /// <param name="x">The x coordinate of the point.</param>
            /// <param name="y">The y coordinate of the point.</param>
            /// <returns>The value of the surface at (<paramref name="x"/>, <paramref name="y"/>).</returns>
            public override double GetValue(double x, double y)
            {
                int columnCount = m_HorizontalDoubleLabels.Length;

                /* compute values w.r.t. to the y-coordinate and each relevant column, i.e. store values to take into account for horizontal
                 * interpolation. In the case of a non-local approach, one may improve performance by indicating that the labels will not be changed: */
                int k = 0;

                for (int j = 0; j < columnCount; j++)
                {
                    m_TempValuesForHorizontalEvaluation[k++] = m_CurvesAlongVerticalDirection[j].GetValue(y);
                }

                GridPointCurve.State horizontalCurveState = GridPointCurve.State.GridPointChanged;
                if ((m_HorizontalParametrization.IsOperable == true) && (m_HorizontalParametrization.GridPointCount == columnCount))
                {
                    horizontalCurveState = GridPointCurve.State.GridPointValueChanged;
                }
                m_HorizontalParametrization.Update(columnCount, m_HorizontalDoubleLabels, m_TempValuesForHorizontalEvaluation, horizontalCurveState);
                if ((x < m_HorizontalParametrization.LowerBound) || (x > m_HorizontalParametrization.UpperBound))
                {
                    throw new ArgumentOutOfRangeException();
                }
                return(m_HorizontalParametrization.GetValue(x));
            }
        /// <summary>Updates the current instance. This method may change <see cref="IOperable.IsOperable"/>.
        /// </summary>
        /// <remarks>Call this method after grid points have been removed, modified or added and before trying to compute a value at a specified argument.
        /// <para>In general this method sets the <see cref="IOperable.IsOperable"/> flag to <c>true</c>.</para></remarks>
        public void Update()
        {
            m_CurveBuilder.Update(m_GridPointLabels.Count, m_GridPointArguments, m_GridPointValues, m_State);
            m_LeftExtrapolator.Update();
            m_RightExtrapolator.Update();

            m_State = GridPointCurve.State.NoChangeSinceLastUpdate;
        }
            /// <summary>Gets a value of the surface at a specified (x,y) coordinate.
            /// </summary>
            /// <param name="x">The x coordinate of the point.</param>
            /// <param name="y">The y coordinate of the point.</param>
            /// <returns>The value of the surface at (<paramref name="x"/>, <paramref name="y"/>).</returns>
            public override double GetValue(double x, double y)
            {
                int rowCount = m_VerticalDoubleLabels.Length;

                int k = 0;

                for (int j = 0; j < rowCount; j++)
                {
                    m_TempValuesForVerticalEvaluation[k++] = m_CurvesAlongHorizontalDirection[j].GetValue(x);
                }

                GridPointCurve.State verticalCurveState = GridPointCurve.State.GridPointChanged;
                if ((m_VerticalParametrization.IsOperable == true) && (m_VerticalParametrization.GridPointCount == rowCount))
                {
                    verticalCurveState = GridPointCurve.State.GridPointValueChanged;
                }
                m_VerticalParametrization.Update(rowCount, m_VerticalDoubleLabels, m_TempValuesForVerticalEvaluation, verticalCurveState);

                if ((y < m_VerticalParametrization.LowerBound) || (y > m_VerticalParametrization.UpperBound))
                {
                    throw new ArgumentOutOfRangeException();
                }
                return(m_VerticalParametrization.GetValue(y));
            }
Example #4
0
        /// <summary>Gets the estimation of a specified missing value via a interpolation along the y-axis.
        /// </summary>
        /// <param name="rowIndex">The null-based index of the row that describes the position of the missing value in <paramref name="matrix"/>.</param>
        /// <param name="columnIndex">The null-based index of the column that describes the position of the missing value in <paramref name="matrix"/>.</param>
        /// <param name="matrix">The matrix.</param>
        /// <param name="rowCount">The number of rows.</param>
        /// <param name="yAxisLabeling">The labels of the y-axis in its <see cref="System.Double"/> representation, i.e. at least <paramref name="rowCount"/> elements.</param>
        /// <param name="curveInterpolator">The (curve) interpolator along y-axis.</param>
        /// <returns>The estimated value for position (<paramref name="rowIndex"/>, <paramref name="columnIndex"/>).</returns>
        /// <exception cref="InvalidOperationException">Thrown, if in the interpolation failed.</exception>
        internal static double GetInterpolatedValueAlongYAxis(int rowIndex, int columnIndex, IList <double> matrix, int rowCount, IList <double> yAxisLabeling, ICurveDataFitting curveInterpolator)
        {
            int  lowIndex      = rowIndex;
            bool foundLowValue = false;

            int arrayOffset = columnIndex * rowCount;

            while ((lowIndex >= 1) && (foundLowValue == false))
            {
                lowIndex--;
                if (Double.IsNaN(matrix[lowIndex + arrayOffset]) == false)  // matrix[lowIndex][columnIndex]
                {
                    foundLowValue = true;
                }
            }

            int  higherIndex      = rowIndex;
            bool foundHigherValue = false;

            while ((higherIndex <= rowCount - 2) && (foundHigherValue == false))
            {
                higherIndex++;
                if (Double.IsNaN(matrix[higherIndex + arrayOffset]) == false)  // matrix[higherIndex][columnIndex]
                {
                    foundHigherValue = true;
                }
            }

            if (foundLowValue && foundHigherValue)
            {
                curveInterpolator.Update(2, yAxisLabeling, matrix, GridPointCurve.State.GridPointChanged, lowIndex, lowIndex + arrayOffset, higherIndex - lowIndex, higherIndex - lowIndex);
                return(curveInterpolator.GetValue(yAxisLabeling[rowIndex]));
            }
            else if (foundLowValue)
            {
                return(matrix[lowIndex + arrayOffset]);   // matrix[lowIndex][columnIndex]
            }
            else if (foundHigherValue)
            {
                return(matrix[higherIndex + arrayOffset]);  // matrix[higherIndex][columnIndex]
            }
            throw new InvalidOperationException(String.Format("Replenish failed at position ({0};{1}).", rowIndex, columnIndex));
        }
Example #5
0
        /// <summary>Gets the estimation of a specified missing value via a interpolation along the x-axis.
        /// </summary>
        /// <param name="rowIndex">The null-based index of the row that describes the position of the missing value in <paramref name="matrix"/>.</param>
        /// <param name="columnIndex">The null-based index of the column that describes the position of the missing value in <paramref name="matrix"/>.</param>
        /// <param name="matrix">The matrix.</param>
        /// <param name="rowCount">The number of rows.</param>
        /// <param name="columnCount">The number of columns.</param>
        /// <param name="xAxisLabeling">The labels of the x-axis in its <see cref="System.Double"/> representation, i.e. at least <paramref name="columnCount"/> elements.</param>
        /// <param name="curveInterpolator">The (curve) interpolator along x-axis.</param>
        /// <returns>The estimated value for position (<paramref name="rowIndex"/>, <paramref name="columnIndex"/>).</returns>
        /// <exception cref="InvalidOperationException">Thrown, if in the interpolation failed.</exception>
        internal static double GetInterpolatedValueAlongXAxis(int rowIndex, int columnIndex, IList <double> matrix, int rowCount, int columnCount, IList <double> xAxisLabeling, ICurveDataFitting curveInterpolator)
        {
            int  leftIndex      = columnIndex;
            bool foundLeftValue = false;

            while ((leftIndex >= 1) && (foundLeftValue == false))
            {
                leftIndex--;

                if (Double.IsNaN(matrix[rowIndex + leftIndex * rowCount]) == false)  // matrix[rowIndex][leftIndex]
                {
                    foundLeftValue = true;
                }
            }

            int  rightIndex      = columnIndex;
            bool foundRightValue = false;

            while ((rightIndex <= columnCount - 2) && (foundRightValue == false))
            {
                rightIndex++;
                if (Double.IsNaN(matrix[rowIndex + rightIndex * rowCount]) == false)  // matrix[rowIndex][rightIndex]
                {
                    foundRightValue = true;
                }
            }

            if (foundLeftValue && foundRightValue)
            {
                curveInterpolator.Update(2, xAxisLabeling, matrix, GridPointCurve.State.GridPointChanged, leftIndex, rowIndex + leftIndex * rowCount, rightIndex - leftIndex, rowCount * (rightIndex - leftIndex));
                return(curveInterpolator.GetValue(xAxisLabeling[columnIndex]));
            }
            else if (foundLeftValue)
            {
                return(matrix[rowIndex + leftIndex * rowCount]);  // matrix[rowIndex][leftIndex]
            }
            else if (foundRightValue)
            {
                return(matrix[rowIndex + rightIndex * rowCount]);  // matrix[rowIndex][rightIndex]
            }
            throw new InvalidOperationException(String.Format("Replenish failed at position ({0};{1}).", rowIndex, columnIndex));
        }
Example #6
0
        /// <summary>Initializes a new instance of the <see cref="SmartReadOnlyGridPointCurve&lt;TLabel&gt;"/> class.
        /// </summary>
        /// <param name="curveInterpolator">The curve interpolator.</param>
        /// <param name="leftExtrapolator">The left extrapolator.</param>
        /// <param name="rightExtrapolator">The right extrapolator.</param>
        /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointLabels"/>, <paramref name="gridPointArguments"/> and <paramref name="gridPointValues"/> to take into account.</param>
        /// <param name="gridPointLabels">The labels of the grid points (the reference will be stored only).</param>
        /// <param name="gridPointArguments">The arguments of the grid points, thus labels of the curve in its <see cref="System.Double"/> representation.</param>
        /// <param name="gridPointValues">The values of the grid points corresponding to <paramref name="gridPointArguments"/>.</param>
        /// <param name="gridPointArgumentStartIndex">The null-based start index of <paramref name="gridPointArguments"/> and <paramref name="gridPointLabels"/> to take into account.</param>
        /// <param name="gridPointValueStartIndex">The null-based start index of <paramref name="gridPointValues"/> to take into account.</param>
        /// <param name="gridPointArgumentIncrement">The increment for <paramref name="gridPointArguments"/> and <paramref name="gridPointLabels"/>.</param>
        /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues"/>.</param>
        internal SmartReadOnlyGridPointCurve(ICurveDataFitting curveInterpolator, ICurveExtrapolator leftExtrapolator, ICurveExtrapolator rightExtrapolator, int gridPointCount, IList <TLabel> gridPointLabels, IList <double> gridPointArguments, IList <double> gridPointValues, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
        {
            m_CurveInterpolator = curveInterpolator;
            m_LeftExtrapolator  = leftExtrapolator;
            m_RightExtrapolator = rightExtrapolator;

            m_GridPointLabels = new SmartReadOnlyCollection <TLabel>(gridPointCount, gridPointLabels, gridPointArgumentStartIndex, gridPointArgumentIncrement);

            curveInterpolator.Update(gridPointCount, gridPointArguments, gridPointValues, GridPointCurve.State.GridPointChanged, gridPointArgumentStartIndex, gridPointValueStartIndex, gridPointArgumentIncrement = 1, gridPointValueIncrement);
            if (curveInterpolator.IsOperable == false)
            {
                throw new ArgumentException();
            }
            leftExtrapolator.Update();
            if (leftExtrapolator.IsOperable == false)
            {
                throw new ArgumentException();
            }
            rightExtrapolator.Update();
            if (rightExtrapolator.IsOperable == false)
            {
                throw new ArgumentException();
            }
        }
            /// <summary>Gets a value of the surface at a specified (x,y) coordinate.
            /// </summary>
            /// <param name="x">The x coordinate of the point.</param>
            /// <param name="y">The y coordinate of the point.</param>
            /// <returns>The value of the surface at (<paramref name="x"/>, <paramref name="y"/>).</returns>
            public override double GetValue(double x, double y)
            {
                int columnCount = m_HorizontalDoubleLabels.Length;

                int firstColumnIndex    = 0;
                int lastColumnIndex     = columnCount - 1;
                int relevantColumnCount = columnCount;

                /* if the interpolation along horizontal direction is a local approach a few function evaluations are needed only: */
                if (m_HorizontalInterpolatorFactory.IsLocalApproach == true)
                {
                    if (x < m_HorizontalDoubleLabels[0])  // on the left side of the grid points
                    {
                        lastColumnIndex = Math.Min(columnCount - 1, m_HorizontalLeftExtrapolatorFactory.GetLevelOfGridPointDependency(columnCount));
                    }
                    else if (x > m_HorizontalDoubleLabels[columnCount - 1])  // on the right side of the grid points
                    {
                        firstColumnIndex = Math.Max(0, columnCount - m_HorizontalRightExtrapolatorFactory.GetLevelOfGridPointDependency(columnCount) - 1);
                    }
                    else // inside the grid points
                    {
                        int nonLastLeftGridPointIndex = GridPointCurve.Utilities.GetNonLastNearestIndex(x, m_HorizontalDoubleLabels, m_HorizontalDoubleLabels.Length);

                        int upperLocalnessLevel = m_HorizontalInterpolatorFactory.GetLeftLocalnessLevel(nonLastLeftGridPointIndex, columnCount);
                        int lowerLocalnessLevel = m_HorizontalInterpolatorFactory.GetRightLocalnessLevel(nonLastLeftGridPointIndex, columnCount);

                        firstColumnIndex = Math.Max(nonLastLeftGridPointIndex - upperLocalnessLevel, 0);
                        lastColumnIndex  = Math.Min(nonLastLeftGridPointIndex + lowerLocalnessLevel, columnCount - 1);
                    }
                    relevantColumnCount = lastColumnIndex - firstColumnIndex + 1;

                    /* perhaps one may take into account less columns than required for the interpolation, i.e. one has to adjust the first/last column index: */
                    if (relevantColumnCount < m_HorizontalInterpolatorFactory.MinimalRequiredNumberOfGridPoints)
                    {
                        int numberOfAdditionalRequiredColumns = m_HorizontalInterpolatorFactory.MinimalRequiredNumberOfGridPoints - relevantColumnCount;

                        firstColumnIndex = Math.Max(0, firstColumnIndex - numberOfAdditionalRequiredColumns);
                        lastColumnIndex  = Math.Min(columnCount - 1, lastColumnIndex + numberOfAdditionalRequiredColumns);

                        relevantColumnCount = lastColumnIndex - firstColumnIndex + 1;
                    }
                }

                /* compute values w.r.t. to the y-coordinate and each relevant column, i.e. store values to take into account for horizontal
                 * interpolation. In the case of a non-local approach, one may improve performance by indicating that the labels will not be changed: */
                int k = 0;

                for (int j = firstColumnIndex; j <= lastColumnIndex; j++)
                {
                    m_TempValuesForHorizontalEvaluation[k++] = m_CurvesAlongVerticalDirection[j].GetValue(y);
                }

                var horizontalCurveState = GridPointCurve.State.GridPointChanged;

                if ((m_HorizontalInterpolatorFactory.IsLocalApproach == false) && (m_HorizontalInterpolator.IsOperable == true) && (m_HorizontalInterpolator.GridPointCount == columnCount))
                {
                    horizontalCurveState = GridPointCurve.State.GridPointValueChanged;
                }
                m_HorizontalInterpolator.Update(relevantColumnCount, m_HorizontalDoubleLabels, m_TempValuesForHorizontalEvaluation, horizontalCurveState, gridPointArgumentStartIndex: firstColumnIndex);

                if (x < m_HorizontalInterpolator.LowerBound)
                {
                    m_HorizontalLeftExtrapolator.Update();
                    return(m_HorizontalLeftExtrapolator.GetValue(x));
                }
                else if (x > m_HorizontalInterpolator.UpperBound)
                {
                    m_HorizontalRightExtrapolator.Update();
                    return(m_HorizontalRightExtrapolator.GetValue(x));
                }
                return(m_HorizontalInterpolator.GetValue(x));
            }