/// <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)); }
/// <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)); }
/// <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)); }
/// <summary>Initializes a new instance of the <see cref="SmartReadOnlyGridPointCurve<TLabel>"/> 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)); }