コード例 #1
0
 /// <summary>Removes all elements from the <see cref="IGridPointCurve"/> object.
 /// </summary>
 /// <remarks>This method set the <see cref="IOperable.IsOperable"/> flag to <c>false</c>.</remarks>
 /// <exception cref="InvalidOperationException">Thrown, if <see cref="IGridPointCurve.IsReadOnly"/> is <c>true</c>.</exception>
 public void Clear()
 {
     m_GridPointLabels.Clear();
     m_GridPointArguments.Clear();
     m_GridPointValues.Clear();
     m_State = GridPointCurve.State.GridPointChanged;
 }
コード例 #2
0
        /// <summary>Removes a specific grid point.
        /// </summary>
        /// <param name="gridPointIndex">The null-based index of the grid point.</param>
        /// <remarks>This method set the <see cref="IOperable.IsOperable"/> flag to <c>false</c>.</remarks>
        /// <exception cref="InvalidOperationException">Thrown, if <see cref="IGridPointCurve.IsReadOnly"/> is <c>true</c>.</exception>
        public void RemoveAt(int gridPointIndex)
        {
            m_GridPointArguments.RemoveAt(gridPointIndex);
            m_GridPointValues.RemoveAt(gridPointIndex);

            m_State = GridPointCurve.State.GridPointChanged;
        }
コード例 #3
0
        /// <summary>Changes a specific grid point argument.
        /// </summary>
        /// <param name="gridPointIndex">The null-based index of the grid point.</param>
        /// <param name="argument">The argument of the specified grid point, i.e. the <see cref="System.Double"/> representation of the label of the x-axis.</param>
        /// <remarks>This method set the <see cref="IOperable.IsOperable"/> flag to <c>false</c>.</remarks>
        /// <exception cref="InvalidOperationException">Thrown, if <see cref="IGridPointCurve.IsReadOnly"/> is <c>true</c>.</exception>
        public void SetGridPointArgument(int gridPointIndex, double argument)
        {
            /* If a re-ordering of the grid points is necessary we first remove the grid point and re-insert the 'new' a the specific position: */
            if (GridPointCount == 0)
            {
                throw new InvalidOperationException();
            }
            if ((gridPointIndex < 0) || (gridPointIndex > GridPointCount - 1))
            {
                throw new IndexOutOfRangeException();
            }
            int previousGridPointIndex = Math.Max(0, gridPointIndex - 1);
            int nextGridPointIndex     = Math.Min(gridPointIndex + 1, GridPointCount - 1);

            if ((m_GridPointArguments[previousGridPointIndex] <= argument) && (argument <= m_GridPointArguments[nextGridPointIndex]))
            {
                m_GridPointArguments[gridPointIndex] = argument;
                m_State |= GridPointCurve.State.GridPointArgumentChanged;
            }
            else
            {
                var label = m_GridPointLabels[gridPointIndex];
                var value = m_GridPointValues[gridPointIndex];

                RemoveAt(gridPointIndex);
                Add(label, argument, value);
            }
        }
            /// <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));
            }
コード例 #5
0
        /// <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;
        }
コード例 #6
0
 /// <summary>Changes the value component of a specific grid point.
 /// </summary>
 /// <param name="label">The label.</param>
 /// <param name="value">The value.</param>
 /// <returns>A value indicating whether the <paramref name="label"/> exists in the curve and the value component has been changed to <paramref name="value"/>.</returns>
 /// <exception cref="InvalidOperationException">Thrown, if <see cref="IGridPointCurve.IsReadOnly"/> is <c>true</c>.</exception>
 public bool TrySetValue(double label, double value)
 {
     int labelIndex = m_GridPointArguments.FindIndex(match => match.Equals(label));
     if (labelIndex >= 0)
     {
         m_GridPointValues[labelIndex] = value;
         m_State |= GridPointCurve.State.GridPointValueChanged;
         return true;
     }
     return false;
 }
コード例 #7
0
 /// <summary>Removes a specific grid point.
 /// </summary>
 /// <param name="label">The label of the grid point to remove.</param>
 /// <returns>A value indicating whether the grid point with respect to <paramref name="label"/> has been removed.</returns>
 /// <exception cref="InvalidOperationException">Thrown, if <see cref="IGridPointCurve.IsReadOnly"/> is <c>true</c>.</exception>
 public bool TryRemove(double label)
 {
     int labelIndex = m_GridPointArguments.FindIndex(match => match.Equals(label));
     if (labelIndex >= 0)
     {
         m_GridPointArguments.RemoveAt(labelIndex);
         m_GridPointValues.RemoveAt(labelIndex);
         m_State = GridPointCurve.State.GridPointChanged;
         return true;
     }
     return false;
 }
コード例 #8
0
        /// <summary>Changes the value component of a specific grid point.
        /// </summary>
        /// <param name="label">The label.</param>
        /// <param name="value">The value.</param>
        /// <returns>A value indicating whether the <paramref name="label"/> exists in the curve and the value component has been changed to <paramref name="value"/>.</returns>
        /// <exception cref="InvalidOperationException">Thrown, if <see cref="IGridPointCurve.IsReadOnly"/> is <c>true</c>.</exception>
        public bool TrySetValue(TLabel label, double value)
        {
            int labelIndex = m_GridPointLabels.FindIndex(match => match.Equals(label));

            if (labelIndex >= 0)
            {
                m_GridPointValues[labelIndex] = value;
                m_State |= GridPointCurve.State.GridPointValueChanged;
                return(true);
            }
            return(false);
        }
コード例 #9
0
        /// <summary>Adds a specific grid point.
        /// </summary>
        /// <param name="label">The label.</param>
        /// <param name="argument">The argument, i.e. the <see cref="System.Double"/> representation of <paramref name="label"/>.</param>
        /// <param name="value">The value.</param>
        /// <returns>The null-based index of the grid point in the curve, the grid points should be ordered with respect to the argument.</returns>
        /// <exception cref="InvalidOperationException">Thrown, if <see cref="IGridPointCurve.IsReadOnly"/> is <c>true</c>.</exception>
        public int Add(double label, double argument, double value)
        {
            int index = m_GridPointArguments.BinarySearch(argument);
            if (index >= 0)
            {
                throw new ArgumentException();
            }
            index = (~index);

            m_GridPointArguments.Insert(index, argument);
            m_GridPointValues.Insert(index, value);
            m_State = GridPointCurve.State.GridPointChanged;
            return index;
        }
コード例 #10
0
        /// <summary>Initializes a new instance of the <see cref="StandardGridPointCurveNoLabels"/> class.
        /// </summary>
        /// <param name="curveInterpolatorFactory">The curve interpolator factory.</param>
        /// <param name="curveInterpolator">The curve interpolator.</param>
        /// <param name="leftExtrapolatorFactory">The left extrapolator factory.</param>
        /// <param name="leftExtrapolator">The left extrapolator.</param>
        /// <param name="rightExtrapolatorFactory">The right extrapolator factory.</param>
        /// <param name="rightExtrapolator">The right extrapolator.</param>
        /// <param name="capacity">The number of elements that the new grid point curve can initially store.</param>
        internal StandardGridPointCurveNoLabels(GridPointCurve.Interpolator curveInterpolatorFactory, ICurveDataFitting curveInterpolator, GridPointCurve.Extrapolator leftExtrapolatorFactory, ICurveExtrapolator leftExtrapolator, GridPointCurve.Extrapolator rightExtrapolatorFactory, ICurveExtrapolator rightExtrapolator, int capacity = 20)
        {
            m_GridPointArguments = new List<double>(capacity);
            m_GridPointValues = new List<double>(capacity);

            m_CurveBuilder = curveInterpolator;
            m_LeftExtrapolator = leftExtrapolator;
            m_RightExtrapolator = rightExtrapolator;

            m_State = GridPointCurve.State.GridPointChanged;

            m_ReadOnlyGridPointValues = new ReadOnlyCollection<double>(m_GridPointValues);
            m_ReadOnlyGridPointArguments = new ReadOnlyCollection<double>(m_GridPointArguments);
        }
コード例 #11
0
            /// <summary>Gets a value at a specified point (<paramref name="columnIndex"/>, <paramref name="y"/>).
            /// </summary>
            /// <param name="columnIndex">The null-based column index of the point.</param>
            /// <param name="y">The y coordinate of the point.</param>
            /// <returns>The value of the surface at (<paramref name="columnIndex"/>, <paramref name="y"/>).</returns>
            public override double GetValue(int columnIndex, double y)
            {
                if (m_HorizontalExactFitToGridPoints == false)
                {
                    if (m_VerticalLabelMapping == null)
                    {
                        return(GetValue(m_GridPointMatrix.HorizontalDoubleLabels[columnIndex], y));
                    }
                    else
                    {
                        return(GetValue(m_GridPointMatrix.HorizontalDoubleLabels[m_VerticalLabelMapping[columnIndex]], y));
                    }
                }

                /* if the horizontal curve fitting meets the grid points, an evaluation of the horizontal curve fitting is not necessary. Here, we do not distinguish
                 * between local and non-local interpolation approach and we take into account all values (!= NaN) along vertical direction: */

                int numberOfRelevantRows = 0;

                for (int j = 0; j < m_GridPointMatrix.RowCount; j++)
                {
                    double gridValue = m_GridPointMatrix[j, columnIndex];
                    if (Double.IsNaN(gridValue) == false)
                    {
                        m_TempValuesForVerticalEvaluation[numberOfRelevantRows] = gridValue;
                        m_TempVerticalDoubleLabels[numberOfRelevantRows]        = m_GridPointMatrix.VerticalDoubleLabels[j];
                        numberOfRelevantRows++;
                    }
                }
                GridPointCurve.State verticalCurveState = GridPointCurve.State.GridPointChanged;
                if ((m_VerticalInterpolator.IsOperable == true) && (m_VerticalInterpolator.GridPointCount == m_GridPointMatrix.RowCount) && (numberOfRelevantRows == m_GridPointMatrix.RowCount))
                {
                    verticalCurveState = GridPointCurve.State.GridPointValueChanged;
                }
                m_VerticalInterpolator.Update(numberOfRelevantRows, m_TempVerticalDoubleLabels, m_TempValuesForVerticalEvaluation, verticalCurveState);

                if (y < m_VerticalInterpolator.LowerBound)
                {
                    m_VerticalAboveExtrapolator.Update();
                    return(m_VerticalAboveExtrapolator.GetValue(y));
                }
                else if (y > m_VerticalInterpolator.UpperBound)
                {
                    m_VerticalBelowExtrapolator.Update();
                    return(m_VerticalBelowExtrapolator.GetValue(y));
                }
                return(m_VerticalInterpolator.GetValue(y));
            }
コード例 #12
0
        /// <summary>Initializes a new instance of the <see cref="StandardGridPointCurveNoLabels"/> class.
        /// </summary>
        /// <param name="curveParametrizationFactory">The curve parametrization factory.</param>
        /// <param name="curveParametrization">The curve parametrization.</param>
        /// <param name="capacity">The number of elements that the new grid point curve can initially store.</param>
        internal StandardGridPointCurveNoLabels(GridPointCurve.Parametrization curveParametrizationFactory, ICurveDataFitting curveParametrization, int capacity = 20)
        {
            m_GridPointArguments = new List<double>(capacity);
            m_GridPointValues = new List<double>(capacity);

            m_CurveBuilder = curveParametrization;

            // do not apply any truncation (extrapolation) approach:
            m_LeftExtrapolator = GridPointCurve.Extrapolator.None.First.Create(curveParametrization);
            m_RightExtrapolator = GridPointCurve.Extrapolator.None.Last.Create(curveParametrization);

            m_ReadOnlyGridPointValues = new ReadOnlyCollection<double>(m_GridPointValues);
            m_ReadOnlyGridPointArguments = new ReadOnlyCollection<double>(m_GridPointArguments);

            m_State = GridPointCurve.State.GridPointChanged;
        }
            /// <summary>Gets a value at a specified point (<paramref name="columnIndex"/>, <paramref name="y"/>).
            /// </summary>
            /// <param name="columnIndex">The null-based column index of the point.</param>
            /// <param name="y">The y coordinate of the point.</param>
            /// <returns>The value of the surface at (<paramref name="columnIndex"/>, <paramref name="y"/>).</returns>
            public override double GetValue(int columnIndex, double y)
            {
                if (m_HorizontalExactFitToGridPoints == false)
                {
                    if (m_VerticalLabelMapping == null)
                    {
                        return(GetValue(m_GridPointMatrix.HorizontalDoubleLabels[columnIndex], y));
                    }
                    else
                    {
                        return(GetValue(m_GridPointMatrix.HorizontalDoubleLabels[m_VerticalLabelMapping[columnIndex]], y));
                    }
                }

                /* if the horizontal curve fitting meets the grid points, an evaluation of the horizontal curve fitting is not necessary. We take into account all values (!= NaN) along vertical direction: */
                int numberOfRelevantRows = 0;

                for (int j = 0; j < m_GridPointMatrix.RowCount; j++)
                {
                    double gridValue = m_GridPointMatrix[j, columnIndex];
                    if (Double.IsNaN(gridValue) == false)
                    {
                        m_TempValuesForVerticalEvaluation[numberOfRelevantRows] = gridValue;
                        m_TempVerticalDoubleLabels[numberOfRelevantRows]        = m_GridPointMatrix.VerticalDoubleLabels[j];
                        numberOfRelevantRows++;
                    }
                }
                GridPointCurve.State verticalCurveState = GridPointCurve.State.GridPointChanged;
                if ((m_VerticalParametrization.IsOperable == true) && (m_VerticalParametrization.GridPointCount == m_GridPointMatrix.RowCount) && (numberOfRelevantRows == m_GridPointMatrix.RowCount))
                {
                    verticalCurveState = GridPointCurve.State.GridPointValueChanged;
                }
                m_VerticalParametrization.Update(numberOfRelevantRows, m_TempVerticalDoubleLabels, m_TempValuesForVerticalEvaluation, verticalCurveState);

                if ((y < m_VerticalParametrization.LowerBound) || (y > m_VerticalParametrization.UpperBound))
                {
                    throw new ArgumentOutOfRangeException();
                }
                return(m_VerticalParametrization.GetValue(y));
            }
            /// <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));
            }
コード例 #15
0
            /// <summary>Updates the current curve fitting object.
            /// </summary>
            /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" /> to take into account.</param>
            /// <param name="gridPointArguments">The arguments of the grid points, thus labels of the curve in its <see cref="System.Double" /> representation in ascending order.</param>
            /// <param name="gridPointValues">The values of the grid points corresponding to <paramref name="gridPointArguments" />.</param>
            /// <param name="state">The state of the grid points, i.e. <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" />, with respect to the previous function call.</param>
            /// <param name="gridPointArgumentStartIndex">The null-based start index of <paramref name="gridPointArguments" /> 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" />.</param>
            /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues" />.</param>
            /// <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>
            /// <para>This method should always store all required data for later use, i.e. creates deep copies of the arguments.</para>
            /// </remarks>
            public void Update(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, GridPointCurve.State state, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
            {
                if (gridPointCount <= 0)
                {
                    m_GridPointCount = 0;  // current instance is not operable
                }
                else
                {
                    m_GridPointCount = gridPointCount;
                    int order = m_LeastSquaresRegressionFactory.Order;

                    if (state.HasFlag(GridPointCurve.State.GridPointArgumentChanged))
                    {
                        ArrayMemory.Reallocate(ref m_GridPointArguments, gridPointCount, Math.Max(10, gridPointCount / 5));
                        gridPointArguments.CopyTo(m_GridPointArguments, gridPointCount, gridPointArgumentStartIndex, sourceIncrement: gridPointArgumentIncrement);

                        /* The optimal parameters (weights) are given by \beta = (A^t *A)^{-1} *A^t * y, where A is the design matrix and
                         * y are the observations (=values of the grid points). For this, we compute the SVD of the design matrix 'A', i.e.
                         * A = U*\Sigma*V^t, where U is a m-by-m, V is a n-by-n and \Sigma is a m-by-n matrix, where n = order +1 and m = number of grid points. It follows
                         * \beta = (V * \Sigma^{-1} * U^t) * y.
                         * */

                        DenseMatrix designMatrix = m_LeastSquaresRegressionFactory.BasisFunctions.GetDesignMatrix(m_GridPointArguments, gridPointCount, order);
                        m_AdjustedReciprocalSingularValues = designMatrix.GetSingularValueDecomposition(out m_U, out m_Vt);

                        // compute \Sigma^{-1} =\diag(s_1,...,s_n,0,....,0)^{-1}:

                        double relThreshold = m_LeastSquaresRegressionFactory.RelativeSingularValueThreshold * m_AdjustedReciprocalSingularValues[0]; // the singular values are given in decresing order
                        double absSingularValueThreshold = m_LeastSquaresRegressionFactory.AbsoluteSingularValueThreshold;
                        for (int j = 0; j <= order; j++)
                        {
                            double singularValue = m_AdjustedReciprocalSingularValues[j];
                            if ((singularValue < absSingularValueThreshold) || (singularValue < relThreshold))
                            {
                                m_AdjustedReciprocalSingularValues[j] = 0;
                            }
                            else
                            {
                                m_AdjustedReciprocalSingularValues[j] = 1.0 / singularValue;
                            }
                        }
                    }
                    if (state.HasFlag(GridPointCurve.State.GridPointValueChanged))
                    {
                        ArrayMemory.Reallocate(ref m_GridPointValues, gridPointCount, Math.Max(10, gridPointCount / 5));
                        gridPointValues.CopyTo(m_GridPointValues, gridPointCount, gridPointValueStartIndex, sourceIncrement: gridPointValueIncrement);
                    }

                    /* one may compute b = U^t*b using BLAS, where 'b' are the grid point values, which gives a
                     * vector of length #grid points. Afterwards, one divided the first (Order+1) elements with
                     * the adjusted singular values and truncate the vector (only the first (Order+1) elements are needed)
                     * for later use.
                     *
                     * Disadvantages:
                     *
                     * - b = U^t*b does no work with 'dgemv', but c = U^t*b + 0.0*c, where 'c' is some working
                     *   array of length #grid points. This is a #grid point x #grid point operation,
                     * - the working array 'c' has #grid points elements, but we need the first (Order+1) elements only.
                     *
                     * example BLAS Code:
                     *
                     * m_WorkingArray = new double[values.Count];
                     * BLAS.Level2.dgemv(values.Count, values.Count, 1.0, m_U.m_Data, BLAS.MatrixTransposeState.Transpose, values, 0.0, m_WorkingArray);
                     * for (int k = 0; k <= m_Order; k++){
                     *    m_WorkingArray[k] *= m_AdjustedReciprocalSingularValues[k];}
                     *
                     */
                    for (int j = 0; j <= order; j++)  // we do not use BLAS (see above), its a (order+1) * #grid point operation only
                    {
                        double value = 0.0;
                        for (int k = 0; k < gridPointCount; k++)
                        {
                            value += m_U[k, j] * m_GridPointValues[k];
                        }
                        m_WorkingArray[j] = value * m_AdjustedReciprocalSingularValues[j];
                    }
                    // the multiplication of the (Order+1,Order+1)-matrix V and the 'working array' gives the coefficients:
                    BLAS.Level2.dgemv(order + 1, order + 1, 1.0, m_Vt.Data, m_WorkingArray, 0.0, m_Coefficients, BLAS.MatrixTransposeState.Transpose);
                }
            }
コード例 #16
0
 /// <summary>Updates the current boundary condition.
 /// </summary>
 /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointArguments"/> and <paramref name="gridPointValues"/> to take into account.</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="state">The state of the grid points, i.e. <paramref name="gridPointArguments"/> and <paramref name="gridPointValues"/>, with respect to the previous function call.</param>
 /// <param name="gridPointArgumentsStartIndex">The null-based start index of <paramref name="gridPointArguments"/> to take into account.</param>
 /// <param name="gridPointValuesStartIndex">The null-based start index of <paramref name="gridPointValues"/> to take into account.</param>
 /// <param name="gridPointArgumentIncrement">The increment for <paramref name="gridPointArguments"/>.</param>
 /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues"/>.</param>
 /// <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.
 /// </remarks>
 public void Update(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, GridPointCurve.State state, int gridPointArgumentsStartIndex = 0, int gridPointValuesStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
 {
     // nothing to do
 }
コード例 #17
0
            /// <summary>Updates the current curve interpolator.
            /// </summary>
            /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" /> to take into account.</param>
            /// <param name="gridPointArguments">The arguments of the grid points, thus labels of the curve in its <see cref="System.Double" /> representation in ascending order.</param>
            /// <param name="gridPointValues">The values of the grid points corresponding to <paramref name="gridPointArguments" />.</param>
            /// <param name="state">The state of the grid points, i.e. <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" />, with respect to the previous function call.</param>
            /// <param name="gridPointArgumentStartIndex">The null-based start index of <paramref name="gridPointArguments" /> 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" />.</param>
            /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues" />.</param>
            /// <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(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, GridPointCurve.State state, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
            {
                double[] coefficientsB, coefficientsC, coefficientsD;
                m_SplineEvaluator.Update(gridPointCount, gridPointArguments, gridPointValues, state, out coefficientsB, out coefficientsC, out coefficientsD, gridPointArgumentStartIndex, gridPointValueStartIndex, gridPointArgumentIncrement, gridPointValueIncrement);

                double deltaT     = m_SplineEvaluator.GridPointArguments[1] - m_SplineEvaluator.GridPointArguments[0]; // = t_{j+1} - t_j
                double nextDeltaT = m_SplineEvaluator.GridPointArguments[2] - m_SplineEvaluator.GridPointArguments[1]; // = t_{j+2} - t_{j+1}

                double b = ((m_SplineEvaluator.GridPointArguments[2] + m_SplineEvaluator.GridPointArguments[1] - 2 * m_SplineEvaluator.GridPointArguments[0]) * (m_SplineEvaluator.GridPointValues[1] - m_SplineEvaluator.GridPointValues[0]) / deltaT - deltaT * (m_SplineEvaluator.GridPointValues[2] - m_SplineEvaluator.GridPointValues[1]) / nextDeltaT) / (m_SplineEvaluator.GridPointArguments[2] - m_SplineEvaluator.GridPointArguments[0]);

                int    k        = 0; // k is the shortcut for j-1, i.e. k = j-1
                double valueAtk = m_SplineEvaluator.GridPointValues[k];

                for (int j = 1; j < gridPointCount - 1; j++)
                {
                    double valueAtj = m_SplineEvaluator.GridPointValues[j];

                    nextDeltaT = m_SplineEvaluator.GridPointArguments[j + 1] - m_SplineEvaluator.GridPointArguments[j];

                    double nextB = (nextDeltaT * (valueAtj - valueAtk) / deltaT + deltaT * (m_SplineEvaluator.GridPointValues[j + 1] - valueAtj) / nextDeltaT) / (m_SplineEvaluator.GridPointArguments[j + 1] - m_SplineEvaluator.GridPointArguments[k]);

                    double m = (valueAtj - valueAtk) / deltaT;

                    coefficientsB[k] = b;
                    coefficientsC[k] = (3 * m - nextB - 2 * b) / deltaT;
                    coefficientsD[k] = (nextB + b - 2 * m) / (deltaT * deltaT);

                    b        = nextB;
                    deltaT   = nextDeltaT;
                    valueAtk = valueAtj;
                    k++;
                }

                // Special case for the last coefficients: (k=n-1)
                int    n   = gridPointCount - 1;
                double b_n = -(nextDeltaT * (m_SplineEvaluator.GridPointValues[n - 1] - m_SplineEvaluator.GridPointValues[n - 2]) / deltaT - (2 * m_SplineEvaluator.GridPointArguments[n] - m_SplineEvaluator.GridPointArguments[n - 1] - m_SplineEvaluator.GridPointArguments[n - 2]) * (m_SplineEvaluator.GridPointValues[n] - m_SplineEvaluator.GridPointValues[n - 1]) / nextDeltaT) / (m_SplineEvaluator.GridPointArguments[n] - m_SplineEvaluator.GridPointArguments[n - 2]);
                double m_n = (m_SplineEvaluator.GridPointValues[n] - m_SplineEvaluator.GridPointValues[n - 1]) / nextDeltaT;

                coefficientsB[k] = b;
                coefficientsC[k] = (3 * m_n - b_n - 2 * b) / deltaT;
                coefficientsD[k] = (b_n + b - 2 * m_n) / (deltaT * deltaT);
            }
コード例 #18
0
            /// <summary>Updates the current curve fitting object.
            /// </summary>
            /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" /> to take into account.</param>
            /// <param name="gridPointArguments">The arguments of the grid points, thus labels of the curve in its <see cref="System.Double" /> representation in ascending order.</param>
            /// <param name="gridPointValues">The values of the grid points corresponding to <paramref name="gridPointArguments" />.</param>
            /// <param name="gridPointArgumentHint">Describes the structure of the grid point arguments.</param>
            /// <param name="gridPointValueHint">Describes the structure of the grid point values.</param>
            /// <param name="gridPointValueTransformation">A transformation to apply to the grid point values, i.e. number of grid points and grid point values (mainly used for log-linear interpolation).
            /// Caution: The application of a transformation has an impact on <see cref="Interpolator.GridPointValues"/>.</param>
            /// <param name="state">The state of the grid points, i.e. <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" />, with respect to the previous function call.</param>
            /// <param name="gridPointArgumentStartIndex">The null-based start index of <paramref name="gridPointArguments" /> 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" />.</param>
            /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues" />.</param>
            /// <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>
            /// <para>This method should always store all required data for later use, i.e. creates deep copies of the arguments.</para>
            /// </remarks>
            public void Update(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, MklGridPointCurve.xHintValue gridPointArgumentHint, MklGridPointCurve.yHintValue gridPointValueHint, Action <int, double[]> gridPointValueTransformation, GridPointCurve.State state = GridPointCurve.State.GridPointChanged, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
            {
                if (gridPointCount <= 0)
                {
                    m_GridPointCount = 0;  // i.e. current instance is not operable
                }
                else
                {
                    m_GridPointCount = gridPointCount;
                    bool isInitializedBefore = m_Task != IntPtr.Zero;

                    if (state.HasFlag(GridPointCurve.State.GridPointArgumentChanged))
                    {
                        if (ArrayMemory.Reallocate(ref m_GridPointArguments, gridPointCount, Math.Max(10, gridPointCount / 5)) == true)
                        {
                            m_ReadOnlyGridPointArguments = new ReadOnlyCollection <double>(m_GridPointArguments);
                            if (isInitializedBefore == true)
                            {
                                CheckErrorCode(_dfdEditPtr(m_Task, PtrParameterChangeType.DF_X, m_GridPointArguments), "dfdEditPtr");
                            }
                        }
                        gridPointArguments.CopyTo(m_GridPointArguments, gridPointCount, gridPointArgumentStartIndex, sourceIncrement: gridPointArgumentIncrement);

                        if ((ArrayMemory.Reallocate(ref m_SplineCoefficients, (int)m_MklDataFitting.m_SplineOrder * gridPointCount, Math.Max(10, gridPointCount / 5)) == true) && (isInitializedBefore == true))
                        {
                            CheckErrorCode(_dfdEditPtr(m_Task, PtrParameterChangeType.DF_PP_SCOEFF, m_SplineCoefficients), "dfdEditPtr");
                        }
                        if (isInitializedBefore == true)
                        {
                            CheckErrorCode(_dfiEditVal(m_Task, IntParameterChangeType.DF_XHINT, (int)gridPointArgumentHint), "dfiEditVal");
                        }
                    }

                    if (state.HasFlag(GridPointCurve.State.GridPointValueChanged))
                    {
                        if (ArrayMemory.Reallocate(ref m_GridPointValues, gridPointCount, Math.Max(10, gridPointCount / 5)) == true)
                        {
                            m_ReadOnlyGridPointValues = new ReadOnlyCollection <double>(m_GridPointValues);
                            if (isInitializedBefore == true)
                            {
                                CheckErrorCode(_dfdEditPtr(m_Task, PtrParameterChangeType.DF_Y, m_GridPointValues), "dfdEditPtr");
                            }
                        }
                        gridPointValues.CopyTo(m_GridPointValues, gridPointCount, gridPointValueStartIndex, sourceIncrement: gridPointValueIncrement);

                        gridPointValueTransformation(gridPointCount, m_GridPointValues);  // mainly used for log-linear transformation, i.e. apply logarithm to each grid point value. Caution: The public properties shows transformed values as well!

                        if (isInitializedBefore == true)
                        {
                            CheckErrorCode(_dfiEditVal(m_Task, IntParameterChangeType.DF_NX, gridPointCount), "dfiEditVal");
                            CheckErrorCode(_dfiEditVal(m_Task, IntParameterChangeType.DF_YHINT, (int)gridPointValueHint), "dfiEditVal");
                        }
                        else
                        {
                            CheckErrorCode(_dfdNewTask1D(out m_Task, gridPointCount, m_GridPointArguments, gridPointArgumentHint, 1, m_GridPointValues, gridPointValueHint), "dfdNewTask1D");
                        }
                    }

                    if (state != GridPointCurve.State.NoChangeSinceLastUpdate)
                    {
                        CheckErrorCode(_dfdEditPPSpline1D(m_Task, m_MklDataFitting.m_SplineOrder, m_MklDataFitting.m_SplineType, m_MklDataFitting.m_BoundaryConditionType, m_MklDataFitting.m_BoundaryCondition, m_MklDataFitting.m_InternalConditionTypes, m_MklDataFitting.m_InternalConditions, m_SplineCoefficients, m_MklDataFitting.m_SplineCoefficientHint), "dfdEditPPSpline1D");

                        if (m_MklDataFitting.m_SplineOrder != MklCurveInterpolationSpline.SplineOrder.DF_PP_STD)  // for a 'real' spline interpolation, one has to calculate the spline coefficients
                        {
                            CheckErrorCode(_dfdConstruct1D(m_Task, MklCurveInterpolationSpline.SplineFormat.DF_PP_SPLINE, MklCurveInterpolationSpline.SplineConstructionMethod.DF_METHOD_STD), "dfdConstruct1D");
                        }
                    }
                }
            }
コード例 #19
0
 /// <summary>Updates the current curve fitting object.
 /// </summary>
 /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" /> to take into account.</param>
 /// <param name="gridPointArguments">The arguments of the grid points, thus labels of the curve in its <see cref="System.Double" /> representation in ascending order.</param>
 /// <param name="gridPointValues">The values of the grid points corresponding to <paramref name="gridPointArguments" />.</param>
 /// <param name="gridPointArgumentHint">Describes the structure of the grid point arguments.</param>
 /// <param name="gridPointValueHint">Describes the structure of the grid point values.</param>
 /// <param name="state">The state of the grid points, i.e. <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" />, with respect to the previous function call.</param>
 /// <param name="gridPointArgumentStartIndex">The null-based start index of <paramref name="gridPointArguments" /> 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" />.</param>
 /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues" />.</param>
 /// <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>
 /// <para>This method should always store all required data for later use, i.e. creates deep copies of the arguments.</para>
 /// </remarks>
 public void Update(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, MklGridPointCurve.xHintValue gridPointArgumentHint, MklGridPointCurve.yHintValue gridPointValueHint, GridPointCurve.State state = GridPointCurve.State.GridPointChanged, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
 {
     Update(gridPointCount, gridPointArguments, gridPointValues, gridPointArgumentHint, gridPointValueHint, (n, v) => { }, state, gridPointArgumentStartIndex, gridPointValueStartIndex, gridPointArgumentIncrement, gridPointValueIncrement);
 }
コード例 #20
0
 /// <summary>Updates the current curve interpolator.
 /// </summary>
 /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" /> to take into account.</param>
 /// <param name="gridPointArguments">The arguments of the grid points, thus labels of the curve in its <see cref="System.Double" /> representation in ascending order.</param>
 /// <param name="gridPointValues">The values of the grid points corresponding to <paramref name="gridPointArguments" />.</param>
 /// <param name="state">The state of the grid points, i.e. <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" />, with respect to the previous function call.</param>
 /// <param name="gridPointArgumentStartIndex">The null-based start index of <paramref name="gridPointArguments" /> 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" />.</param>
 /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues" />.</param>
 /// <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(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, GridPointCurve.State state, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
 {
     Update(gridPointCount, gridPointArguments, gridPointValues, MklGridPointCurve.xHintValue.DF_NO_HINT, MklGridPointCurve.yHintValue.DF_NO_HINT, state, gridPointArgumentStartIndex, gridPointValueStartIndex, gridPointArgumentIncrement, gridPointValueIncrement);
 }
コード例 #21
0
 /// <summary>Updates the current boundary condition.
 /// </summary>
 /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" /> to take into account.</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="state">The state of the grid points, i.e. <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" />, with respect to the previous function call.</param>
 /// <param name="gridPointArgumentStartIndex">The null-based start index of <paramref name="gridPointArguments" /> 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" />.</param>
 /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues" />.</param>
 /// <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.
 /// </remarks>
 public void Update(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, GridPointCurve.State state, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
 {
     if (state.HasFlag(GridPointCurve.State.GridPointArgumentChanged))
     {
         m_FirstXDelta = gridPointArguments[gridPointArgumentStartIndex + 1] - gridPointArguments[gridPointArgumentStartIndex];
         m_LastXDelta  = gridPointArguments[gridPointArgumentStartIndex + gridPointArgumentIncrement * (gridPointCount - 1)] - gridPointArguments[gridPointArgumentStartIndex + gridPointArgumentIncrement * (gridPointCount - 2)];
     }
     m_FirstYDelta = gridPointValues[gridPointValueStartIndex + 1] - gridPointValues[gridPointValueStartIndex];
     m_LastYDelta  = gridPointValues[gridPointValueStartIndex + gridPointValueIncrement * (gridPointCount - 1)] - gridPointValues[gridPointValueStartIndex + gridPointValueIncrement * (gridPointCount - 2)];
 }
コード例 #22
0
            /// <summary>Updates the current boundary condition.
            /// </summary>
            /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointArguments"/> and <paramref name="gridPointValues"/> to take into account.</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="state">The state of the grid points, i.e. <paramref name="gridPointArguments"/> and <paramref name="gridPointValues"/>, with respect to the previous function call.</param>
            /// <param name="gridPointArgumentsStartIndex">The null-based start index of <paramref name="gridPointArguments"/> to take into account.</param>
            /// <param name="gridPointValuesStartIndex">The null-based start index of <paramref name="gridPointValues"/> to take into account.</param>
            /// <param name="gridPointArgumentIncrement">The increment for <paramref name="gridPointArguments"/>.</param>
            /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues"/>.</param>
            /// <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.
            /// </remarks>
            public void Update(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, GridPointCurve.State state, int gridPointArgumentsStartIndex = 0, int gridPointValuesStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
            {
                if (gridPointCount < 2)
                {
                    m_FirstBoundaryCoefficient = m_LastBoundaryCoefficient = Double.NaN;
                }
                else
                {
                    double deltaT     = gridPointArguments[gridPointArgumentsStartIndex + gridPointArgumentIncrement] - gridPointArguments[gridPointArgumentsStartIndex];                                  // = t_{j+1} - t_j
                    double nextDeltaT = gridPointArguments[gridPointArgumentsStartIndex + 2 * gridPointArgumentIncrement] - gridPointArguments[gridPointArgumentsStartIndex + gridPointArgumentIncrement]; // = t_{j+2} - t_{j+1}

                    double valueAt1 = gridPointValues[gridPointValuesStartIndex + gridPointValueIncrement];
                    double m        = (valueAt1 - gridPointValues[gridPointValuesStartIndex]) / deltaT;

                    m_FirstBoundaryCoefficient = ((deltaT + deltaT + nextDeltaT) * m - deltaT * (gridPointValues[gridPointValuesStartIndex + 2 * gridPointValueIncrement] - valueAt1) / nextDeltaT) / (deltaT + nextDeltaT);


                    int lastGridPointArgumentIndex = gridPointArgumentsStartIndex + gridPointArgumentIncrement * (gridPointCount - 1);
                    int lastGridPointValueIndex    = gridPointValuesStartIndex + gridPointValueIncrement * (gridPointCount - 1);

                    double lastButOneDeltaT = gridPointArguments[lastGridPointArgumentIndex - 2 * gridPointArgumentIncrement] - gridPointArguments[lastGridPointArgumentIndex - gridPointArgumentIncrement];
                    double lastButOne_m     = (gridPointValues[lastGridPointValueIndex - 2 * gridPointValueIncrement] - gridPointValues[lastGridPointValueIndex - gridPointValueIncrement]) / lastButOneDeltaT;

                    double lastDeltaT = gridPointArguments[lastGridPointArgumentIndex - gridPointArgumentIncrement] - gridPointArguments[lastGridPointArgumentIndex];
                    double last_m     = (gridPointValues[lastGridPointValueIndex - gridPointValueIncrement] - gridPointValues[lastGridPointValueIndex]) / lastDeltaT;

                    m_LastBoundaryCoefficient = ((2.0 * lastDeltaT + lastButOneDeltaT) * last_m - lastDeltaT * last_m) / (lastButOneDeltaT + lastDeltaT);
                }
            }
コード例 #23
0
 /// <summary>Changes the value component of a specific grid point.
 /// </summary>
 /// <param name="gridPointIndex">The null-based index of the grid point.</param>
 /// <param name="value">The value.</param>
 /// <remarks>This method set the <see cref="IOperable.IsOperable"/> flag to <c>false</c>.</remarks>
 /// <exception cref="InvalidOperationException">Thrown, if <see cref="IGridPointCurve.IsReadOnly"/> is <c>true</c>.</exception>
 public void SetValue(int gridPointIndex, double value)
 {
     m_GridPointValues[gridPointIndex] = value;
     m_State |= GridPointCurve.State.GridPointValueChanged;
 }
コード例 #24
0
            /// <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 firstRowIndex    = 0;
                int lastRowIndex     = rowCount - 1;
                int relevantRowCount = rowCount;

                /* if the interpolation along vertical direction is a local approach a few function evaluations are needed only: */
                if (m_VerticalInterpolatorFactory.IsLocalApproach == true)
                {
                    if (y < m_VerticalDoubleLabels[0])  // above the grid points
                    {
                        lastRowIndex = Math.Min(rowCount - 1, m_VerticalAboveExtrapolatorFactory.GetLevelOfGridPointDependency(rowCount));
                    }
                    else if (y > m_VerticalDoubleLabels[rowCount - 1])  // below the grid points
                    {
                        firstRowIndex = Math.Max(0, rowCount - m_VerticalBelowExtrapolatorFactory.GetLevelOfGridPointDependency(rowCount) - 1);
                    }
                    else // inside the grid points
                    {
                        int nonLastLeftGridPointIndex = GridPointCurve.Utilities.GetNonLastNearestIndex(y, m_VerticalDoubleLabels, m_VerticalDoubleLabels.Length);

                        int upperLocalnessLevel = m_VerticalInterpolatorFactory.GetLeftLocalnessLevel(nonLastLeftGridPointIndex, rowCount);
                        int lowerLocalnessLevel = m_VerticalInterpolatorFactory.GetRightLocalnessLevel(nonLastLeftGridPointIndex, rowCount);

                        firstRowIndex = Math.Max(nonLastLeftGridPointIndex - upperLocalnessLevel, 0);
                        lastRowIndex  = Math.Min(nonLastLeftGridPointIndex + lowerLocalnessLevel, rowCount - 1);
                    }
                    relevantRowCount = lastRowIndex - firstRowIndex + 1;

                    /* perhaps one may take into account less rows than required for the interpolation, i.e. one has to adjust the first/last row index: */
                    if (relevantRowCount < m_VerticalInterpolatorFactory.MinimalRequiredNumberOfGridPoints)
                    {
                        int numberOfAdditionalRequiredRows = m_VerticalInterpolatorFactory.MinimalRequiredNumberOfGridPoints - relevantRowCount;

                        firstRowIndex = Math.Max(0, firstRowIndex - numberOfAdditionalRequiredRows);
                        lastRowIndex  = Math.Min(rowCount - 1, lastRowIndex + numberOfAdditionalRequiredRows);

                        relevantRowCount = lastRowIndex - firstRowIndex + 1;
                    }
                }

                /* compute values w.r.t. to the x-coordinate and each relevant row, i.e. store values to take into account for vertical
                 * 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 = firstRowIndex; j <= lastRowIndex; j++)
                {
                    m_TempValuesForVerticalEvaluation[k++] = m_CurvesAlongHorizontalDirection[j].GetValue(x);
                }

                GridPointCurve.State verticalCurveState = GridPointCurve.State.GridPointChanged;
                if ((m_VerticalInterpolatorFactory.IsLocalApproach == false) && (m_VerticalInterpolator.IsOperable == true) && (m_VerticalInterpolator.GridPointCount == rowCount))
                {
                    verticalCurveState = GridPointCurve.State.GridPointValueChanged;
                }
                m_VerticalInterpolator.Update(relevantRowCount, m_VerticalDoubleLabels, m_TempValuesForVerticalEvaluation, verticalCurveState, gridPointArgumentStartIndex: firstRowIndex);

                if (y < m_VerticalInterpolator.LowerBound)
                {
                    m_VerticalAboveExtrapolator.Update();
                    return(m_VerticalAboveExtrapolator.GetValue(y));
                }
                else if (y > m_VerticalInterpolator.UpperBound)
                {
                    m_VerticalBelowExtrapolator.Update();
                    return(m_VerticalBelowExtrapolator.GetValue(y));
                }
                return(m_VerticalInterpolator.GetValue(y));
            }
コード例 #25
0
            /// <summary>Updates the current curve fitting object.
            /// </summary>
            /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of gridPointArguments and gridPointValues to take into account.</param>
            /// <param name="gridPointArguments">The arguments of the grid points, thus labels of the curve in its <see cref="System.Double"/> representation in ascending order.</param>
            /// <param name="gridPointValues">The values of the grid points corresponding to gridPointArguments.</param>
            /// <param name="state">The state of the grid points, i.e. gridPointArguments and gridPointValues, with respect to the previous function call.</param>
            /// <param name="gridPointArgumentStartIndex">The null-based start index of gridPointArguments to take into account.</param>
            /// <param name="gridPointValueStartIndex">The null-based start index of gridPointValues to take into account.</param>
            /// <param name="gridPointArgumentIncrement">The increment for <paramref name="gridPointArguments"/>.</param>
            /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues"/>.</param>
            /// <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(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, GridPointCurve.State state = GridPointCurve.State.GridPointChanged, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
            {
                int n = gridPointCount - 1;

                if (n >= 3)
                {
                    m_BoundaryCondition.Update(gridPointCount, gridPointArguments, gridPointValues, state, gridPointArgumentStartIndex, gridPointValueStartIndex, gridPointArgumentIncrement, gridPointValueIncrement);

                    m_SplineEvaluator.Update(gridPointCount, gridPointArguments, gridPointValues, state, out double[] coefficientsB, out double[] coefficientsC, out double[] coefficientsD, gridPointArgumentStartIndex, gridPointValueStartIndex, gridPointArgumentIncrement, gridPointValueIncrement);

                    double b = m_BoundaryCondition.GetFirstBoundaryCoefficient();

                    int gridPointValueIndex    = gridPointValueStartIndex;
                    int gridPointArgumentIndex = gridPointArgumentStartIndex;

                    double deltaT = m_SplineEvaluator.GridPointArguments[gridPointArgumentIndex + gridPointArgumentIncrement] - m_SplineEvaluator.GridPointArguments[gridPointArgumentIndex]; // = t_{j+1} - t_j
                    double nextDeltaT;                                                                                                                                                        // = t_{j+2} - t_{j+1}

                    double m = (m_SplineEvaluator.GridPointValues[gridPointValueIndex + gridPointValueIncrement] - m_SplineEvaluator.GridPointValues[gridPointValueIndex]) / deltaT;

                    int    k      = 0;   // k is just the shortcut for j-1, i.e. k = j-1
                    double next_m = 0.0; // assiment is needed for the compiler only.

                    for (int j = 1; j < n; j++)
                    {
                        gridPointValueIndex    += gridPointValueIncrement;
                        gridPointArgumentIndex += gridPointArgumentIncrement;

                        nextDeltaT = m_SplineEvaluator.GridPointArguments[gridPointArgumentIndex + gridPointArgumentIncrement] - m_SplineEvaluator.GridPointArguments[gridPointArgumentIndex];
                        next_m     = (m_SplineEvaluator.GridPointValues[gridPointValueIndex + gridPointValueIncrement] - m_SplineEvaluator.GridPointValues[gridPointValueIndex]) / nextDeltaT;

                        double nextB = 0.0;
                        if (m * next_m > 0.0) // locally monotone
                        {
                            double max = Math.Max(m, next_m);
                            double min = Math.Min(m, next_m);
                            nextB = 3.0 * m * next_m / (max + min + min);

                            if (min > 0.0)  // locally increasing
                            {
                                nextB = Math.Min(Math.Max(0.0, nextB), 3.0 * min);
                            }
                            else if (max < 0.0)
                            {
                                nextB = Math.Max(Math.Min(0.0, nextB), 3.0 * max);
                            }
                        }
                        coefficientsB[k] = b;
                        coefficientsC[k] = (3.0 * m - nextB - b - b) / deltaT;
                        coefficientsD[k] = (nextB + b - m - m) / (deltaT * deltaT);

                        b      = nextB;
                        deltaT = nextDeltaT;
                        m      = next_m;
                        k++;
                    }

                    // Special case for the last coefficients, i.e. 'b_n':
                    b = m_BoundaryCondition.GetLastBoundaryCoefficient();

                    coefficientsB[k] = b;
                    coefficientsC[k] = (3.0 * next_m - b - b) / deltaT;
                    coefficientsD[k] = (b - next_m - next_m) / (deltaT * deltaT);
                }
            }
コード例 #26
0
 /// <summary>Updates the current curve fitting object.
 /// </summary>
 /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" /> to take into account.</param>
 /// <param name="gridPointArguments">The arguments of the grid points, thus labels of the curve in its <see cref="System.Double" /> representation in ascending order.</param>
 /// <param name="gridPointValues">The values of the grid points corresponding to <paramref name="gridPointArguments" />.</param>
 /// <param name="gridPointArgumentHint">Describes the structure of the grid point arguments.</param>
 /// <param name="gridPointValueHint">Describes the structure of the grid point values.</param>
 /// <param name="state">The state of the grid points, i.e. <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" />, with respect to the previous function call.</param>
 /// <param name="gridPointArgumentStartIndex">The null-based start index of <paramref name="gridPointArguments" /> 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" />.</param>
 /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues" />.</param>
 /// <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>
 /// <para>This method should always store all required data for later use, i.e. creates deep copies of the arguments.</para>
 /// </remarks>
 public void Update(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, MklGridPointCurve.xHintValue gridPointArgumentHint, MklGridPointCurve.yHintValue gridPointValueHint, GridPointCurve.State state = GridPointCurve.State.GridPointChanged, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
 {
     /* lets store a copy of the original grid point values: */
     if (state.HasFlag(GridPointCurve.State.GridPointValueChanged))
     {
         if (ArrayMemory.Reallocate(ref m_OriginalGridPointValues, gridPointCount, Math.Max(10, gridPointCount / 5)) == true)
         {
             m_OriginalGridPointValuesReadOnlyCollection = new ReadOnlyCollection <double>(m_OriginalGridPointValues);
         }
         gridPointValues.CopyTo(m_OriginalGridPointValues, gridPointCount, gridPointValueStartIndex, sourceIncrement: gridPointValueIncrement);
     }
     m_DataFitting.Update(gridPointCount, gridPointArguments, gridPointValues, gridPointArgumentHint, gridPointValueHint, (n, x) => { VectorUnit.Basics.Log(n, x); }, state, gridPointArgumentStartIndex, gridPointValueStartIndex, gridPointArgumentIncrement, gridPointValueIncrement);
 }
コード例 #27
0
 public void Update(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, GridPointCurve.State state, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
 {
     throw new NotImplementedException();
 }
コード例 #28
0
        /// <summary>Updates the current instance, i.e. stores the grid points and returns references to the coefficients of the splines.
        /// </summary>
        /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointArguments"/> and <paramref name="gridPointValues"/> to take into account.</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="state">The state of the grid points, i.e. <paramref name="gridPointArguments"/> and <paramref name="gridPointValues"/>, with respect to the previous function call.</param>
        /// <param name="coefficientsB">A reference to the coefficients 'b' with respect to f(t) = a[j] + b[j]*(t[j] - t) + c[j] * (t[j] - t)^2 + d[j] * (t[j] - t)^3. The caller of this method has to set valid coefficients (output).</param>
        /// <param name="coefficientsC">A reference to the coefficients 'c' with respect to f(t) = a[j] + b[j]*(t[j] - t) + c[j] * (t[j] - t)^2 + d[j] * (t[j] - t)^3. The caller of this method has to set valid coefficients (output).</param>
        /// <param name="coefficientsD">A reference to the coefficients 'd' with respect to f(t) = a[j] + b[j]*(t[j] - t) + c[j] * (t[j] - t)^2 + d[j] * (t[j] - t)^3. The caller of this method has to set valid coefficients (output).</param>
        /// <param name="gridPointArgumentStartIndex">The null-based start index of <paramref name="gridPointArguments" /> 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" />.</param>
        /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues" />.</param>
        public void Update(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, GridPointCurve.State state, out double[] coefficientsB, out double[] coefficientsC, out double[] coefficientsD, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
        {
            m_GridPointCount = gridPointCount;

            if (state.HasFlag(GridPointCurve.State.GridPointArgumentChanged))
            {
                if (ArrayMemory.Reallocate(ref m_GridPointArguments, gridPointCount, Math.Max(10, gridPointCount / 5)) == true)
                {
                    m_ReadOnlyGridPointArguments = new ReadOnlyCollection <double>(m_GridPointArguments);
                }
                gridPointArguments.CopyTo(m_GridPointArguments, gridPointCount, gridPointArgumentStartIndex, sourceIncrement: gridPointArgumentIncrement);
            }
            if (state.HasFlag(GridPointCurve.State.GridPointValueChanged))
            {
                if (ArrayMemory.Reallocate(ref m_GridPointValues, gridPointCount, Math.Max(10, gridPointCount / 5)) == true)
                {
                    m_ReadOnlyGridPointValues = new ReadOnlyCollection <double>(m_GridPointValues);
                }
                gridPointValues.CopyTo(m_GridPointValues, gridPointCount, gridPointValueStartIndex, sourceIncrement: gridPointValueIncrement);
            }

            /* allocate memory for spline coefficients if necessary and add a small buffer to avoid reallocation of memory: */
            ArrayMemory.Reallocate(ref m_CoefficientsB, gridPointCount - 1, Math.Max(10, gridPointCount / 5));
            coefficientsB = m_CoefficientsB;

            ArrayMemory.Reallocate(ref m_CoefficientsC, gridPointCount - 1, Math.Max(10, gridPointCount / 5));
            coefficientsC = m_CoefficientsC;

            ArrayMemory.Reallocate(ref m_CoefficientsD, gridPointCount - 1, Math.Max(10, gridPointCount / 5));
            coefficientsD = m_CoefficientsD;

            IntegralCacheUpdateRequested = true;
        }
コード例 #29
0
            /// <summary>Updates the current curve interpolator.
            /// </summary>
            /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" /> to take into account.</param>
            /// <param name="gridPointArguments">The arguments of the grid points, thus labels of the curve in its <see cref="System.Double" /> representation in ascending order.</param>
            /// <param name="gridPointValues">The values of the grid points corresponding to <paramref name="gridPointArguments" />.</param>
            /// <param name="state">The state of the grid points, i.e. <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" />, with respect to the previous function call.</param>
            /// <param name="gridPointArgumentStartIndex">The null-based start index of <paramref name="gridPointArguments" /> 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" />.</param>
            /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues" />.</param>
            /// <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(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, GridPointCurve.State state, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
            {
                if (gridPointCount <= 0)
                {
                    m_GridPointCount = 0;  // current instance is not operable
                }
                else
                {
                    m_GridPointCount = gridPointCount;

                    if (state.HasFlag(GridPointCurve.State.GridPointArgumentChanged))
                    {
                        if (ArrayMemory.Reallocate(ref m_GridPointArguments, gridPointCount, Math.Max(10, gridPointCount / 5)) == true)
                        {
                            m_ReadOnlyGridPointArguments = new ReadOnlyCollection <double>(m_GridPointArguments);
                        }
                        gridPointArguments.CopyTo(m_GridPointArguments, gridPointCount, gridPointArgumentStartIndex, sourceIncrement: gridPointArgumentIncrement);
                    }
                    if (state.HasFlag(GridPointCurve.State.GridPointValueChanged))
                    {
                        if (ArrayMemory.Reallocate(ref m_GridPointValues, gridPointCount, Math.Max(10, gridPointCount / 5)) == true)
                        {
                            m_ReadOnlyGridPointValues = new ReadOnlyCollection <double>(m_GridPointValues);
                        }
                        gridPointValues.CopyTo(m_GridPointValues, gridPointCount, gridPointValueStartIndex, sourceIncrement: gridPointValueIncrement);
                    }
                }
                m_IntegralCache.EarmarkUpdateRequest();
            }
コード例 #30
0
            /// <summary>Updates the current curve interpolator.
            /// </summary>
            /// <param name="gridPointCount">The number of grid points, i.e. the number of relevant elements of <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" /> to take into account.</param>
            /// <param name="gridPointArguments">The arguments of the grid points, thus labels of the curve in its <see cref="System.Double" /> representation in ascending order.</param>
            /// <param name="gridPointValues">The values of the grid points corresponding to <paramref name="gridPointArguments" />.</param>
            /// <param name="state">The state of the grid points, i.e. <paramref name="gridPointArguments" /> and <paramref name="gridPointValues" />, with respect to the previous function call.</param>
            /// <param name="gridPointArgumentStartIndex">The null-based start index of <paramref name="gridPointArguments" /> 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" />.</param>
            /// <param name="gridPointValueIncrement">The increment for <paramref name="gridPointValues" />.</param>
            /// <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(int gridPointCount, IList <double> gridPointArguments, IList <double> gridPointValues, GridPointCurve.State state, int gridPointArgumentStartIndex = 0, int gridPointValueStartIndex = 0, int gridPointArgumentIncrement = 1, int gridPointValueIncrement = 1)
            {
                m_BoundaryCondition.Update(gridPointCount, gridPointArguments, gridPointValues, state, gridPointArgumentStartIndex, gridPointValueStartIndex, gridPointArgumentIncrement, gridPointValueIncrement);

                double[] coefficientsB, coefficientsC, coefficientsD;
                m_SplineEvaluator.Update(gridPointCount, gridPointArguments, gridPointValues, state, out coefficientsB, out coefficientsC, out coefficientsD, gridPointArgumentStartIndex, gridPointValueStartIndex, gridPointArgumentIncrement, gridPointValueIncrement);

                int n         = gridPointCount;
                int nMinusOne = n - 1;

                double deltaT;

                // LU decomposition is necessary if and only if the labels have been changed, too:
                if (state.HasFlag(GridPointCurve.State.GridPointArgumentChanged) == true)
                {
                    ArrayMemory.Reallocate(ref m_DiagonalElements, n, Math.Max(10, n / 5));
                    ArrayMemory.Reallocate(ref m_SubDiagonalElements, nMinusOne, Math.Max(10, n / 5));
                    ArrayMemory.Reallocate(ref m_SuperDiagonalElements, nMinusOne, Math.Max(10, n / 5));
                    ArrayMemory.Reallocate(ref m_SecondSuperDiagonalElements, nMinusOne - 1, Math.Max(10, n / 5));
                    ArrayMemory.Reallocate(ref m_PivotIndices, n, Math.Max(10, n / 5));

                    deltaT = m_SplineEvaluator.GridPointArguments[1] - m_SplineEvaluator.GridPointArguments[0];
                    for (int j = 1; j < nMinusOne; j++)
                    {
                        double nextDeltaT = m_SplineEvaluator.GridPointArguments[j + 1] - m_SplineEvaluator.GridPointArguments[j];
                        m_SubDiagonalElements[j - 1] = deltaT;
                        m_DiagonalElements[j]        = 2.0 * (deltaT + nextDeltaT);
                        m_SuperDiagonalElements[j]   = nextDeltaT;
                        deltaT = nextDeltaT;
                    }
                    m_BoundaryCondition.GetRemainingMatrixElements(out m_DiagonalElements[0], out m_SuperDiagonalElements[0], out m_SubDiagonalElements[n - 2], out m_DiagonalElements[nMinusOne]);
                    LAPACK.LinearEquations.MatrixFactorization.dgttrf(n, m_SubDiagonalElements, m_DiagonalElements, m_SuperDiagonalElements, m_SecondSuperDiagonalElements, m_PivotIndices);
                }

                /* Compute the right hand side of Ax=b, where A is the tri-diagonal matrix already calculated and
                 * b depends on the second derivatives and the boundary condition only. We store the value of b in *coefficientsC*:
                 */
                deltaT = m_SplineEvaluator.GridPointArguments[1] - m_SplineEvaluator.GridPointArguments[0];
                for (int j = 1; j < nMinusOne; j++)
                {
                    double nextDeltaT = m_SplineEvaluator.GridPointArguments[j + 1] - m_SplineEvaluator.GridPointArguments[j];
                    coefficientsC[j] = 3.0 * ((m_SplineEvaluator.GridPointValues[j + 1] - m_SplineEvaluator.GridPointValues[j]) / nextDeltaT - (m_SplineEvaluator.GridPointValues[j] - m_SplineEvaluator.GridPointValues[j - 1]) / deltaT);
                    deltaT           = nextDeltaT;
                }
                m_BoundaryCondition.GetRemainingRightHandSideElements(out coefficientsC[0], out coefficientsC[nMinusOne]);

                /* Calculate the solution x of Ax=b. The solution is the coefficient 'c' and 'dttrs' stores the result in 'coefficientsC': */
                LAPACK.LinearEquations.Solver.dgttrs(n, m_SubDiagonalElements, m_DiagonalElements, m_SuperDiagonalElements, m_SecondSuperDiagonalElements, m_PivotIndices, coefficientsC, 1);

                /* Calculate the coefficients b_j and d_j: */
                for (int k = 0; k < nMinusOne; k++)
                {
                    deltaT = m_SplineEvaluator.GridPointArguments[k + 1] - m_SplineEvaluator.GridPointArguments[k];

                    coefficientsD[k] = (coefficientsC[k + 1] - coefficientsC[k]) / (3.0 * deltaT);
                    coefficientsB[k] = (m_SplineEvaluator.GridPointValues[k + 1] - m_SplineEvaluator.GridPointValues[k]) / deltaT - deltaT * (2 * coefficientsC[k] + coefficientsC[k + 1]) / 3.0;
                }
            }