public void Fit(DenseVector y_train, DenseMatrix x_train, bool constant = true) { intercept = constant; y = y_train; if (intercept) { var features = new Vector <double> [x_train.ColumnCount + 1]; features[0] = DenseVector.OfEnumerable(Enumerable.Repeat <double>(1, y.Count)); for (int column = 0; column < x_train.ColumnCount; column++) { features[1 + column] = x_train.Column(column); } x = DenseMatrix.OfColumns(features); } else { x = x_train; } N = y.Count; k = x_train.ColumnCount; betas = MultipleRegression.QR(x, y); predictions = x.Transpose().LeftMultiply(betas); errors = y - predictions; r_squared = 1 - (Variance(errors) / Variance(y)); // R^2 = 1 - RSS/TSS r_squared_adjusted = 1 - ((1 - r_squared) * (N - 1) / (N - k - 1)); // R^2-Adjusted = 1 - (1-R^2)(N-1) / (N-k-1) }
//Called after gathering training data public Vector <double>[] Solve(double[,] X, double[,] yArray) { //Solve matrix to generate weights for runtime calibration double[] y = new double[yArray.GetLength(0)]; Vector <double>[] theta = new Vector <double> [yArray.GetLength(1)]; //Process each collum one by one for (int i = 0; i < yArray.GetLength(1); i++) { //Clone raw data to manipulate double[,] Xclone = X.Clone() as double[, ]; //Disable channels not used for this solve Xclone = DisableChannels(Xclone, ActiveSensors, i); Matrix <double> XMatrix = CreateMatrix.DenseOfArray(Xclone); RemoveChannels temp = RemoveEmptyChannels(XMatrix); XMatrix = temp.ReducedMatrix; //Get a solution vector y = getCollumn(yArray, i); Matrix <double> tempMat = XMatrix; //Perform Regression fit Vector <double> yVector = CreateVector.DenseOfArray(y); theta[i] = MultipleRegression.Svd <double>(tempMat, yVector); //Add removed collumns theta[i] = PadArray(temp.usedCol, theta[i]); } return(theta); }
public static List <double> CalculateCholesskyRegression(double [][] v, double [] c) { double[] slopes = null; try { slopes = MultipleRegression.NormalEquations(v, c, false); } catch { slopes = MultipleRegression.QR(v, c); Console.WriteLine("Unable to solve with Cholessky" + ++_bad); } if (slopes.Any(s => double.IsNaN(s))) { for (int i = 0; i < slopes.Length; i++) { if (double.IsInfinity(slopes[i]) || double.IsNaN(slopes[i])) { slopes[i] = 0.0; } } } return(slopes.ToList()); }
public static List <double> CalculateLeastSquares(double[][] x, double[] y) { double[] slopes = null; try { slopes = MultipleRegression.QR(x, y, false); if (slopes.Any(s => double.IsNaN(s))) { for (int i = 0; i < slopes.Length; i++) { if (double.IsInfinity(slopes[i]) || double.IsNaN(slopes[i])) { slopes[i] = 0.0; } } } return(slopes.ToList()); } catch { Console.WriteLine(DoubleToR(x)); Console.WriteLine(DoubleToR(y)); Console.WriteLine(slopes); return(null); } }
public mlr() { _proj = VBProjectManager.GetProjectManager(); DataTable dt = _proj.CorrelationDataTable; MultipleRegression model = computeModel(dt); _obs = model.ObservedValues; _pred = model.PredictedValues; }
public LinearRegressionEstimator Fit(Matrix <double> x, Vector <double> y) { if (Intercept) { x = x.InsertColumn(0, Vector <double> .Build.Dense(x.RowCount, Vector <double> .One)); } var w = MultipleRegression.NormalEquations(x, y); // TODO: what if matrix is sparse? other methods? return(new LinearRegressionEstimator(this, w)); }
public double[] LinearRegression(List <double[]> xLists, double[] yList) { var y = DenseVector.OfEnumerable(yList); var x = Matrix <double> .Build.Dense(xLists[0].Length, 1, (i, j) => 1.0); for (var i = 1; i < xLists.Count + 1; i++) { x = x.Append(DenseMatrix.OfColumnArrays(xLists[i - 1])); } return(MultipleRegression.NormalEquations(x, y).ToArray()); }
/// <summary> /// create a scatter plot of dependent variable and selected variable /// </summary> /// <param name="response">response variable values</param> /// <param name="iv">selected independent variable valuess</param> /// <param name="tags">tags for points - should be date/timestamp</param> /// <returns></returns> private GraphPane addPlotXY(double[] response, double[] iv, string[] tags) { PointPairList ppl = new PointPairList(); string tag = string.Empty; //might be a smarter way to add tags to points but I can't find it. for (int i = 0; i < response.Length; i++) { //tag = "(" + iv[i].ToString("n2") + " , " + response[i].ToString("n2") + ") " + tags[i]; tag = tags[i]; ppl.Add(iv[i], response[i], tag); } GraphPane gp = new GraphPane(); if (_dt.Rows.Count > 6) { //mc wants a regression line and some new stats on the plot double pcoeff = Statistics.Correlation(response, iv); double pval = Statistics.Pvalue4Correlation(pcoeff, _dt.Rows.Count); string[] ivname = new string[] { _dt.Columns[_selectedcol].Caption }; VBStatistics.MultipleRegression mlr = new MultipleRegression(_dt, _dt.Columns[_responsevarcol].Caption, ivname); mlr.Compute(); //andersondarling stats for the regression _regressionadstat = mlr.ADResidNormStatVal; _regressionadpval = mlr.ADResidPvalue; PointPairList ppl2 = new PointPairList(iv, mlr.PredictedValues); string fmtstring = formatNumberString(pval); fmtstring = "r = {0:f4}, P-Value = " + fmtstring; string annot = string.Format(fmtstring, pcoeff, pval); //string annot = string.Format("r = {0:f4}, p-value = {1:e4}", pcoeff, pval); LineItem curve2 = gp.AddCurve(annot, ppl2, Color.Red); curve2.Symbol.IsVisible = false; curve2.Line.IsVisible = true; } //end new stuff //GraphPane gp = new GraphPane(); LineItem curve = gp.AddCurve(_dt.Columns[_selectedcol].ColumnName, ppl, Color.Black); curve.Line.IsVisible = false; gp.XAxis.Title.Text = _dt.Columns[_selectedcol].ColumnName; gp.YAxis.Title.Text = _dt.Columns[_responsevarcol].ColumnName; gp.Tag = "XYPlot"; gp.Title.Text = "Scatter Plot"; return(gp); }
private MultipleRegression computeModel(DataTable dt) { //given a datatable, build a model MultipleRegression model = null; string[] idvars = _proj.ModelIndependentVariables.ToArray(); string dvar = _proj.ModelDependentVariable; if (dt != null) { model = new MultipleRegression(dt, dvar, idvars); model.Compute(); } return model; }
//constructor for manual processing (plotting) public Polynomial(double[] y, double[] x, string colname) { createResultsTable(); _colname = colname; _modelDT = createModelTable(y, x); MultipleRegression model = new MultipleRegression(_modelDT, "Y", new[] { "X", "X**2" }); model.Compute(); DataTable result = model.Parameters; computePoly(result); _adjrsqrd = model.AdjustedR2; _rsqrd = model.R2; savePolyInfo(); }
static double[] multi_linear_regression(double[] x1, double[] x2, double[] y) { double[][] matrix = new double[x1.Length][]; for (int i = 0; i < x1.Length; i++) { matrix[i] = new[] { x1[i], x2[i] }; } double[] p = new double[3]; for (int i = 0; i < 1; i++) { p = MultipleRegression.QR(matrix, y, intercept: true); } return(p); }
//public DataTable _polyDT = null; //constructor for procedural processing in datasheet public Polynomial(DataTable dt, int colndx) { //_polyDT = new DataTable(); createResultsTable(); _colname = dt.Columns[colndx].ColumnName; _modelDT = createModelTable(dt, colndx); MultipleRegression model = new MultipleRegression(_modelDT, "Y", new [] { "X", "X**2"} ); model.Compute(); DataTable result = model.Parameters; computePoly(result); _adjrsqrd = model.AdjustedR2; _rsqrd = model.R2; savePolyInfo(); }
private MultipleRegression computeModel(DataTable dt) { //given a datatable, build a model MultipleRegression model = null; string[] idvars = _proj.ModelIndependentVariables.ToArray(); string dvar = _proj.ModelDependentVariable; if (dt != null) { model = new MultipleRegression(dt, dvar, idvars); model.Compute(); } return(model); }
public UnBiasedEst(double[] obs, double[] est) { _obs = obs; _est = est; _data = getTable(); MultipleRegression model = new MultipleRegression(_data, "EST", new[] { "OBS" }); model.Compute(); _intercept = (double)model.Parameters.Rows[0][1]; _slope = (double)model.Parameters.Rows[1][1]; _unbiasedEst = new double[_obs.Length]; for (int i = 0; i < _obs.Length; i++) { _unbiasedEst[i] = (est[i] - _intercept) / _slope; } }
//constructor for manual processing (plotting) public Polynomial(double[] y, double[] x, string colname) { createResultsTable(); _colname = colname; _modelDT = createModelTable(y, x); MultipleRegression model = new MultipleRegression(_modelDT, "Y", new[] { "X", "X**2" }); model.Compute(); DataTable result = model.Parameters; computePoly(result); _adjrsqrd = model.AdjustedR2; _rsqrd = model.R2; savePolyInfo(); }
public UnBiasedEst(double[] obs, double[] est) { _obs = obs; _est = est; _data = getTable(); MultipleRegression model = new MultipleRegression(_data, "EST", new[] { "OBS" }); model.Compute(); _intercept = (double)model.Parameters.Rows[0][1]; _slope = (double)model.Parameters.Rows[1][1]; _unbiasedEst = new double[_obs.Length]; for (int i = 0; i < _obs.Length; i++) { _unbiasedEst[i] = (est[i] - _intercept) / _slope; } }
/// <summary> /// Логистическая регрессия /// </summary> /// <param name="x">Вектора входов</param> /// <param name="y">Принадлежность</param> public LogisticRegression(Vector[] x, bool[] y) { t = new Vector(y.Length); Vector[] vecs = new Vector[x.Length]; for (int i = 0; i < t.N; i++) { t[i] = y[i] ? 8 : -8; vecs[i] = x[i].AddOne(); } t *= 3000; _lr = new MultipleRegression(vecs, t); }
public static double[] ComputeRegressionNumerics(LasFile file, LasPoint point, int count, int radiusSector) { var neighbours = file.LasPointDataRecords.GetNeighbours(point, count, radiusSector); double[][] xy = new double[neighbours.Count][]; double[] z = new double[neighbours.Count]; for (int i = 0; i < neighbours.Count; i++) { xy[i] = new double[] { neighbours[i].X, neighbours[i].Y }; z[i] = neighbours[i].Z; } double[] p = MultipleRegression.QR(xy, z); return(p); }
//public DataTable _polyDT = null; //constructor for procedural processing in datasheet public Polynomial(DataTable dt, int colndx) { //_polyDT = new DataTable(); createResultsTable(); _colname = dt.Columns[colndx].ColumnName; _modelDT = createModelTable(dt, colndx); MultipleRegression model = new MultipleRegression(_modelDT, "Y", new [] { "X", "X**2" }); model.Compute(); DataTable result = model.Parameters; computePoly(result); _adjrsqrd = model.AdjustedR2; _rsqrd = model.R2; savePolyInfo(); }
private static double[] FitPoly(double[] x, double[] fx, int order) { int Ncoefficients = order + 1; Matrix <double> A = Matrix <double> .Build.Dense(x.Length, Ncoefficients); for (int i = 0; i < x.Length; i++) { A[i, 0] = 1; for (int j = 1; j < Ncoefficients; j++) { A[i, j] = A[i, j - 1] * x[i]; } } return(MultipleRegression.DirectMethod <double>(A, Vector <double> .Build.Dense(fx), DirectRegressionMethod.QR).AsArray()); //return MultipleRegression.DirectMethod<double>(A.ToRowArrays(), fx, true, DirectRegressionMethod.QR); //return Fit.Polynomial(x, fx, order); }
public IDecisionTreeLeaf BuildLeaf(IDataFrame finalData, string dependentFeatureName) { var vectorY = finalData.GetNumericColumnVector(dependentFeatureName); var featureNames = finalData.ColumnNames.Except(new[] { dependentFeatureName }).ToList(); var subset = finalData.GetSubsetByColumns(featureNames); var matrixX = finalData.GetSubsetByColumns(featureNames).GetAsMatrixWithIntercept(); Vector <double> fittedWeights = null; try { fittedWeights = MultipleRegression.DirectMethod(matrixX, vectorY); } catch (Exception) { fittedWeights = regressionModelBuilder.BuildModel(matrixX, vectorY, regressionParams).Weights; } return(new RegressionAndModelLeaf(dependentFeatureName, fittedWeights, vectorY.Mean())); }
/// <summary> /// Polynomial curve fitting /// </summary> /// <param name="x">x values</param> /// <param name="y">y values</param> /// <param name="degree">fit degree</param> /// <returns>Polynom with coefficients for a polynomial p(x) of degree n that is a best fit for the data in y. /// The coefficients in p are in acscending powers (offset first), and the length of p is n+1</returns> public static Polynom Polyfit(double[] x, double[] y, int degree) { if (x.Length != y.Length) { throw new ArgumentOutOfRangeException("Polyfit nicht möglich, da der X- und Y-Vektor verschiedene Längen haben!"); } if (degree > x.Length) { throw new ArgumentOutOfRangeException("Polyfit nicht möglich, da der angegeben Fit-Grad mit der Länge der Eingangsdaten nicht erreicht werden kann!"); } var design = Matrix <double> .Build.Dense(x.Length, degree + 1, (i, j) => Math.Pow(x[i], j)); return(new Polynom() { Coefficients = MultipleRegression.QR(design, Vector <double> .Build.Dense(y)).ToArray() }); }
/// <summary> /// Логистическая регрессия /// </summary> /// <param name="x"></param> /// <param name="y"></param> public LogisticRegression(Vector x, bool[] y) { t = new Vector(y.Length); Vector[] vecs = new Vector[x.N]; for (int i = 0; i < t.N; i++) { t[i] = y[i] ? 4.6 : -4.6; vecs[i] = new Vector ( new double[] { 1, x[i] } ); } t *= 30; _lr = new MultipleRegression(vecs, t); }
public Task <MultipleRegression> GetMultipleRegressionAsync(string ys, string xs1, string xs2, string xs3, double a) { if (string.IsNullOrEmpty(xs1) || string.IsNullOrEmpty(xs2) || string.IsNullOrEmpty(xs3) || string.IsNullOrEmpty(ys)) { return(Task.FromException <MultipleRegression>(new ArgumentNullException())); } if (a <= 0) { return(Task.FromException <MultipleRegression>(new ArithmeticException())); } var x1 = Utils.StringToNumber(xs1); var x2 = Utils.StringToNumber(xs2); var x3 = Utils.StringToNumber(xs3); var y = Utils.StringToNumber(ys); var s = new MultipleRegression(y, x1, x2, x3, alf: a); return(Task.FromResult(s)); }
/// <summary> /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to a linear surface y : X -> p0*x0 + p1*x1 + ... + pk*xk, /// returning a function y' for the best fitting combination. /// </summary> public static Func <double[], double> MultiDimFunc(double[][] x, double[] y) { var parameters = MultipleRegression.NormalEquations(x, y); return(z => Control.LinearAlgebraProvider.DotProduct(parameters, z)); }
/// <summary> /// Least-Squares fitting the points (T,y) = (T,y) to an arbitrary linear combination y : X -> p0*f0(T) + p1*f1(T) + ... + pk*fk(T), /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. /// </summary> public static double[] LinearGeneric <T>(T[] x, double[] y, DirectRegressionMethod method, params Func <T, double>[] functions) { var design = Matrix <double> .Build.Dense(x.Length, functions.Length, (i, j) => functions[j](x[i])); return(MultipleRegression.DirectMethod(design, Vector <double> .Build.Dense(y), method).ToArray()); }
/// <summary> /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to an arbitrary linear combination y : X -> p0*f0(x) + p1*f1(x) + ... + pk*fk(x), /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. /// </summary> public static double[] LinearMultiDim(double[][] x, double[] y, params Func <double[], double>[] functions) { var design = Matrix <double> .Build.Dense(x.Length, functions.Length, (i, j) => functions[j](x[i])); return(MultipleRegression.QR(design, Vector <double> .Build.Dense(y)).ToArray()); }
/// <summary> /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to a linear surface y : X -> p0*x0 + p1*x1 + ... + pk*xk, /// returning a function y' for the best fitting combination. /// If an intercept is added, its coefficient will be prepended to the resulting parameters. /// </summary> public static Func <double[], double> MultiDimFunc(double[][] x, double[] y, bool intercept = false, DirectRegressionMethod method = DirectRegressionMethod.NormalEquations) { var parameters = MultipleRegression.DirectMethod(x, y, intercept, method); return(z => LinearAlgebraControl.Provider.DotProduct(parameters, z)); }
/// <summary> /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to a linear surface y : X -> p0*x0 + p1*x1 + ... + pk*xk, /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. /// If an intercept is added, its coefficient will be prepended to the resulting parameters. /// </summary> public static double[] MultiDim(double[][] x, double[] y, bool intercept = false, DirectRegressionMethod method = DirectRegressionMethod.NormalEquations) { return(MultipleRegression.DirectMethod(x, y, intercept, method)); }
/// <summary> /// Least-Squares fitting the points (x,y) to a k-order polynomial y : x -> p0 + p1*x + p2*x^2 + ... + pk*x^k, /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array, compatible with Evaluate.Polynomial. /// A polynomial with order/degree k has (k+1) coefficients and thus requires at least (k+1) samples. /// </summary> public static double[] Polynomial(double[] x, double[] y, int order, DirectRegressionMethod method = DirectRegressionMethod.QR) { var design = Matrix <double> .Build.Dense(x.Length, order + 1, (i, j) => Math.Pow(x[i], j)); return(MultipleRegression.DirectMethod(design, Vector <double> .Build.Dense(y), method).ToArray()); }
/// <summary> /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to a linear surface y : X -> p0*x0 + p1*x1 + ... + pk*xk, /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. /// </summary> public static double[] MultiDim(double[][] x, double[] y) { return(MultipleRegression.NormalEquations(x, y)); }
/// <summary> /// Least-Squares fitting the points (x,y) to a k-order polynomial y : x -> p0 + p1*x + p2*x^2 + ... + pk*x^k, /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array, compatible with Evaluate.Polynomial. /// </summary> public static double[] Polynomial(double[] x, double[] y, int order) { var design = Matrix <double> .Build.Dense(x.Length, order + 1, (i, j) => Math.Pow(x[i], j)); return(MultipleRegression.QR(design, Vector <double> .Build.Dense(y)).ToArray()); }
//this is asych for the calling Task.WhenAll //but does not necessarily need internal asych awaits public async Task RunAlgorithmAsync(List <List <double> > data) { try { //minimal data requirement is first five cols if (_colNames.Count() < 5 || _mathTerms.Count() == 0) { ErrorMessage = "Regression requires at least one dependent variable and one independent variable."; return; } if (data.Count() < 5) { //185 same as other analysis ErrorMessage = "Regression requires at least 2 rows of observed data and 3 rows of scoring data."; return; } //convert data to a Math.Net Matrix //v185 uses same ci technique as algos 2,3 and 4 -last 3 rows are used to generate ci List <List <double> > dataci = data.Skip(data.Count - _scoreRows).ToList(); data.Reverse(); List <List <double> > dataobs = data.Skip(_scoreRows).ToList(); dataobs.Reverse(); //actual observed values Vector <double> y = Shared.GetYData(dataobs); Matrix <double> x = Shared.GetDoubleMatrix(dataobs, _colNames, _depColNames); Matrix <double> ci = Shared.GetDoubleMatrix(dataci, _colNames, _depColNames); //model expected values - get the coefficents //use normal equations regression Vector <double> p = MultipleRegression.NormalEquations(x, y); //but note that this runs without errors in more cases but still does not give good results //Vector<double> p = MultipleRegression.QR(x, y); if (p.Count() != ci.Row(_scoreRows - 1).Count()) { //185 same as other analysis ErrorMessage = "The scoring and training datasets have different numbers of columns."; return; } //get the predicted yhats Vector <double> yhat = GetYHatandSetQTPred(y.Count, x, p, ci.Row(_scoreRows - 1).ToArray()); //get the durbin-watson d statistic double d = GetDurbinWatson(y, yhat); double SSE = 0; //sum of the square of the error (between the predicted, p, and observed, y); SSE = Distance.SSD(yhat, y); double rSquared = GoodnessOfFit.RSquared(yhat, y); //sum of the square of the regression (between the predicted, p, and observed mean, statsY.Mean); double SSR = 0; for (int i = 0; i < yhat.Count(); i++) { SSR += Math.Pow((yhat[i] - y.Mean()), 2); } //set joint vars properties //degrees freedom double dfR = x.ColumnCount - 1; double dfE = x.RowCount - x.ColumnCount; int idfR = x.ColumnCount - 1; int idfE = x.RowCount - x.ColumnCount; double s2 = SSE / dfE; double s = Math.Sqrt(s2); double MSR = SSR / dfR; double MSE = SSE / dfE; double FValue = MSR / MSE; double adjRSquared = 1 - ((x.RowCount - 1) * (MSE / (SSE + SSR))); double pValue = Shared.GetPValueForFDist(idfR, idfE, FValue); //correct 2 tailed t test //double TCritialValue = ExcelFunctions.TInv(0.05, idfE); //so do this double dbCI = CalculatorHelpers.GetConfidenceIntervalProb(_confidenceInt); double tCriticalValue = ExcelFunctions.TInv(dbCI, idfE); //set each coeff properties //coeffs st error //use matrix math to get the standard error of coefficients Matrix <double> xt = x.Transpose(); //matrix x'x Matrix <double> xx = xt.Multiply(x); Matrix <double> xxminus1 = xx.Inverse(); double sxx = 0; double[] xiSE = new double[x.ColumnCount]; //coeff tstats double[] xiT = new double[x.ColumnCount]; //lower value for pvalue double[] xiP = new double[x.ColumnCount]; for (int i = 0; i < x.ColumnCount; i++) { //use the matrix techniques shown on p 717 of Mendenhall and Sincich sxx = s * Math.Sqrt(xxminus1.Column(i)[i]); xiSE[i] = sxx; xiT[i] = p[i] / sxx; xiP[i] = Shared.GetPValueForTDist(idfE, xiT[i], 0, 1); } double FCriticalValue = 0; string FGreaterFCritical = string.Empty; if (_subalgorithm == Calculator1.MATH_SUBTYPES.subalgorithm8.ToString()) { //anova regression //anova critical fvalue test //FCriticalValue = ExcelFunctions.FInv(1 - _confidenceInt, idfR, idfE); FCriticalValue = ExcelFunctions.FInv(dbCI, idfR, idfE); FGreaterFCritical = (FValue > FCriticalValue) ? "true" : "false"; SetAnovaIntervals(0, p, xiSE, tCriticalValue); SetAnovaIntervals(1, p, xiSE, tCriticalValue); SetAnovaIntervals(2, p, xiSE, tCriticalValue); } else { //set QTM ci and pi intervals SetQTIntervals(0, s, xxminus1, ci.Row(_scoreRows - 1).ToArray(), p, tCriticalValue); SetQTIntervals(1, s, xxminus1, ci.Row(_scoreRows - 2).ToArray(), p, tCriticalValue); SetQTIntervals(2, s, xxminus1, ci.Row(_scoreRows - 3).ToArray(), p, tCriticalValue); } //add the data to a string builder StringBuilder sb = new StringBuilder(); sb.AppendLine("regression results"); //dep var has to be in the 4 column always string sLine = string.Concat("dependent variable: ", _colNames[3]); sb.AppendLine(sLine); string[] cols = new string[] { "source", "df", "SS", "MS" }; sb.AppendLine(Shared.GetLine(cols, true)); cols = new string[] { "model", dfR.ToString("F0"), SSR.ToString("F4"), MSR.ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); cols = new string[] { "error ", dfE.ToString("F0"), SSE.ToString("F4"), MSE.ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); cols = new string[] { "total ", (dfR + dfE).ToString("F0"), (SSR + SSE).ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); sb.AppendLine(string.Empty); cols = new string[] { "R-squared", rSquared.ToString("F4"), "Adj R-squared", adjRSquared.ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); cols = new string[] { "F value", FValue.ToString("F4"), "prob > F", pValue.ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); sb.AppendLine(string.Empty); cols = new string[] { GetName("variable"), "coefficient", "stand error", "T-ratio", "prob > T" }; sb.AppendLine(Shared.GetLine(cols, true)); for (int i = 0; i < p.Count(); i++) { if (i == 0) { cols = new string[] { GetName(_depColNames[i]), p[i].ToString("F5"), xiSE[i].ToString("F4"), xiT[i].ToString("F4"), xiP[i].ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); } else { cols = new string[] { GetName(_depColNames[i]), p[i].ToString("F5"), xiSE[i].ToString("F4"), xiT[i].ToString("F4"), xiP[i].ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); } } cols = new string[] { "durbin-watson: ", d.ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); if (_subalgorithm == Calculator1.MATH_SUBTYPES.subalgorithm8.ToString()) { cols = new string[] { "F Critical Value", FCriticalValue.ToString("F5"), "F > F Critical", FGreaterFCritical }; sb.AppendLine(Shared.GetLine(cols, true)); cols = new string[] { "estimate", "predicted", string.Concat("lower ", _confidenceInt.ToString(), "%"), string.Concat("upper ", _confidenceInt.ToString(), "%") }; sb.AppendLine(Shared.GetLine(cols, true)); cols = new string[] { "Col 0 Mean CI ", QTPredicted.ToString("F4"), QTL.ToString("F4"), QTU.ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); cols = new string[] { "Col 1 - 0 Mean CI ", QTPredicted10.ToString("F4"), QTL10.ToString("F4"), QTU10.ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); cols = new string[] { "Col 2 - 0 Mean CI ", QTPredicted20.ToString("F4"), QTL20.ToString("F4"), QTU20.ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); } else { cols = new string[] { "estimate", "predicted", string.Concat("lower ", _confidenceInt.ToString(), "%"), string.Concat("upper ", _confidenceInt.ToString(), "%") }; sb.AppendLine(Shared.GetLine(cols, true)); cols = new string[] { "QTM CI ", QTPredicted.ToString("F4"), QTL.ToString("F4"), QTU.ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); cols = new string[] { "QTM PI ", QTPredicted.ToString("F4"), (QTPredicted - QTPI).ToString("F4"), (QTPredicted + QTPI).ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); string sRow = string.Concat("row ", data.Count - 2); cols = new string[] { sRow }; sb.AppendLine(Shared.GetLine(cols, true)); cols = new string[] { "CI ", QTPredicted10.ToString("F4"), QTL10.ToString("F4"), QTU10.ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); cols = new string[] { "PI ", QTPredicted10.ToString("F4"), (QTPredicted10 - QTPI10).ToString("F4"), (QTPredicted10 + QTPI10).ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); sRow = string.Concat("row ", data.Count - 1); cols = new string[] { sRow }; sb.AppendLine(Shared.GetLine(cols, true)); cols = new string[] { "CI ", QTPredicted20.ToString("F4"), QTL20.ToString("F4"), QTU20.ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); cols = new string[] { "PI ", QTPredicted20.ToString("F4"), (QTPredicted20 - QTPI20).ToString("F4"), (QTPredicted20 + QTPI20).ToString("F4") }; sb.AppendLine(Shared.GetLine(cols, false)); } if (this.MathResult.ToLower().StartsWith("http")) { string sError = string.Empty; bool bHasSaved = CalculatorHelpers.SaveTextInURI( _params.ExtensionDocToCalcURI, sb.ToString(), this.MathResult, out sError); if (!string.IsNullOrEmpty(sError)) { this.MathResult += sError; } } else { this.MathResult = sb.ToString(); } } catch (Exception ex) { this.ErrorMessage = ex.Message; } }
/// <summary> /// Performs linear regression that is evaluated on every x-th pixel /// </summary> public void LinearRegression() { int step = PlaneLocalizationConfig.RegressionIsEvaluatedOnEveryNthTablePixel; // count how many evaluated pixels are valid int numberOfEvaluatedTablePixels = 0; for (int i = 0; i < DepthData.Length; i += step) { if (DepthData[i].Type == PixelType.Table) { numberOfEvaluatedTablePixels++; } } if (numberOfEvaluatedTablePixels == 0) { return; } // allocate arrays for values for regression double[] lAx = new double[numberOfEvaluatedTablePixels]; double[] lAy = new double[numberOfEvaluatedTablePixels]; double[] lAvalue = new double[numberOfEvaluatedTablePixels]; double[] ones = new double[numberOfEvaluatedTablePixels]; // temporary - hold position in upper arrays int counter = 0; // fill data to the arrays for (int i = 0; i < numberOfEvaluatedTablePixels; i++) { ones[i] = 1; } for (int i = 0; i < DepthData.Length; i += step) { if (DepthData[i].Type == PixelType.Table) { lAx[counter] = DepthData[i].X; lAy[counter] = DepthData[i].Y; lAvalue[counter] = DepthData[i].Z; counter++; } } // library regression solver var X = DenseMatrix.OfColumnArrays(ones, lAx, lAy); var YY = new DenseVector(lAvalue); double[][] abc = new double[3][]; abc[0] = ones; abc[1] = lAx; abc[2] = lAy; var p = MultipleRegression.QR((MathNet.Numerics.LinearAlgebra.Matrix <double>)X, YY); // regression coeficients double a = p[0]; double bx = p[1]; double by = p[2]; // convert them to analytical plane equation (ax + by + cz + d) where (a,b,c) is normal // pick 3 points, count expected value, get 2 vectors from em and count normal to plane float x1 = 0; float y1 = 0; float z1 = (float)(a + (bx * x1) + (by * y1)); float x2 = 1000; float y2 = 0; float z2 = (float)(a + (bx * x2) + (by * y2)); float x3 = 0; float y3 = 1000; float z3 = (float)(a + (bx * x3) + (by * y3)); var normal = MyVector3D.CrossProduct( new MyVector3D(x1 - x2, y1 - y2, z1 - z2), new MyVector3D(x1 - x3, y1 - y3, z1 - z3) ); double d = -(normal.x * x1 + normal.y * y1 + normal.z * z1); // erase potentional table markers for (int i = 0; i < DepthData.Length; i++) { if (DepthData[i].Type == PixelType.Table) { DepthData[i].Type = PixelType.NotMarked; } } // Mark pixels as table, based on distance from computed plane for (int y = 0; y < PlaneLocalizationConfig.DepthImageHeight; y++) { for (int x = 0; x < PlaneLocalizationConfig.DepthImageWidth; x++) { if (DepthData[x + y * PlaneLocalizationConfig.DepthImageWidth].Type == PixelType.Invalid) { continue; } float pointX = DepthData[x + y * PlaneLocalizationConfig.DepthImageWidth].X; float pointY = DepthData[x + y * PlaneLocalizationConfig.DepthImageWidth].Y; float pointZ = DepthData[x + y * PlaneLocalizationConfig.DepthImageWidth].Z; float distance = (float)(Math.Abs(normal.x * pointX + normal.y * pointY + normal.z * pointZ + d) / Math.Sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z)); if (distance < PlaneLocalizationConfig.RegreseTloustka) { DepthData[PosFromCoor(x, y)].Type = PixelType.Table; } } } }