示例#1
0
        /// <summary>
        /// Processes the spectra in matrix xMatrix according to the set-up options.
        /// </summary>
        /// <param name="xMatrix">The matrix of spectra. Each spectrum is a row of the matrix.</param>
        /// <param name="xMean">Will be filled with the spectral mean.</param>
        /// <param name="xScale">Will be filled with the inverse spectral variance.(Or with 1 if the user has not choosen this option).</param>
        public void Process(IMatrix <double> xMatrix, IVector <double> xMean, IVector <double> xScale)
        {
            // before processing, fill xScale with 1
            VectorMath.FillWith(xScale, 1);

            GetPreprocessingMethod().Process(xMatrix, xMean, xScale, _regions);

            if (UseDetrending)
            {
                new DetrendingCorrection(_detrendingOrder).Process(xMatrix, xMean, xScale, _regions);
            }

            if (EnsembleMeanAfterProcessing || EnsembleScale)
            {
                new EnsembleMeanAndScaleCorrection(EnsembleMeanAfterProcessing, EnsembleScale).Process(xMatrix, xMean, xScale, _regions);
            }
        }
示例#2
0
        /// <summary>
        /// Fits data provided as xcolumn and ycolumn with a polynomial base. Here special measures are taken (scaling of the x-variable) in order
        /// to keep the precision high.
        /// </summary>
        /// <param name="order">The order of the fit (1:linear, 2:quadratic, etc.)</param>
        /// <param name="xValues">The array of x-values. The values of the array are destroyed (altered) during the evaluation!</param>
        /// <param name="yValues">The array of y-values.</param>
        /// <param name="errorValues">The column of errorValues. If null, errorValues are set to 1 for each element.</param>
        /// <param name="count">Number of values to use (array[0] ... array[count-1].</param>
        /// <returns>The fit.</returns>
        public static LinearFitBySvd FitPolymomialDestructive(int order, double[] xValues, double[] yValues, double[] errorValues, int count)
        {
            if (!(xValues != null))
            {
                throw new ArgumentNullException(nameof(xValues));
            }
            if (!(yValues != null))
            {
                throw new ArgumentNullException(nameof(yValues));
            }
            if (!(count > 0))
            {
                throw new ArgumentOutOfRangeException(nameof(count), "must be >0");
            }
            if (!(count <= xValues.Length))
            {
                throw new ArgumentOutOfRangeException(nameof(count), "exceeds capacity of array " + nameof(xValues));
            }
            if (!(count <= yValues.Length))
            {
                throw new ArgumentOutOfRangeException(nameof(count), "exceeds capacity of array " + nameof(yValues));
            }
            if (null != errorValues && !(count <= errorValues.Length))
            {
                throw new ArgumentOutOfRangeException(nameof(count), "exceeds capacity of array " + nameof(errorValues));
            }

            double[] xarr = xValues;
            double[] yarr = yValues;
            double[] earr = errorValues;

            if (null == earr)
            {
                earr = new double[count];
                VectorMath.FillWith(earr, 1);
            }

            int numberOfDataPoints = count;

            // we scale the x-values in order to keep the Condition number reasonable

            var xmin = Altaxo.Calc.LinearAlgebra.VectorMath.Min(xarr, 0, numberOfDataPoints);
            var xmax = Altaxo.Calc.LinearAlgebra.VectorMath.Max(xarr, 0, numberOfDataPoints);

            double xscale    = Math.Max(-xmin, xmax);
            double xinvscale = 1 / xscale;

            if (0 == xscale)
            {
                xscale = xinvscale = 1;
            }

            for (int i = 0; i < numberOfDataPoints; ++i)
            {
                xarr[i] *= xinvscale;
            }

            var fit =
                new LinearFitBySvd(
                    xarr, yarr, earr, numberOfDataPoints, order + 1, new FunctionBaseEvaluator(GetPolynomialFunctionBase(order)), 1E-15);

            // rescale parameter of fit in order to account for rescaled x variable
            for (int i = 0; i <= order; ++i)
            {
                fit._parameter[i] *= RMath.Pow(xinvscale, i);
                for (int j = 0; j <= order; ++j)
                {
                    fit._covarianceMatrix[i][j] *= RMath.Pow(xinvscale, i + j);
                }
            }

            return(fit);
        }
示例#3
0
        private void EvaluateInternally(double?tout, out double t_result, double[] result)
        {
            if (_initializationState == InitializationState.NotInitialized) // not initialized so far
            {
                _initializationState = InitializationState.InitialValueReturned;

                if (null == tout)
                {
                    last_tout = t_result = currstate._tn;
                    currstate._zn.CopyColumn(0, result);
                    return;
                }
            }
            else if (_initializationState == InitializationState.Initialized)
            {
                // we have to clone some of the code from below to here
                // this is no good style, but a goto statement with a jump inside another code block will not work here.

                if (tout.HasValue)
                {
                    // Output data, but only if (i) we have requested a certain time point,
                    // and ii) as long as we can interpolate this point from the previous point and the current point
                    if (currstate._tn <= tout.Value && tout.Value <= currstate._tn + currstate._dt)
                    {
                        // VectorMath.Lerp(tout.Value, currstate.tn, xout, currstate.tn + currstate.dt, currstate.xn, result);
                        currstate.EvaluateYAtTime(tout.Value, result);
                        last_tout = t_result = tout.Value;
                        return;
                    }
                }
                else
                {
                    if (currstate._tn == last_tout)
                    {
                        last_tout = t_result = currstate._tn + currstate._dt;
                        VectorMath.Copy(currstate._xn, result);
                        return;
                    }
                }

                VectorMath.Copy(currstate._xn, xout); // save x of this step

                currstate._tn = currstate._tn + currstate._dt;

                if (opts.MaxStep < double.MaxValue)
                {
                    r = Math.Min(r, opts.MaxStep / currstate._dt);
                }

                if (opts.MinStep > 0)
                {
                    r = Math.Max(r, opts.MinStep / currstate._dt);
                }

                r = Math.Min(r, opts.MaxScale);
                r = Math.Max(r, opts.MinScale);

                currstate._dt = currstate._dt * r;

                currstate.Rescale(r);
            }

            _initializationState = InitializationState.Initialized;
            //Can produce any number of solution points
            while (true)
            {
                // Reset fail flag
                isIterationFailed = false;

                // Predictor step
                _zn_saved.CopyFrom(currstate._zn);
                currstate.ZNew();
                VectorMath.FillWith(currstate._en, 0); // TODO find out if this statement is neccessary
                currstate._zn.CopyColumn(0, currstate._xn);

                // Corrector step
                currstate.PredictorCorrectorScheme(ref isIterationFailed, f, _denseJacobianEvaluation, _sparseJacobianEvaluation, opts);

                if (isIterationFailed)                 // If iterations are not finished - bad convergence
                {
                    currstate._zn.CopyFrom(_zn_saved); // copy saved state back
                    currstate._nsuccess = 0;
                    currstate.DivideStepBy2();
                }
                else // Iterations finished, i.e. did not fail
                {
                    r = Math.Min(1.1d, Math.Max(0.2d, currstate._rFactor));

                    if (currstate._delta >= 1.0d)
                    {
                        if (opts.MaxStep < double.MaxValue)
                        {
                            r = Math.Min(r, opts.MaxStep / currstate._dt);
                        }

                        if (opts.MinStep > 0)
                        {
                            r = Math.Max(r, opts.MinStep / currstate._dt);
                        }

                        r = Math.Min(r, opts.MaxScale);
                        r = Math.Max(r, opts.MinScale);

                        currstate._dt = currstate._dt * r; // Decrease step
                        currstate.Rescale(r);
                    }
                    else // Iteration finished successfully
                    {
                        // Output data
                        if (tout.HasValue)
                        {
                            if (currstate._tn <= tout.Value && tout.Value <= currstate._tn + currstate._dt)
                            {
                                // VectorMath.Lerp(tout.Value, currstate.tn, xout, currstate.tn + currstate.dt, currstate.xn, result);
                                currstate.EvaluateYAtTime(tout.Value, result);
                                t_result = tout.Value;

                                return;
                            }
                        }
                        else
                        {
                            VectorMath.Copy(currstate._xn, result);
                            t_result = last_tout = currstate._tn + currstate._dt;
                            return;
                        }

                        VectorMath.Copy(currstate._xn, xout);

                        currstate._tn = currstate._tn + currstate._dt;

                        if (opts.MaxStep < double.MaxValue)
                        {
                            r = Math.Min(r, opts.MaxStep / currstate._dt);
                        }

                        if (opts.MinStep > 0)
                        {
                            r = Math.Max(r, opts.MinStep / currstate._dt);
                        }

                        r = Math.Min(r, opts.MaxScale);
                        r = Math.Max(r, opts.MinScale);

                        currstate._dt = currstate._dt * r;
                        currstate.Rescale(r);
                    }
                }
            }
        }