예제 #1
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;
        }
예제 #2
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();
            }
예제 #3
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;
                }
            }
 /// <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);
 }
예제 #5
0
        /// <summary>Updates the internal cache.
        /// </summary>
        private void Update()
        {
            ArrayMemory.Reallocate(ref m_Cache, GridPointCount, pufferSize: 5);

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

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

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

                /* prepare for next loop: */
                lowerBound = upperBound;
            }
            UpdateRequested = false;
        }
            /// <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);
                }
            }
예제 #7
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");
                        }
                    }
                }
            }