/// <summary> /// Sorts the matrix rows according to the order induced by the specified comparator. /// The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa. /// The algorithm compares two rows (1-d matrices) at a time, determinining whether one is smaller, equal or larger than the other. /// To sort ranges use sub-ranging viewsd To sort columns by rows, use dice viewsd To sort descending, use flip views ... /// <p> /// <b>Example:</b> /// <pre> /// // sort by sum of values in a row /// ObjectMatrix1DComparator comp = new ObjectMatrix1DComparator() { /// public int compare(ObjectMatrix1D a, ObjectMatrix1D b) { /// Object as = a.zSum(); Object bs = b.zSum(); /// return as %lt; bs ? -1 : as == bs ? 0 : 1; /// } /// }; /// sorted = quickSort(matrix,comp); /// </pre> /// /// @param matrix the matrix to be sorted. /// @param c the comparator to determine the order. /// @return a new matrix view having rows sorted as specified. /// <b>Note that the original matrix is left unaffected.</b> /// </summary> public ObjectMatrix2D sort(ObjectMatrix2D matrix, ObjectMatrix1DComparator c) { int[] rowIndexes = new int[matrix.Rows]; // row indexes to reorder instead of matrix itself for (int i = rowIndexes.Length; --i >= 0;) { rowIndexes[i] = i; } ObjectMatrix1D[] views = new ObjectMatrix1D[matrix.Rows]; // precompute views for speed for (int i = views.Length; --i >= 0;) { views[i] = matrix.ViewRow(i); } IntComparator comp = new IntComparator((a, b) => { return(c(views[a], views[b])); }); RunSort(rowIndexes, 0, rowIndexes.Length, comp); // view the matrix according to the reordered row indexes // take all columns in the original order return(matrix.ViewSelection(rowIndexes, null)); }
/// <summary> /// Assigns the result of a function to each cell; <i>x[row,col] = function(x[row,col],y[row,col])</i>. /// <p> /// <b>Example:</b> /// <pre> /// // assign x[row,col] = x[row,col]<sup>y[row,col]</sup> /// m1 = 2 x 2 matrix /// 0 1 /// 2 3 /// /// m2 = 2 x 2 matrix /// 0 2 /// 4 6 /// /// m1.assign(m2, Cern.Jet.Math.Functions.pow); /// --> /// m1 == 2 x 2 matrix /// 1 1 /// 16 729 /// </pre> /// For further examples, see the <a href="package-summary.html#FunctionObjects">package doc</a>. /// </summary> /// <param name="y">the secondary matrix to operate on.</param> /// <param name="function">a function object taking as first argument the current cell's value of <i>this</i>, and as second argument the current cell's value of <i>y</i>,</param> /// <returns><i>this</i> (for convenience only).</returns> /// <exception cref="ArgumentException">if <i>columns() != other.columns() || rows() != other.rows()</i></exception> /// <see cref="Cern.Jet.Math.Functions"/> public override ObjectMatrix2D Assign(ObjectMatrix2D y, Cern.Colt.Function.ObjectObjectFunction <Object> function) { // overriden for performance only if (!(y is DenseObjectMatrix2D)) { return(base.Assign(y, function)); } DenseObjectMatrix2D other = (DenseObjectMatrix2D)y; CheckShape(y); Object[] elems = this.Elements; Object[] otherElems = other.Elements; if (elems == null || otherElems == null) { throw new NullReferenceException(); } int cs = this.ColumnStride; int ocs = other.ColumnStride; int rs = this.RowStride; int ors = other.RowStride; int otherIndex = other.Index(0, 0); int index = base.Index(0, 0); // the general case x[i] = f(x[i],y[i]) for (int row = Rows; --row >= 0;) { for (int i = index, j = otherIndex, column = Columns; --column >= 0;) { elems[i] = function(elems[i], otherElems[j]); i += cs; j += ocs; } index += rs; otherIndex += ors; } return(this); }
/// <summary> /// Sorts the matrix slices according to the order induced by the specified comparator. /// The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa. /// The algorithm compares two slices (2-d matrices) at a time, determinining whether one is smaller, equal or larger than the other. /// To sort ranges use sub-ranging viewsd To sort by other dimensions, use dice viewsd To sort descending, use flip views ... /// <p> /// <b>Example:</b> /// <pre> /// sort by sum of values in a slice /// ObjectMatrix2DComparator comp = new ObjectMatrix2DComparator() { /// public int compare(ObjectMatrix2D a, ObjectMatrix2D b) { /// Object as = a.zSum(); Object bs = b.zSum(); /// return as %lt; bs ? -1 : as == bs ? 0 : 1; /// } /// }; /// sorted = quickSort(matrix,comp); /// </pre> /// /// @param matrix the matrix to be sorted. /// @param c the comparator to determine the order. /// @return a new matrix view having slices sorted as specified. /// <b>Note that the original matrix is left unaffected.</b> /// </summary> public ObjectMatrix3D sort(ObjectMatrix3D matrix, ObjectMatrix2DComparator c) { int[] sliceIndexes = new int[matrix.Slices]; // indexes to reorder instead of matrix itself for (int i = sliceIndexes.Length; --i >= 0;) { sliceIndexes[i] = i; } ObjectMatrix2D[] views = new ObjectMatrix2D[matrix.Slices]; // precompute views for speed for (int i = views.Length; --i >= 0;) { views[i] = matrix.ViewSlice(i); } IntComparator comp = new IntComparator((a, b) => { return(c(views[a], views[b])); }); RunSort(sliceIndexes, 0, sliceIndexes.Length, comp); // view the matrix according to the reordered slice indexes // take all rows and columns in the original order return(matrix.ViewSelection(sliceIndexes, null, null)); }
/// <summary> /// Returns a string representation of the given matrix with axis as well as rows and columns labeled. /// Pass <i>null</i> to one or more parameters to indicate that the corresponding decoration element shall not appear in the string converted matrix. /// </summary> /// <param name="matrix">The matrix to format.</param> /// <param name="rowNames">The headers of all rows (to be put to the left of the matrix).</param> /// <param name="columnNames">The headers of all columns (to be put to above the matrix).</param> /// <param name="rowAxisName">The label of the y-axis.</param> /// <param name="columnAxisName">The label of the x-axis.</param> /// <param name="title">The overall title of the matrix to be formatted.</param> /// <returns>the matrix converted to a string.</returns> public String ToTitleString(ObjectMatrix2D matrix, String[] rowNames, String[] columnNames, String rowAxisName, String columnAxisName, String title) { if (matrix.Size == 0) { return("Empty matrix"); } String oldFormat = this.formatString; this.formatString = LEFT; int rows = matrix.Rows; int columns = matrix.Columns; // determine how many rows and columns are needed int r = 0; int c = 0; r += (columnNames == null ? 0 : 1); c += (rowNames == null ? 0 : 1); c += (rowAxisName == null ? 0 : 1); c += (rowNames != null || rowAxisName != null ? 1 : 0); int height = r + System.Math.Max(rows, rowAxisName == null ? 0 : rowAxisName.Length); int width = c + columns; // make larger matrix holding original matrix and naming strings ObjectMatrix2D titleMatrix = matrix.Like(height, width); // insert original matrix into larger matrix titleMatrix.ViewPart(r, c, rows, columns).Assign(matrix); // insert column axis name in leading row if (r > 0) { titleMatrix.ViewRow(0).ViewPart(c, columns).Assign(columnNames); } // insert row axis name in leading column if (rowAxisName != null) { String[] rowAxisStrings = new String[rowAxisName.Length]; for (int i = rowAxisName.Length; --i >= 0;) { rowAxisStrings[i] = rowAxisName.Substring(i, i + 1); } titleMatrix.ViewColumn(0).ViewPart(r, rowAxisName.Length).Assign(rowAxisStrings); } // insert row names in next leading columns if (rowNames != null) { titleMatrix.ViewColumn(c - 2).ViewPart(r, rows).Assign(rowNames); } // insert vertical "---------" separator line in next leading column if (c > 0) { titleMatrix.ViewColumn(c - 2 + 1).ViewPart(0, rows + r).Assign("|"); } // convert the large matrix to a string Boolean oldPrintShape = this.printShape; this.printShape = false; String str = ToString(titleMatrix); this.printShape = oldPrintShape; // insert horizontal "--------------" separator line StringBuilder total = new StringBuilder(str); if (columnNames != null) { int i = str.IndexOf(rowSeparator); total.Insert(i + 1, Repeat('-', i) + rowSeparator); } else if (columnAxisName != null) { int i = str.IndexOf(rowSeparator); total.Insert(0, Repeat('-', i) + rowSeparator); } // insert line for column axis name if (columnAxisName != null) { int j = 0; if (c > 0) { j = str.IndexOf('|'); } String s = Blanks(j); if (c > 0) { s = s + "| "; } s = s + columnAxisName + "\n"; total.Insert(0, s); } // insert title if (title != null) { total.Insert(0, title + "\n"); } this.formatString = oldFormat; return(total.ToString()); }
/// <summary> /// Returns a string representation of the given matrix. /// </summary> /// <param name="matrix">the matrix to convert.</param> /// <returns></returns> public String ToString(ObjectMatrix2D matrix) { return(base.ToString(matrix)); }