public XYZMeshedColumnPlotData(Altaxo.Data.DataColumnCollection coll, IAscendingIntegerCollection selected) { m_XColumn = new Altaxo.Data.IndexerColumn(); m_YColumn = new Altaxo.Data.IndexerColumn(); int len = selected == null ? coll.ColumnCount : selected.Count; m_DataColumns = new Altaxo.Data.IReadableColumn[len]; for (int i = 0; i < len; i++) { int idx = null == selected ? i : selected[i]; m_DataColumns[i] = coll[idx]; // set the event chain if (m_DataColumns[i] is Altaxo.Data.DataColumn) { ((Altaxo.Data.DataColumn)m_DataColumns[i]).Changed += new EventHandler(EhColumnDataChangedEventHandler); } } this.SetXBoundsFromTemplate(new FiniteNumericalBoundaries()); this.SetYBoundsFromTemplate(new FiniteNumericalBoundaries()); this.SetVBoundsFromTemplate(new FiniteNumericalBoundaries()); }
/// <summary> /// Copy constructor. /// </summary> /// <param name="from">The object to copy from.</param> /// <remarks>Only clones the references to the data columns, not the columns itself.</remarks> public XYZMeshedColumnPlotData(XYZMeshedColumnPlotData from) { if (from.m_XColumn is Altaxo.Data.DataColumn && ((Altaxo.Data.DataColumn)from.m_XColumn).ParentObject != null) { m_XColumn = from.m_XColumn; } else { m_XColumn = (Altaxo.Data.INumericColumn)from.m_XColumn.Clone(); } if (from.m_YColumn is Altaxo.Data.DataColumn && ((Altaxo.Data.DataColumn)from.m_YColumn).ParentObject != null) { m_YColumn = from.m_YColumn; } else { m_YColumn = (Altaxo.Data.INumericColumn)from.m_YColumn.Clone(); } int len = from.m_DataColumns.Length; m_DataColumns = new Altaxo.Data.IReadableColumn[len]; for (int i = 0; i < len; i++) { m_DataColumns[i] = from.m_DataColumns[i]; // do not clone the data columns! // set the event chain if (m_DataColumns[i] is Altaxo.Data.DataColumn) { ((Altaxo.Data.DataColumn)m_DataColumns[i]).Changed += new EventHandler(EhColumnDataChangedEventHandler); } } this.SetXBoundsFromTemplate(new FiniteNumericalBoundaries()); this.SetYBoundsFromTemplate(new FiniteNumericalBoundaries()); this.SetVBoundsFromTemplate(new FiniteNumericalBoundaries()); }
/// <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); }
/// <summary> /// Constructor /// </summary> /// <param name="column">The <see cref="DataColumn" /> to wrap.</param> /// <param name="nRows">The number of rows that are part of the vector. (Starting from index 0).</param> public NumericColumnToROVectorWrapper(Altaxo.Data.INumericColumn column, int nRows) { _column = column; _rows = nRows; }
/// <summary> /// Constructor /// </summary> /// <param name="column">The <see cref="DataColumn" /> to wrap.</param> /// <param name="nRows">The number of rows that are part of the vector. (Starting from index 0).</param> public NumericColumnToROHorzMatrixWrapper(Altaxo.Data.INumericColumn column, int nRows) { _column = column; _rows = nRows; }
/// <summary> /// Constructor /// </summary> /// <param name="column">The <see cref="DataColumn" /> to wrap.</param> /// <param name="selectedRows">The set of rows that are part of the vector. This collection is not cloned here, therefore it must not be subsequently changed!</param> public NumericColumnSelectedRowsToROVectorWrapper(Altaxo.Data.INumericColumn column, IAscendingIntegerCollection selectedRows) { _column = column; _rows = selectedRows; }
/// <summary> /// Constructor /// </summary> /// <param name="column">The <see cref="DataColumn" /> to wrap.</param> /// <param name="start">Index of the element in <paramref name="column"/> that is used as first element of the wrapped vector.</param> /// <param name="nRows">The number of rows that are part of the vector. (Starting from index 0).</param> public NumericColumnToROVectorWrapper(Altaxo.Data.INumericColumn column, int start, int nRows) { _column = column; _start = start; _rows = nRows; }
/// <summary> /// Constructor /// </summary> /// <param name="column">The <see cref="DataColumn" /> to wrap.</param> /// <param name="nRows">The number of rows that are part of the vector. (Starting from index 0).</param> public NumericColumnToROVertMatrixWrapper(Altaxo.Data.INumericColumn column, int nRows) { _column = column; _rows = nRows; }
public static LinearFitBySvd Regress(MultivariateLinearFitParameters parameters, out string[] paramNames) { DataColumnCollection table = parameters.Table; IAscendingIntegerCollection selectedCols = parameters.SelectedDataColumns; AscendingIntegerCollection selectedColsWODependent = new AscendingIntegerCollection(selectedCols); selectedColsWODependent.RemoveAt(parameters.DependentColumnIndexIntoSelection); IAscendingIntegerCollection validRows = DataTableWrapper.GetCollectionOfValidNumericRows(parameters.Table, selectedCols); parameters.SelectedDataRows = validRows; IROMatrix xbase; if (parameters.IncludeIntercept) { xbase = DataTableWrapper.ToROColumnMatrixWithIntercept(parameters.Table, selectedColsWODependent, validRows); } else { xbase = DataTableWrapper.ToROColumnMatrix(parameters.Table, selectedColsWODependent, validRows); } paramNames = new string[xbase.Columns]; if (parameters.IncludeIntercept) { paramNames[0] = "Intercept"; for (int i = 0; i < selectedColsWODependent.Count; i++) { paramNames[i + 1] = table[selectedColsWODependent[i]].Name; } } else { for (int i = 0; i < selectedColsWODependent.Count; i++) { paramNames[i] = table[selectedColsWODependent[i]].Name; } } // Fill the y and the error array double[] yarr = new double[validRows.Count]; double[] earr = new double[validRows.Count]; Altaxo.Data.INumericColumn ycol = (Altaxo.Data.INumericColumn)table[selectedCols[parameters.DependentColumnIndexIntoSelection]]; for (int i = 0; i < validRows.Count; i++) { yarr[i] = ycol[validRows[i]]; earr[i] = 1; } LinearFitBySvd fit = new LinearFitBySvd( xbase, yarr, earr, xbase.Rows, xbase.Columns, 1E-5); return(fit); }