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());
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
 /// <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;
 }
예제 #6
0
 /// <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;
 }
예제 #7
0
 /// <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;
 }
예제 #8
0
			/// <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;
			}
예제 #9
0
			/// <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;
			}
예제 #10
0
			/// <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;
			}
예제 #11
0
        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);
        }