Пример #1
0
        /// <summary>
        /// Same as <see cref="Cern.Colt.Partitioning.Partition(int[], int, int, int[], int, int, int[])"/>
        /// except that it <i>synchronously</i> partitions the rows of the given matrix by the values of the given matrix column;
        /// This is essentially the same as partitioning a list of composite objects by some instance variable;
        /// In other words, two entire rows of the matrix are swapped, whenever two column values indicate so.
        /// <p>
        /// Let's say, a "row" is an "object" (tuple, d-dimensional point).
        /// A "column" is the list of "object" values of a given variable (field, dimension).
        /// A "matrix" is a list of "objects" (tuples, points).
        /// <p>
        /// Now, rows (objects, tuples) are partially sorted according to their values in one given variable (dimension).
        /// Two entire rows of the matrix are swapped, whenever two column values indicate so.
        /// <p>
        /// Note that arguments are not checked for validity.
        /// </summary>
        /// <param name="matrix">
        /// the matrix to be partitioned.
        /// </param>
        /// <param name="column">
        /// the index of the column to partition on.
        /// </param>
        /// <param name="splitters">
        /// the values at which the rows shall be split into intervals.
        ///             Must be sorted ascending and must not contain multiple identical values.
        ///             These preconditions are not checked; be sure that they are met.
        /// </param>
        /// <param name="splitIndexes">
        /// a list into which this method fills the indexes of rows delimiting intervals.
        /// Therefore, must satisfy <i>splitIndexes.Length >= splitters.Length</i>.
        /// </param>
        /// <returns>a new matrix view having rows partitioned by the given column and splitters.</returns>
        /// <example>
        /// <table border="1" cellspacing="0">
        ///           <tr nowrap>
        ///             <td valign="top"><i>8 x 3 matrix:<br>
        ///               23, 22, 21<br>
        ///               20, 19, 18<br>
        ///               17, 16, 15<br>
        ///               14, 13, 12<br>
        ///               11, 10, 9<br>
        ///               8,  7,  6<br>
        ///               5,  4,  3<br>
        ///               2,  1,  0 </i></td>
        ///             <td align="left" valign="top">
        ///                 <i>column = 0;<br>
        ///                 splitters = {5,10,12}<br>
        ///                 partition(matrix,column,splitters,splitIndexes);<br>
        ///                 ==><br>
        ///                 splitIndexes == {0, 2, 3}</i></p>
        ///               </td>
        ///             <td valign="top">
        ///               The matrix IS NOT REORDERED.<br>
        ///               The new VIEW IS REORDERED:<br>
        ///               <i>8 x 3 matrix:<br>
        ///               2,  1,  0<br>
        ///               5,  4,  3<br>
        ///               8,  7,  6<br>
        ///               11, 10, 9<br>
        ///               23, 22, 21<br>
        ///               20, 19, 18<br>
        ///               17, 16, 15<br>
        ///               14, 13, 12 </i></td>
        ///           </tr>
        /// </table>
        /// </example>
        public static DoubleMatrix2D Partition(DoubleMatrix2D matrix, int column, double[] splitters, int[] splitIndexes)
        {
            int rowFrom   = 0;
            int rowTo     = matrix.Rows - 1;
            int splitFrom = 0;
            int splitTo   = splitters.Length - 1;

            int[] rowIndexes = new int[matrix.Rows]; // row indexes to reorder instead of matrix itself
            for (int i = rowIndexes.Length; --i >= 0;)
            {
                rowIndexes[i] = i;
            }

            Partition(matrix, rowIndexes, rowFrom, rowTo, column, splitters, splitFrom, splitTo, splitIndexes);

            // take all columns in the original order
            int[] columnIndexes = new int[matrix.Columns];
            for (int i = columnIndexes.Length; --i >= 0;)
            {
                columnIndexes[i] = i;
            }

            // view the matrix according to the reordered row indexes
            return(matrix.ViewSelection(rowIndexes, columnIndexes));
        }
Пример #2
0
        /// <summary>
        /// Sorts the matrix rows into ascending order, according to the <i>natural ordering</i> of the matrix values in the given column.
        /// </summary>
        /// <param name="matrix">
        /// The matrix to be sorted.
        /// </param>
        /// <param name="column">
        /// The index of the column inducing the order.
        /// </param>
        /// <returns>
        /// A new matrix view having rows sorted by the given column.
        /// </returns>
        /// <exception cref="IndexOutOfRangeException">
        /// If <i>column &lt; 0 || column &gt;= matrix.columns()</i>.
        /// </exception>
        public DoubleMatrix2D Sort(DoubleMatrix2D matrix, int column)
        {
            if (column < 0 || column >= matrix.Columns)
            {
                throw new IndexOutOfRangeException("column=" + column + ", matrix=" + AbstractFormatter.Shape(matrix));
            }

            var rowIndexes = new int[matrix.Rows]; // row indexes to reorder instead of matrix itself

            for (int i = rowIndexes.Length; --i >= 0;)
            {
                rowIndexes[i] = i;
            }

            DoubleMatrix1D col = matrix.ViewColumn(column);

            RunSort(
                rowIndexes,
                0,
                rowIndexes.Length,
                (a, b) =>
            {
                double av = col[a];
                double bv = col[b];
                if (Double.IsNaN(av) || Double.IsNaN(bv))
                {
                    return(CompareNaN(av, bv));                                          // swap NaNs to the end
                }
                return(av < bv ? -1 : (av == bv ? 0 : 1));
            });

            // view the matrix according to the reordered row indexes
            // take all columns in the original order
            return(matrix.ViewSelection(rowIndexes, null));
        }
Пример #3
0
        /// <summary>
        /// Sorts the matrix rows into ascending order, according to the <i>natural ordering</i> of the matrix values in the virtual column <i>aggregates</i>;
        /// Particularly efficient when comparing expensive aggregates, because aggregates need not be recomputed time and again, as is the case for comparator based sorts.
        /// Essentially, this algorithm makes expensive comparisons cheap.
        /// Normally each element of <i>aggregates</i> is a summary measure of a row.
        /// Speedup over comparator based sorting = <i>2*log(rows)</i>, on average.
        /// For this operation, quicksort is usually faster.
        /// </summary>
        /// <param name="matrix">
        /// The matrix to be sorted.
        /// </param>
        /// <param name="aggregates">
        /// The values to sort ond (As a side effect, this array will also get sorted).
        /// </param>
        /// <returns>
        /// A new matrix view having rows sorted.
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">
        /// If <i>aggregates.Length != matrix.rows()</i>.
        /// </exception>
        public DoubleMatrix2D Sort(DoubleMatrix2D matrix, double[] aggregates)
        {
            int rows = matrix.Rows;

            if (aggregates.Length != rows)
            {
                throw new ArgumentOutOfRangeException("aggregates", "aggregates.Length != matrix.rows()");
            }

            // set up index reordering
            var indexes = new int[rows];

            for (int i = rows; --i >= 0;)
            {
                indexes[i] = i;
            }

            // sort indexes and aggregates
            RunSort(
                0,
                rows,
                (x, y) =>
            {
                double a = aggregates[x];
                double b = aggregates[y];
                if (Double.IsNaN(a) || Double.IsNaN(b))
                {
                    return(CompareNaN(a, b));                                        // swap NaNs to the end
                }
                return(a < b ? -1 : (a == b) ? 0 : 1);
            },
                (x, y) =>
            {
                int t1    = indexes[x]; indexes[x] = indexes[y]; indexes[y] = t1;
                double t2 = aggregates[x]; aggregates[x] = aggregates[y]; aggregates[y] = t2;
            });

            // view the matrix according to the reordered row indexes
            // take all columns in the original order
            return(matrix.ViewSelection(indexes, null));
        }
Пример #4
0
        /// <summary>
        /// Sorts the matrix rows according to the order induced by the specified comparator.
        /// </summary>
        /// <param name="matrix">
        /// The matrix to be sorted.
        /// </param>
        /// <param name="c">
        /// The comparator to determine the order.
        /// </param>
        /// <returns>
        /// A new matrix view having rows sorted as specified.
        /// </returns>
        public DoubleMatrix2D Sort(DoubleMatrix2D matrix, DoubleMatrix1DComparator c)
        {
            var rowIndexes = new int[matrix.Rows]; // row indexes to reorder instead of matrix itself

            for (int i = rowIndexes.Length; --i >= 0;)
            {
                rowIndexes[i] = i;
            }

            var views = new DoubleMatrix1D[matrix.Rows]; // precompute views for speed

            for (int i = views.Length; --i >= 0;)
            {
                views[i] = matrix.ViewRow(i);
            }

            RunSort(rowIndexes, 0, rowIndexes.Length, (a, b) => c(views[a], views[b]));

            // view the matrix according to the reordered row indexes
            // take all columns in the original order
            return(matrix.ViewSelection(rowIndexes, null));
        }
Пример #5
0
 public static DoubleMatrix2D Permute(DoubleMatrix2D A, int[] rowIndexes, int[] columnIndexes)
 {
     return(A.ViewSelection(rowIndexes, columnIndexes));
 }