/// <summary>Updates the current curve extrapolator. /// </summary> /// <remarks>This method should be called if grid points have been changed, added, removed etc. and before evaluating the grid point curve at a specified point. /// <para>If no problem occurred, the flag <see cref="IOperable.IsOperable"/> will be set to <c>true</c>.</para> /// </remarks> public void Update() { if (m_CurveInterpolator.GridPointCount >= 2) { int gridIndex = (m_BuildingDirection == BuildingDirection.FromFirstGridPoint) ? 0 : m_CurveInterpolator.GridPointCount - 2; double x1 = m_CurveInterpolator.GridPointArguments[gridIndex]; double x2 = m_CurveInterpolator.GridPointArguments[gridIndex + 1]; double y1 = m_CurveInterpolator.GetValue(x1); double y2 = m_CurveInterpolator.GetValue(x2); if (x2 - x1 > MachineConsts.Epsilon) { m_Slope = (y2 - y1) / (x2 - x1); } else { throw new ArithmeticException("Linear extrapolation failed."); } m_ReferencePoint = (m_BuildingDirection == BuildingDirection.FromFirstGridPoint) ? m_CurveInterpolator.LowerBound : m_CurveInterpolator.UpperBound; m_ReferenceValue = m_CurveInterpolator.GetValue(m_ReferencePoint); } else { m_Slope = Double.NaN; // IsOperable flag will be set to 'false' } }
/// <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>Gets the value at a specific argument. /// </summary> /// <param name="pointToEvaluate">The point to evaluate.</param> /// <returns>The value of the curve at <paramref name="pointToEvaluate"/>.</returns> /// <remarks>The argument must be an element of the domain of definition, represented by <see cref="IRealValuedCurve.LowerBound"/> and <see cref="IRealValuedCurve.UpperBound"/>.</remarks> public double GetValue(double pointToEvaluate) { if (pointToEvaluate < m_CurveBuilder.LowerBound) { return(m_LeftExtrapolator.GetValue(pointToEvaluate)); } else if (pointToEvaluate > m_CurveBuilder.UpperBound) { return(m_RightExtrapolator.GetValue(pointToEvaluate)); } return(m_CurveBuilder.GetValue(pointToEvaluate)); }
/// <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>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)); }
/// <summary>Updates the current curve extrapolator. /// </summary> /// <remarks>This method should be called if grid points have been changed, added, removed etc. and before evaluating the grid point curve at a specified point. /// <para>If no problem occurred, the flag <see cref="IOperable.IsOperable"/> will be set to <c>true</c>.</para> /// </remarks> public void Update() { m_ReferencePoint = (m_BuildingDirection == BuildingDirection.FromFirstGridPoint) ? m_CurveInterpolator.LowerBound : m_CurveInterpolator.UpperBound; m_ReferenceValue = m_CurveInterpolator.GetValue(m_ReferencePoint); }
/// <summary>Updates the current curve extrapolator. /// </summary> /// <remarks>This method should be called if grid points have been changed, added, removed etc. and before evaluating the grid point curve at a specified point. /// <para>If no problem occurred, the flag <see cref="IOperable.IsOperable"/> will be set to <c>true</c>.</para> /// </remarks> public void Update() { m_GridPointBound = m_CurveInterpolator.UpperBound; m_GridPointValue = m_CurveInterpolator.GetValue(m_GridPointBound); }