コード例 #1
0
ファイル: PolynomialFitting.cs プロジェクト: Altaxo/Altaxo
		public static string Fit(Altaxo.Gui.Graph.Gdi.Viewing.IGraphController ctrl, int order, double fitCurveXmin, double fitCurveXmax, bool showFormulaOnGraph)
		{
			string error;

			double[] xarr, yarr;
			error = GetActivePlotPoints(ctrl, out xarr, out yarr);
			int numberOfDataPoints = xarr.Length;

			if (null != error)
				return error;

			string[] plotNames = GetActivePlotName(ctrl);

			int numberOfParameter = order + 1;
			double[] parameter = new double[numberOfParameter];
			LinearFitBySvd fit =
				new LinearFitBySvd(
				xarr, yarr, null, numberOfDataPoints, order + 1, new FunctionBaseEvaluator(EvaluatePolynomialBase), 1E-5);

			// Output of results

			Current.Console.WriteLine("");
			Current.Console.WriteLine("---- " + DateTime.Now.ToString() + " -----------------------");
			Current.Console.WriteLine("Polynomial regression of order {0} of {1} over {2}", order, plotNames[1], plotNames[0]);

			Current.Console.WriteLine(
				"Name           Value               Error               F-Value             Prob>F");

			for (int i = 0; i < fit.Parameter.Length; i++)
				Current.Console.WriteLine("A{0,-3} {1,20} {2,20} {3,20} {4,20}",
					i,
					fit.Parameter[i],
					fit.StandardErrorOfParameter(i),
					fit.TofParameter(i),
					1 - FDistribution.CDF(fit.TofParameter(i), numberOfParameter, numberOfDataPoints - 1)
					);

			Current.Console.WriteLine("R²: {0}, Adjusted R²: {1}",
				fit.RSquared,
				fit.AdjustedRSquared);

			Current.Console.WriteLine("------------------------------------------------------------");
			Current.Console.WriteLine("Source of  Degrees of");
			Current.Console.WriteLine("variation  freedom          Sum of Squares          Mean Square          F0                   P value");

			double regressionmeansquare = fit.RegressionCorrectedSumOfSquares / numberOfParameter;
			double residualmeansquare = fit.ResidualSumOfSquares / (numberOfDataPoints - numberOfParameter - 1);

			Current.Console.WriteLine("Regression {0,10} {1,20} {2,20} {3,20} {4,20}",
				numberOfParameter,
				fit.RegressionCorrectedSumOfSquares,
				fit.RegressionCorrectedSumOfSquares / numberOfParameter,
				regressionmeansquare / residualmeansquare,
				1 - FDistribution.CDF(regressionmeansquare / residualmeansquare, numberOfParameter, numberOfDataPoints - 1)
				);

			Current.Console.WriteLine("Residual   {0,10} {1,20} {2,20}",
				numberOfDataPoints - 1 - numberOfParameter,
				fit.ResidualSumOfSquares,
				residualmeansquare
				);

			Current.Console.WriteLine("Total      {0,10} {1,20}",
				numberOfDataPoints - 1,
				fit.TotalCorrectedSumOfSquares

				);

			Current.Console.WriteLine("------------------------------------------------------------");

			// add the fit curve to the graph
			IScalarFunctionDD plotfunction = new PolynomialFunction(fit.Parameter);
			XYFunctionPlotItem fittedCurve = new XYFunctionPlotItem(new XYFunctionPlotData(plotfunction), new G2DPlotStyleCollection(LineScatterPlotStyleKind.Line, ctrl.Doc.GetPropertyContext()));

			var xylayer = ctrl.ActiveLayer as XYPlotLayer;
			if (null != xylayer)
				xylayer.PlotItems.Add(fittedCurve);

			return null;
		}
コード例 #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
ファイル: PolynomialFitting.cs プロジェクト: Altaxo/Altaxo
		/// <summary>
		/// Fits data provided as xcolumn and ycolumn with a polynomial base.
		/// </summary>
		/// <param name="order">The order of the fit (1:linear, 2:quadratic, etc.)</param>
		/// <param name="xcolumn">The column of x-values.</param>
		/// <param name="ycolumn">The column of y-values.</param>
		/// <returns>The fit.</returns>
		public static LinearFitBySvd Fit(int order, Altaxo.Data.DataColumn xcolumn, Altaxo.Data.DataColumn ycolumn)
		{
			if (!(xcolumn is Altaxo.Data.INumericColumn))
				throw new ArgumentException("The x-column must be numeric", "xcolumn");
			if (!(ycolumn is Altaxo.Data.INumericColumn))
				throw new ArgumentException("The y-column must be numeric", "ycolumn");

			int firstIndex = 0;
			int count = Math.Min(xcolumn.Count, ycolumn.Count);

			double[] xarr = new double[count];
			double[] yarr = new double[count];
			double[] earr = new double[count];

			Altaxo.Data.INumericColumn xcol = (Altaxo.Data.INumericColumn)xcolumn;
			Altaxo.Data.INumericColumn ycol = (Altaxo.Data.INumericColumn)ycolumn;

			int numberOfDataPoints = 0;
			int endIndex = firstIndex + count;
			for (int i = firstIndex; i < endIndex; i++)
			{
				double x = xcol[i];
				double y = ycol[i];
				if (double.IsNaN(x) || double.IsNaN(y))
					continue;

				xarr[numberOfDataPoints] = x;
				yarr[numberOfDataPoints] = y;
				earr[numberOfDataPoints] = 1;
				numberOfDataPoints++;
			}

			LinearFitBySvd fit =
				new LinearFitBySvd(
				xarr, yarr, earr, numberOfDataPoints, order + 1, new FunctionBaseEvaluator(EvaluatePolynomialBase), 1E-5);

			return fit;
		}