Browse Source

LA: tweak matrix.ToString formatting (auto column count + width)

provider
Christoph Ruegg 12 years ago
parent
commit
7726242ba3
  1. 1
      build.fsx
  2. 293
      src/Numerics/LinearAlgebra/Matrix.BCL.cs

1
build.fsx

@ -361,6 +361,7 @@ let provideReadme title releasenotes path =
|> ReplaceFile (path @@ "readme.txt")
let provideFsLoader includes path =
// inspired by FsLab/tpetricek
let fullScript = ReadFile "src/FSharp/MathNet.Numerics.fsx" |> Array.ofSeq
let startIndex = fullScript |> Seq.findIndex (fun s -> s.Contains "***MathNet.Numerics.fsx***")
let extraScript = fullScript .[startIndex + 1 ..] |> List.ofSeq

293
src/Numerics/LinearAlgebra/Matrix.BCL.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -29,7 +29,9 @@
// </copyright>
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace MathNet.Numerics.LinearAlgebra
@ -91,7 +93,7 @@ namespace MathNet.Numerics.LinearAlgebra
#endif
/// <summary>
/// Returns a <see cref="System.String"/> that describes the type, dimensions and shape of this matrix.
/// Returns a string that describes the type, dimensions and shape of this matrix.
/// </summary>
public virtual string ToTypeString()
{
@ -99,131 +101,274 @@ namespace MathNet.Numerics.LinearAlgebra
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents the content of this matrix.
/// Returns a string 2D array that summarizes the content of this matrix.
/// </summary>
public string ToMatrixString(int maxRows, int maxColumns, IFormatProvider provider = null)
public string[,] ToMatrixStringArray(int upperRows, int lowerRows, int leftColumns, int rightColumns,
string horizontalEllipsis, string verticalEllipsis, string diagonalEllipsis, Func<T, string> formatValue)
{
return ToMatrixString(maxRows, maxColumns, 12, "G6", provider);
int upper = RowCount <= upperRows ? RowCount : upperRows;
int lower = RowCount <= upperRows ? 0 : RowCount <= upperRows + lowerRows ? RowCount - upperRows : lowerRows;
bool rowEllipsis = RowCount > upper + lower;
int rows = rowEllipsis ? upper + lower + 1 : upper + lower;
int left = ColumnCount <= leftColumns ? ColumnCount : leftColumns;
int right = ColumnCount <= leftColumns ? 0 : ColumnCount <= leftColumns + rightColumns ? RowCount - leftColumns : rightColumns;
bool colEllipsis = ColumnCount > left + right;
int cols = colEllipsis ? left + right + 1 : left + right;
var array = new string[rows, cols];
for (int i = 0; i < upper; i++)
{
for (int j = 0; j < left; j++)
{
array[i, j] = formatValue(At(i, j));
}
if (colEllipsis)
{
array[i, left] = horizontalEllipsis;
}
for (int j = 0; j < right; j++)
{
array[i, left + 1 + j] = formatValue(At(i, ColumnCount - right + j));
}
}
if (rowEllipsis)
{
for (int j = 0; j < left; j++)
{
array[upper, j] = verticalEllipsis;
}
if (colEllipsis)
{
array[upper, left] = diagonalEllipsis;
}
for (int j = 0; j < right; j++)
{
array[upper, left + 1 + j] = verticalEllipsis;
}
}
for (int i = 0; i < lower; i++)
{
for (int j = 0; j < left; j++)
{
array[upper + 1 + i, j] = formatValue(At(RowCount - lower + i, j));
}
if (colEllipsis)
{
array[upper + 1 + i, left] = horizontalEllipsis;
}
for (int j = 0; j < right; j++)
{
array[upper + 1 + i, left + 1 + j] = formatValue(At(RowCount - lower + i, ColumnCount - right + j));
}
}
return array;
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents the content of this matrix.
/// Returns a string 2D array that summarizes the content of this matrix.
/// </summary>
public string ToMatrixString(int maxRows, int maxColumns, int padding, string format = null, IFormatProvider provider = null)
public string[,] ToMatrixStringArray(int upperRows, int lowerRows, int minLeftColumns, int rightColumns, int maxWidth, int padding,
string horizontalEllipsis, string verticalEllipsis, string diagonalEllipsis, Func<T, string> formatValue)
{
int rowN = RowCount <= maxRows ? RowCount : maxRows < 3 ? maxRows : maxRows - 1;
bool rowDots = maxRows < RowCount;
bool rowLast = rowDots && maxRows > 2;
int upper = RowCount <= upperRows ? RowCount : upperRows;
int lower = RowCount <= upperRows ? 0 : RowCount <= upperRows + lowerRows ? RowCount - upperRows : lowerRows;
bool rowEllipsis = RowCount > upper + lower;
int rows = rowEllipsis ? upper + lower + 1 : upper + lower;
int colN = ColumnCount <= maxColumns ? ColumnCount : maxColumns < 3 ? maxColumns : maxColumns - 1;
bool colDots = maxColumns < ColumnCount;
bool colLast = colDots && maxColumns > 2;
int left = ColumnCount <= minLeftColumns ? ColumnCount : minLeftColumns;
int right = ColumnCount <= minLeftColumns ? 0 : ColumnCount <= minLeftColumns + rightColumns ? RowCount - minLeftColumns : rightColumns;
const string separator = " ";
const string dots = "...";
string pdots = "...".PadLeft(padding);
var columnsLeft = new List<Tuple<int, string[]>>();
for (int j = 0; j < left; j++)
{
columnsLeft.Add(FormatColumn(j, rows, upper, lower, rowEllipsis, verticalEllipsis, formatValue));
}
if (format == null)
var columnsRight = new List<Tuple<int, string[]>>();
for (int j = 0; j < right; j++)
{
format = "G8";
columnsRight.Add(FormatColumn(ColumnCount - right + j, rows, upper, lower, rowEllipsis, verticalEllipsis, formatValue));
}
var stringBuilder = new StringBuilder();
int chars = columnsLeft.Sum(t => t.Item1 + padding) + columnsRight.Sum(t => t.Item1 + padding);
for (int j = left; j < ColumnCount - right; j++)
{
var candidate = FormatColumn(j, rows, upper, lower, rowEllipsis, verticalEllipsis, formatValue);
chars += candidate.Item1 + padding;
if (chars > maxWidth)
{
break;
}
columnsLeft.Add(candidate);
}
for (var row = 0; row < rowN; row++)
int cols = columnsLeft.Count + columnsRight.Count;
bool colEllipsis = ColumnCount > cols;
if (colEllipsis)
{
if (row > 0)
cols++;
}
var array = new string[rows, cols];
int colIndex = 0;
foreach (var column in columnsLeft)
{
for (int i = 0; i < column.Item2.Length; i++)
{
stringBuilder.Append(Environment.NewLine);
array[i, colIndex] = column.Item2[i];
}
stringBuilder.Append(At(row, 0).ToString(format, provider).PadLeft(padding));
for (var column = 1; column < colN; column++)
colIndex++;
}
if (colEllipsis)
{
int rowIndex = 0;
for (var row = 0; row < upper; row++)
{
stringBuilder.Append(separator);
stringBuilder.Append(At(row, column).ToString(format, provider).PadLeft(padding));
array[rowIndex++, colIndex] = horizontalEllipsis;
}
if (colDots)
if (rowEllipsis)
{
stringBuilder.Append(separator);
stringBuilder.Append(dots);
if (colLast)
{
stringBuilder.Append(separator);
stringBuilder.Append(At(row, ColumnCount - 1).ToString(format, provider).PadLeft(12));
}
array[rowIndex++, colIndex] = diagonalEllipsis;
}
}
if (rowDots)
{
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(pdots);
for (var column = 1; column < colN; column++)
for (var row = RowCount - lower; row < RowCount; row++)
{
stringBuilder.Append(separator);
stringBuilder.Append(pdots);
array[rowIndex++, colIndex] = horizontalEllipsis;
}
if (colDots)
colIndex++;
}
foreach (var column in columnsRight)
{
for (int i = 0; i < column.Item2.Length; i++)
{
stringBuilder.Append(separator);
stringBuilder.Append(dots);
if (colLast)
{
stringBuilder.Append(separator);
stringBuilder.Append(pdots);
}
array[i, colIndex] = column.Item2[i];
}
colIndex++;
}
return array;
}
if (rowLast)
Tuple<int, string[]> FormatColumn(int column, int height, int upper, int lower, bool withEllipsis, string ellipsis, Func<T, string> formatValue)
{
var c = new string[height];
int index = 0;
for (var row = 0; row < upper; row++)
{
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(At(RowCount - 1, 0).ToString(format, provider).PadLeft(padding));
for (var column = 1; column < colN; column++)
c[index++] = formatValue(At(row, column));
}
if (withEllipsis)
{
c[index++] = "";
}
for (var row = RowCount - lower; row < RowCount; row++)
{
c[index++] = formatValue(At(row, column));
}
int w = c.Max(x => x.Length);
if (withEllipsis)
{
c[upper] = ellipsis;
}
return new Tuple<int, string[]>(w, c);
}
static string FormatStringArrayToString(string[,] array, string columnSeparator, string rowSeparator)
{
var rows = array.GetLength(0);
var cols = array.GetLength(1);
var widths = new int[cols];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
stringBuilder.Append(separator);
stringBuilder.Append(At(RowCount - 1, column).ToString(format, provider).PadLeft(padding));
widths[j] = Math.Max(widths[j], array[i, j].Length);
}
if (colDots)
}
var sb = new StringBuilder();
for (int i = 0; i < rows; i++)
{
sb.Append(array[i, 0].PadLeft(widths[0]));
for (int j = 1; j < cols; j++)
{
stringBuilder.Append(separator);
stringBuilder.Append(dots);
if (colLast)
{
stringBuilder.Append(separator);
stringBuilder.Append(At(RowCount - 1, ColumnCount - 1).ToString(format, provider).PadLeft(padding));
}
sb.Append(columnSeparator);
sb.Append(array[i, j].PadLeft(widths[j]));
}
sb.Append(rowSeparator);
}
return sb.ToString();
}
public string ToMatrixString(int upperRows, int lowerRows, int leftColumns, int rightColumns,
string horizontalEllipsis, string verticalEllipsis, string diagonalEllipsis,
string columnSeparator, string rowSeparator, Func<T, string> formatValue)
{
return FormatStringArrayToString(
ToMatrixStringArray(upperRows, lowerRows, leftColumns, rightColumns, horizontalEllipsis, verticalEllipsis, diagonalEllipsis, formatValue),
columnSeparator, rowSeparator);
}
public string ToMatrixString(int upperRows, int lowerRows, int minLeftColumns, int rightColumns, int maxWidth,
string horizontalEllipsis, string verticalEllipsis, string diagonalEllipsis,
string columnSeparator, string rowSeparator, Func<T, string> formatValue)
{
return FormatStringArrayToString(
ToMatrixStringArray(upperRows, lowerRows, minLeftColumns, rightColumns, maxWidth, columnSeparator.Length, horizontalEllipsis, verticalEllipsis, diagonalEllipsis, formatValue),
columnSeparator, rowSeparator);
}
/// <summary>
/// Returns a string that summarizes the content of this matrix.
/// </summary>
public string ToMatrixString(int maxRows, int maxColumns, string format = null, IFormatProvider provider = null)
{
if (format == null)
{
format = "G6";
}
return ToMatrixString(maxRows - 2, 2, maxColumns - 2, 2, "..", "..", "..", " ", Environment.NewLine, x => x.ToString(format, provider));
}
/// <summary>
/// Returns a string that summarizes the content of this matrix.
/// </summary>
public string ToMatrixString(string format = null, IFormatProvider provider = null)
{
if (format == null)
{
format = "G6";
}
return stringBuilder.ToString();
return ToMatrixString(8, 4, 5, 2, 76, "..", "..", "..", " ", Environment.NewLine, x => x.ToString(format, provider));
}
/// <summary>
/// Returns a <see cref="System.String"/> that summarizes this matrix.
/// Returns a string that summarizes this matrix.
/// </summary>
public string ToString(int maxRows, int maxColumns, IFormatProvider provider = null)
public string ToString(int maxRows, int maxColumns, string format = null, IFormatProvider formatProvider = null)
{
return string.Concat(ToTypeString(), Environment.NewLine, ToMatrixString(maxRows, maxColumns, provider));
return string.Concat(ToTypeString(), Environment.NewLine, ToMatrixString(maxRows, maxColumns, format, formatProvider));
}
/// <summary>
/// Returns a <see cref="System.String"/> that summarizes this matrix.
/// Returns a string that summarizes this matrix.
/// The maximum number of cells can be configured in the <see cref="Control"/> class.
/// </summary>
public override sealed string ToString()
{
return string.Concat(ToTypeString(), Environment.NewLine, ToMatrixString(Control.MaxToStringRows, Control.MaxToStringColumns));
return string.Concat(ToTypeString(), Environment.NewLine, ToMatrixString());
}
/// <summary>
/// Returns a <see cref="System.String"/> that summarizes this matrix.
/// Returns a string that summarizes this matrix.
/// The maximum number of cells can be configured in the <see cref="Control"/> class.
/// The format string is ignored.
/// </summary>
public string ToString(string format, IFormatProvider formatProvider)
public string ToString(string format = null, IFormatProvider formatProvider = null)
{
return string.Concat(ToTypeString(), Environment.NewLine, ToMatrixString(Control.MaxToStringRows, Control.MaxToStringColumns, formatProvider));
return string.Concat(ToTypeString(), Environment.NewLine, ToMatrixString(format, formatProvider));
}
}
}

Loading…
Cancel
Save