/// <summary> /// Makes a PCA (a principal component analysis) of the table or the selected columns / rows and stores the results in a newly created table. /// </summary> /// <param name="mainDocument">The main document of the application.</param> /// <param name="srctable">The table where the data come from.</param> /// <param name="selectedColumns">The selected columns.</param> /// <param name="selectedRows">The selected rows.</param> /// <param name="bHorizontalOrientedSpectrum">True if a spectrum is a single row, False if a spectrum is a single column.</param> /// <param name="maxNumberOfFactors">The maximum number of factors to calculate.</param> /// <returns></returns> public static string PrincipalComponentAnalysis( Altaxo.AltaxoDocument mainDocument, Altaxo.Data.DataTable srctable, IAscendingIntegerCollection selectedColumns, IAscendingIntegerCollection selectedRows, bool bHorizontalOrientedSpectrum, int maxNumberOfFactors ) { bool bUseSelectedColumns = (null != selectedColumns && 0 != selectedColumns.Count); int prenumcols = bUseSelectedColumns ? selectedColumns.Count : srctable.DataColumns.ColumnCount; // check for the number of numeric columns int numcols = 0; for (int i = 0; i < prenumcols; i++) { int idx = bUseSelectedColumns ? selectedColumns[i] : i; if (srctable[i] is Altaxo.Data.INumericColumn) { numcols++; } } // check the number of rows bool bUseSelectedRows = (null != selectedRows && 0 != selectedRows.Count); int numrows; if (bUseSelectedRows) { numrows = selectedRows.Count; } else { numrows = 0; for (int i = 0; i < numcols; i++) { int idx = bUseSelectedColumns ? selectedColumns[i] : i; numrows = Math.Max(numrows, srctable[idx].Count); } } // check that both dimensions are at least 2 - otherwise PCA is not possible if (numrows < 2) { return("At least two rows are neccessary to do Principal Component Analysis!"); } if (numcols < 2) { return("At least two numeric columns are neccessary to do Principal Component Analysis!"); } // Create a matrix of appropriate dimensions and fill it MatrixMath.BEMatrix matrixX; if (bHorizontalOrientedSpectrum) { matrixX = new MatrixMath.BEMatrix(numrows, numcols); int ccol = 0; // current column in the matrix for (int i = 0; i < prenumcols; i++) { int colidx = bUseSelectedColumns ? selectedColumns[i] : i; Altaxo.Data.INumericColumn col = srctable[colidx] as Altaxo.Data.INumericColumn; if (null != col) { for (int j = 0; j < numrows; j++) { int rowidx = bUseSelectedRows ? selectedRows[j] : j; matrixX[j, ccol] = col[rowidx]; } ++ccol; } } } // end if it was a horizontal oriented spectrum else // if it is a vertical oriented spectrum { matrixX = new MatrixMath.BEMatrix(numcols, numrows); int ccol = 0; // current column in the matrix for (int i = 0; i < prenumcols; i++) { int colidx = bUseSelectedColumns ? selectedColumns[i] : i; Altaxo.Data.INumericColumn col = srctable[colidx] as Altaxo.Data.INumericColumn; if (null != col) { for (int j = 0; j < numrows; j++) { int rowidx = bUseSelectedRows ? selectedRows[j] : j; matrixX[ccol, j] = col[rowidx]; } ++ccol; } } } // if it was a vertical oriented spectrum // now do PCA with the matrix MatrixMath.REMatrix factors = new MatrixMath.REMatrix(0, 0); MatrixMath.BEMatrix loads = new MatrixMath.BEMatrix(0, 0); MatrixMath.BEMatrix residualVariances = new MatrixMath.BEMatrix(0, 0); MatrixMath.HorizontalVector meanX = new MatrixMath.HorizontalVector(matrixX.Columns); // first, center the matrix MatrixMath.ColumnsToZeroMean(matrixX, meanX); MatrixMath.NIPALS_HO(matrixX, maxNumberOfFactors, 1E-9, factors, loads, residualVariances); // now we have to create a new table where to place the calculated factors and loads // we will do that in a vertical oriented manner, i.e. even if the loads are // here in horizontal vectors: in our table they are stored in (vertical) columns Altaxo.Data.DataTable table = new Altaxo.Data.DataTable("PCA of " + srctable.Name); // Fill the Table table.Suspend(); // first of all store the meanscore { double meanScore = MatrixMath.LengthOf(meanX); MatrixMath.NormalizeRows(meanX); Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < factors.Rows; i++) { col[i] = meanScore; } table.DataColumns.Add(col, "MeanFactor", Altaxo.Data.ColumnKind.V, 0); } // first store the factors for (int i = 0; i < factors.Columns; i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < factors.Rows; j++) { col[j] = factors[j, i]; } table.DataColumns.Add(col, "Factor" + i.ToString(), Altaxo.Data.ColumnKind.V, 1); } // now store the mean of the matrix { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < meanX.Columns; j++) { col[j] = meanX[0, j]; } table.DataColumns.Add(col, "MeanLoad", Altaxo.Data.ColumnKind.V, 2); } // now store the loads - careful - they are horizontal in the matrix for (int i = 0; i < loads.Rows; i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < loads.Columns; j++) { col[j] = loads[i, j]; } table.DataColumns.Add(col, "Load" + i.ToString(), Altaxo.Data.ColumnKind.V, 3); } // now store the residual variances, they are vertical in the vector { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < residualVariances.Rows; i++) { col[i] = residualVariances[i, 0]; } table.DataColumns.Add(col, "ResidualVariance", Altaxo.Data.ColumnKind.V, 4); } table.Resume(); mainDocument.DataTableCollection.Add(table); // create a new worksheet without any columns Current.ProjectService.CreateNewWorksheet(table); return(null); }
/// <summary> /// Multiplies selected columns to form a matrix. /// </summary> /// <param name="mainDocument"></param> /// <param name="srctable"></param> /// <param name="selectedColumns"></param> /// <returns>Null if successful, else the description of the error.</returns> /// <remarks>The user must select an even number of columns. All columns of the first half of the selection /// must have the same number of rows, and all columns of the second half of selection must also have the same /// number of rows. The first half of selected columns form a matrix of dimensions(firstrowcount,halfselected), and the second half /// of selected columns form a matrix of dimension(halfselected, secondrowcount). The resulting matrix has dimensions (firstrowcount,secondrowcount) and is /// stored in a separate worksheet.</remarks> public static string MultiplyColumnsToMatrix( Altaxo.AltaxoDocument mainDocument, Altaxo.Data.DataTable srctable, IAscendingIntegerCollection selectedColumns ) { // check that there are columns selected if (0 == selectedColumns.Count) { return("You must select at least two columns to multiply!"); } // selected columns must contain an even number of columns if (0 != selectedColumns.Count % 2) { return("You selected an odd number of columns. Please select an even number of columns to multiply!"); } // all selected columns must be numeric columns for (int i = 0; i < selectedColumns.Count; i++) { if (!(srctable[selectedColumns[i]] is Altaxo.Data.INumericColumn)) { return(string.Format("The column[{0}] (name:{1}) is not a numeric column!", selectedColumns[i], srctable[selectedColumns[i]].Name)); } } int halfselect = selectedColumns.Count / 2; // check that all columns from the first half of selected colums contain the same // number of rows int rowsfirsthalf = int.MinValue; for (int i = 0; i < halfselect; i++) { int idx = selectedColumns[i]; if (rowsfirsthalf < 0) { rowsfirsthalf = srctable[idx].Count; } else if (rowsfirsthalf != srctable[idx].Count) { return("The first half of selected columns have not all the same length!"); } } int rowssecondhalf = int.MinValue; for (int i = halfselect; i < selectedColumns.Count; i++) { int idx = selectedColumns[i]; if (rowssecondhalf < 0) { rowssecondhalf = srctable[idx].Count; } else if (rowssecondhalf != srctable[idx].Count) { return("The second half of selected columns have not all the same length!"); } } // now create the matrices to multiply from the MatrixMath.REMatrix firstMat = new MatrixMath.REMatrix(rowsfirsthalf, halfselect); for (int i = 0; i < halfselect; i++) { Altaxo.Data.INumericColumn col = (Altaxo.Data.INumericColumn)srctable[selectedColumns[i]]; for (int j = 0; j < rowsfirsthalf; j++) { firstMat[j, i] = col[j]; } } MatrixMath.BEMatrix secondMat = new MatrixMath.BEMatrix(halfselect, rowssecondhalf); for (int i = 0; i < halfselect; i++) { Altaxo.Data.INumericColumn col = (Altaxo.Data.INumericColumn)srctable[selectedColumns[i + halfselect]]; for (int j = 0; j < rowssecondhalf; j++) { secondMat[i, j] = col[j]; } } // now multiply the two matrices MatrixMath.BEMatrix resultMat = new MatrixMath.BEMatrix(rowsfirsthalf, rowssecondhalf); MatrixMath.Multiply(firstMat, secondMat, resultMat); // and store the result in a new worksheet Altaxo.Data.DataTable table = new Altaxo.Data.DataTable("ResultMatrix of " + srctable.Name); table.Suspend(); // first store the factors for (int i = 0; i < resultMat.Columns; i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < resultMat.Rows; j++) { col[j] = resultMat[j, i]; } table.DataColumns.Add(col, i.ToString()); } table.Resume(); mainDocument.DataTableCollection.Add(table); // create a new worksheet without any columns Current.ProjectService.CreateNewWorksheet(table); return(null); }
/// <summary> /// Multiplies selected columns to form a matrix. /// </summary> /// <param name="mainDocument"></param> /// <param name="srctable"></param> /// <param name="selectedColumns"></param> /// <returns>Null if successful, else the description of the error.</returns> /// <remarks>The user must select an even number of columns. All columns of the first half of the selection /// must have the same number of rows, and all columns of the second half of selection must also have the same /// number of rows. The first half of selected columns form a matrix of dimensions(firstrowcount,halfselected), and the second half /// of selected columns form a matrix of dimension(halfselected, secondrowcount). The resulting matrix has dimensions (firstrowcount,secondrowcount) and is /// stored in a separate worksheet.</remarks> public static string MultiplyColumnsToMatrix( Altaxo.AltaxoDocument mainDocument, Altaxo.Data.DataTable srctable, IAscendingIntegerCollection selectedColumns ) { // check that there are columns selected if(0==selectedColumns.Count) return "You must select at least two columns to multiply!"; // selected columns must contain an even number of columns if(0!=selectedColumns.Count%2) return "You selected an odd number of columns. Please select an even number of columns to multiply!"; // all selected columns must be numeric columns for(int i=0;i<selectedColumns.Count;i++) { if(!(srctable[selectedColumns[i]] is Altaxo.Data.INumericColumn)) return string.Format("The column[{0}] (name:{1}) is not a numeric column!",selectedColumns[i],srctable[selectedColumns[i]].Name); } int halfselect = selectedColumns.Count/2; // check that all columns from the first half of selected colums contain the same // number of rows int rowsfirsthalf=int.MinValue; for(int i=0;i<halfselect;i++) { int idx = selectedColumns[i]; if(rowsfirsthalf<0) rowsfirsthalf = srctable[idx].Count; else if(rowsfirsthalf != srctable[idx].Count) return "The first half of selected columns have not all the same length!"; } int rowssecondhalf=int.MinValue; for(int i=halfselect;i<selectedColumns.Count;i++) { int idx = selectedColumns[i]; if(rowssecondhalf<0) rowssecondhalf = srctable[idx].Count; else if(rowssecondhalf != srctable[idx].Count) return "The second half of selected columns have not all the same length!"; } // now create the matrices to multiply from the MatrixMath.REMatrix firstMat = new MatrixMath.REMatrix(rowsfirsthalf,halfselect); for(int i=0;i<halfselect;i++) { Altaxo.Data.INumericColumn col = (Altaxo.Data.INumericColumn)srctable[selectedColumns[i]]; for(int j=0;j<rowsfirsthalf;j++) firstMat[j,i] = col[j]; } MatrixMath.BEMatrix secondMat = new MatrixMath.BEMatrix(halfselect,rowssecondhalf); for(int i=0;i<halfselect;i++) { Altaxo.Data.INumericColumn col = (Altaxo.Data.INumericColumn)srctable[selectedColumns[i+halfselect]]; for(int j=0;j<rowssecondhalf;j++) secondMat[i,j] = col[j]; } // now multiply the two matrices MatrixMath.BEMatrix resultMat = new MatrixMath.BEMatrix(rowsfirsthalf,rowssecondhalf); MatrixMath.Multiply(firstMat,secondMat,resultMat); // and store the result in a new worksheet Altaxo.Data.DataTable table = new Altaxo.Data.DataTable("ResultMatrix of " + srctable.Name); table.Suspend(); // first store the factors for(int i=0;i<resultMat.Columns;i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<resultMat.Rows;j++) col[j] = resultMat[j,i]; table.DataColumns.Add(col,i.ToString()); } table.Resume(); mainDocument.DataTableCollection.Add(table); // create a new worksheet without any columns Current.ProjectService.CreateNewWorksheet(table); return null; }
/// <summary> /// Makes a PCA (a principal component analysis) of the table or the selected columns / rows and stores the results in a newly created table. /// </summary> /// <param name="mainDocument">The main document of the application.</param> /// <param name="srctable">The table where the data come from.</param> /// <param name="selectedColumns">The selected columns.</param> /// <param name="selectedRows">The selected rows.</param> /// <param name="bHorizontalOrientedSpectrum">True if a spectrum is a single row, False if a spectrum is a single column.</param> /// <param name="maxNumberOfFactors">The maximum number of factors to calculate.</param> /// <returns></returns> public static string PrincipalComponentAnalysis( Altaxo.AltaxoDocument mainDocument, Altaxo.Data.DataTable srctable, IAscendingIntegerCollection selectedColumns, IAscendingIntegerCollection selectedRows, bool bHorizontalOrientedSpectrum, int maxNumberOfFactors ) { bool bUseSelectedColumns = (null!=selectedColumns && 0!=selectedColumns.Count); int prenumcols = bUseSelectedColumns ? selectedColumns.Count : srctable.DataColumns.ColumnCount; // check for the number of numeric columns int numcols = 0; for(int i=0;i<prenumcols;i++) { int idx = bUseSelectedColumns ? selectedColumns[i] : i; if(srctable[i] is Altaxo.Data.INumericColumn) numcols++; } // check the number of rows bool bUseSelectedRows = (null!=selectedRows && 0!=selectedRows.Count); int numrows; if(bUseSelectedRows) numrows = selectedRows.Count; else { numrows = 0; for(int i=0;i<numcols;i++) { int idx = bUseSelectedColumns ? selectedColumns[i] : i; numrows = Math.Max(numrows,srctable[idx].Count); } } // check that both dimensions are at least 2 - otherwise PCA is not possible if(numrows<2) return "At least two rows are neccessary to do Principal Component Analysis!"; if(numcols<2) return "At least two numeric columns are neccessary to do Principal Component Analysis!"; // Create a matrix of appropriate dimensions and fill it MatrixMath.BEMatrix matrixX; if(bHorizontalOrientedSpectrum) { matrixX = new MatrixMath.BEMatrix(numrows,numcols); int ccol = 0; // current column in the matrix for(int i=0;i<prenumcols;i++) { int colidx = bUseSelectedColumns ? selectedColumns[i] : i; Altaxo.Data.INumericColumn col = srctable[colidx] as Altaxo.Data.INumericColumn; if(null!=col) { for(int j=0;j<numrows;j++) { int rowidx = bUseSelectedRows ? selectedRows[j] : j; matrixX[j,ccol] = col[rowidx]; } ++ccol; } } } // end if it was a horizontal oriented spectrum else // if it is a vertical oriented spectrum { matrixX = new MatrixMath.BEMatrix(numcols,numrows); int ccol = 0; // current column in the matrix for(int i=0;i<prenumcols;i++) { int colidx = bUseSelectedColumns ? selectedColumns[i] : i; Altaxo.Data.INumericColumn col = srctable[colidx] as Altaxo.Data.INumericColumn; if(null!=col) { for(int j=0;j<numrows;j++) { int rowidx = bUseSelectedRows ? selectedRows[j] : j; matrixX[ccol,j] = col[rowidx]; } ++ccol; } } } // if it was a vertical oriented spectrum // now do PCA with the matrix MatrixMath.REMatrix factors = new MatrixMath.REMatrix(0,0); MatrixMath.BEMatrix loads = new MatrixMath.BEMatrix(0,0); MatrixMath.BEMatrix residualVariances = new MatrixMath.BEMatrix(0,0); MatrixMath.HorizontalVector meanX = new MatrixMath.HorizontalVector(matrixX.Columns); // first, center the matrix MatrixMath.ColumnsToZeroMean(matrixX,meanX); MatrixMath.NIPALS_HO(matrixX,maxNumberOfFactors,1E-9,factors,loads,residualVariances); // now we have to create a new table where to place the calculated factors and loads // we will do that in a vertical oriented manner, i.e. even if the loads are // here in horizontal vectors: in our table they are stored in (vertical) columns Altaxo.Data.DataTable table = new Altaxo.Data.DataTable("PCA of " + srctable.Name); // Fill the Table table.Suspend(); // first of all store the meanscore { double meanScore = MatrixMath.LengthOf(meanX); MatrixMath.NormalizeRows(meanX); Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int i=0;i<factors.Rows;i++) col[i] = meanScore; table.DataColumns.Add(col,"MeanFactor",Altaxo.Data.ColumnKind.V,0); } // first store the factors for(int i=0;i<factors.Columns;i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<factors.Rows;j++) col[j] = factors[j,i]; table.DataColumns.Add(col,"Factor"+i.ToString(),Altaxo.Data.ColumnKind.V,1); } // now store the mean of the matrix { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<meanX.Columns;j++) col[j] = meanX[0,j]; table.DataColumns.Add(col,"MeanLoad",Altaxo.Data.ColumnKind.V,2); } // now store the loads - careful - they are horizontal in the matrix for(int i=0;i<loads.Rows;i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<loads.Columns;j++) col[j] = loads[i,j]; table.DataColumns.Add(col,"Load"+i.ToString(),Altaxo.Data.ColumnKind.V,3); } // now store the residual variances, they are vertical in the vector { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int i=0;i<residualVariances.Rows;i++) col[i] = residualVariances[i,0]; table.DataColumns.Add(col,"ResidualVariance",Altaxo.Data.ColumnKind.V,4); } table.Resume(); mainDocument.DataTableCollection.Add(table); // create a new worksheet without any columns Current.ProjectService.CreateNewWorksheet(table); return null; }
public static void StatisticsOnRows( Altaxo.AltaxoDocument mainDocument, Altaxo.Data.DataTable srctable, IAscendingIntegerCollection selectedColumns, IAscendingIntegerCollection selectedRows ) { bool bUseSelectedColumns = (null != selectedColumns && 0 != selectedColumns.Count); int numcols = bUseSelectedColumns ? selectedColumns.Count : srctable.DataColumns.ColumnCount; if (numcols == 0) { return; // nothing selected } bool bUseSelectedRows = (null != selectedRows && 0 != selectedRows.Count); int numrows = bUseSelectedRows ? selectedRows.Count : srctable.DataColumns.RowCount; if (numrows == 0) { return; } Altaxo.Data.DataTable table = new Altaxo.Data.DataTable(); // add a text column and some double columns // note: statistics is only possible for numeric columns since // otherwise in one column doubles and i.e. dates are mixed, which is not possible // 1st column is the mean, and holds the sum during the calculation Data.DoubleColumn c1 = new Data.DoubleColumn(); // 2rd column is the standard deviation, and holds the square sum during calculation Data.DoubleColumn c2 = new Data.DoubleColumn(); // 3th column is the standard e (N) Data.DoubleColumn c3 = new Data.DoubleColumn(); // 4th column is the sum Data.DoubleColumn c4 = new Data.DoubleColumn(); // 5th column is the number of items for statistics Data.DoubleColumn c5 = new Data.DoubleColumn(); table.DataColumns.Add(c1, "Mean"); table.DataColumns.Add(c2, "sd"); table.DataColumns.Add(c3, "se"); table.DataColumns.Add(c4, "Sum"); table.DataColumns.Add(c5, "N"); table.Suspend(); // first fill the cols c1, c2, c5 with zeros because we want to sum up for (int i = 0; i < numrows; i++) { c1[i] = 0; c2[i] = 0; c5[i] = 0; } for (int si = 0; si < numcols; si++) { Altaxo.Data.DataColumn col = bUseSelectedColumns ? srctable[selectedColumns[si]] : srctable[si]; if (!(col is Altaxo.Data.INumericColumn)) { continue; } // now do the statistics Data.INumericColumn ncol = (Data.INumericColumn)col; for (int i = 0; i < numrows; i++) { double val = bUseSelectedRows ? ncol[selectedRows[i]] : ncol[i]; if (Double.IsNaN(val)) { continue; } c1[i] += val; c2[i] += val * val; c5[i] += 1; } } // for all selected columns // now calculate the statistics for (int i = 0; i < numrows; i++) { // now fill a new row in the worksheet double NN = c5[i]; double sum = c1[i]; double sumsqr = c2[i]; if (NN > 0) { double mean = c1[i] / NN; double ymy0sqr = sumsqr - sum * sum / NN; if (ymy0sqr < 0) { ymy0sqr = 0; // if this is lesser zero, it is a rounding error, so set it to zero } double sd = NN > 1 ? Math.Sqrt(ymy0sqr / (NN - 1)) : 0; double se = sd / Math.Sqrt(NN); c1[i] = mean; // mean c2[i] = sd; c3[i] = se; c4[i] = sum; c5[i] = NN; } } // for all rows // if a table was created, we add the table to the data set and // create a worksheet if (null != table) { table.Resume(); mainDocument.DataTableCollection.Add(table); // create a new worksheet without any columns Current.ProjectService.CreateNewWorksheet(table); } }
/// <summary> /// Makes a PLS (a partial least squares) analysis of the table or the selected columns / rows and stores the results in a newly created table. /// </summary> /// <param name="mainDocument">The main document of the application.</param> /// <param name="srctable">The table where the data come from.</param> /// <param name="selectedColumns">The selected columns.</param> /// <param name="selectedRows">The selected rows.</param> /// <param name="selectedPropertyColumns">The selected property column(s).</param> /// <param name="bHorizontalOrientedSpectrum">True if a spectrum is a single row, False if a spectrum is a single column.</param> /// <param name="plsOptions">Provides information about the max number of factors and the calculation of cross PRESS value.</param> /// <param name="preprocessOptions">Provides information about how to preprocess the spectra.</param> /// <returns></returns> public virtual string ExecuteAnalysis( Altaxo.AltaxoDocument mainDocument, Altaxo.Data.DataTable srctable, IAscendingIntegerCollection selectedColumns, IAscendingIntegerCollection selectedRows, IAscendingIntegerCollection selectedPropertyColumns, bool bHorizontalOrientedSpectrum, MultivariateAnalysisOptions plsOptions, SpectralPreprocessingOptions preprocessOptions ) { IMatrix matrixX, matrixY; IROVector xOfX; MultivariateContentMemento plsContent = new MultivariateContentMemento(); plsContent.Analysis = this; // now we have to create a new table where to place the calculated factors and loads // we will do that in a vertical oriented manner, i.e. even if the loads are // here in horizontal vectors: in our table they are stored in (vertical) columns Altaxo.Data.DataTable table = new Altaxo.Data.DataTable(this.AnalysisName + " of " + srctable.Name); // Fill the Table table.Suspend(); table.SetTableProperty("Content",plsContent); plsContent.TableName = srctable.Name; // Get matrices GetXYMatrices( srctable, selectedColumns, selectedRows, selectedPropertyColumns, bHorizontalOrientedSpectrum, plsContent, out matrixX, out matrixY, out xOfX ); StoreXOfX(xOfX,table); // Preprocess plsContent.SpectralPreprocessing = preprocessOptions; IVector meanX,scaleX,meanY,scaleY; MultivariateRegression.PreprocessForAnalysis(preprocessOptions,xOfX,matrixX,matrixY, out meanX, out scaleX, out meanY, out scaleY); StorePreprocessedData(meanX,scaleX,meanY,scaleY,table); // Analyze and Store IROVector press; ExecuteAnalysis( matrixX, matrixY, plsOptions, plsContent, table, out press); this.StorePRESSData(press,table); if(plsOptions.CrossPRESSCalculation!=CrossPRESSCalculationType.None) CalculateCrossPRESS(xOfX,matrixX,matrixY,plsOptions,plsContent,table); StoreFRatioData(table,plsContent); StoreOriginalY(table,plsContent); table.Resume(); Current.Project.DataTableCollection.Add(table); // create a new worksheet without any columns Current.ProjectService.CreateNewWorksheet(table); return null; }
public static void StatisticsOnRows( Altaxo.AltaxoDocument mainDocument, Altaxo.Data.DataTable srctable, IAscendingIntegerCollection selectedColumns, IAscendingIntegerCollection selectedRows ) { bool bUseSelectedColumns = (null!=selectedColumns && 0!=selectedColumns.Count); int numcols = bUseSelectedColumns ? selectedColumns.Count : srctable.DataColumns.ColumnCount; if(numcols==0) return; // nothing selected bool bUseSelectedRows = (null!=selectedRows && 0!=selectedRows.Count); int numrows = bUseSelectedRows ? selectedRows.Count : srctable.DataColumns.RowCount; if(numrows==0) return; Altaxo.Data.DataTable table = new Altaxo.Data.DataTable(); // add a text column and some double columns // note: statistics is only possible for numeric columns since // otherwise in one column doubles and i.e. dates are mixed, which is not possible // 1st column is the mean, and holds the sum during the calculation Data.DoubleColumn c1 = new Data.DoubleColumn(); // 2rd column is the standard deviation, and holds the square sum during calculation Data.DoubleColumn c2 = new Data.DoubleColumn(); // 3th column is the standard e (N) Data.DoubleColumn c3 = new Data.DoubleColumn(); // 4th column is the sum Data.DoubleColumn c4 = new Data.DoubleColumn(); // 5th column is the number of items for statistics Data.DoubleColumn c5 = new Data.DoubleColumn(); table.DataColumns.Add(c1,"Mean"); table.DataColumns.Add(c2,"sd"); table.DataColumns.Add(c3,"se"); table.DataColumns.Add(c4,"Sum"); table.DataColumns.Add(c5,"N"); table.Suspend(); // first fill the cols c1, c2, c5 with zeros because we want to sum up for(int i=0;i<numrows;i++) { c1[i]=0; c2[i]=0; c5[i]=0; } for(int si=0;si<numcols;si++) { Altaxo.Data.DataColumn col = bUseSelectedColumns ? srctable[selectedColumns[si]] : srctable[si]; if(!(col is Altaxo.Data.INumericColumn)) continue; // now do the statistics Data.INumericColumn ncol = (Data.INumericColumn)col; for(int i=0;i<numrows;i++) { double val = bUseSelectedRows ? ncol[selectedRows[i]] : ncol[i]; if(Double.IsNaN(val)) continue; c1[i] += val; c2[i] += val*val; c5[i] += 1; } } // for all selected columns // now calculate the statistics for(int i=0;i<numrows;i++) { // now fill a new row in the worksheet double NN=c5[i]; double sum=c1[i]; double sumsqr=c2[i]; if(NN>0) { double mean = c1[i]/NN; double ymy0sqr = sumsqr - sum*sum/NN; if(ymy0sqr<0) ymy0sqr=0; // if this is lesser zero, it is a rounding error, so set it to zero double sd = NN>1 ? Math.Sqrt(ymy0sqr/(NN-1)) : 0; double se = sd/Math.Sqrt(NN); c1[i] = mean; // mean c2[i] = sd; c3[i] = se; c4[i] = sum; c5[i] = NN; } } // for all rows // if a table was created, we add the table to the data set and // create a worksheet if(null!=table) { table.Resume(); mainDocument.DataTableCollection.Add(table); // create a new worksheet without any columns Current.ProjectService.CreateNewWorksheet(table); } }