diff --git a/build.fsx b/build.fsx
index dfc3fd33..b7581440 100644
--- a/build.fsx
+++ b/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
diff --git a/src/Numerics/LinearAlgebra/Matrix.BCL.cs b/src/Numerics/LinearAlgebra/Matrix.BCL.cs
index aa8dfeff..af555eba 100644
--- a/src/Numerics/LinearAlgebra/Matrix.BCL.cs
+++ b/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 @@
//
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
///
- /// Returns a that describes the type, dimensions and shape of this matrix.
+ /// Returns a string that describes the type, dimensions and shape of this matrix.
///
public virtual string ToTypeString()
{
@@ -99,131 +101,274 @@ namespace MathNet.Numerics.LinearAlgebra
}
///
- /// Returns a that represents the content of this matrix.
+ /// Returns a string 2D array that summarizes the content of this matrix.
///
- 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 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;
}
///
- /// Returns a that represents the content of this matrix.
+ /// Returns a string 2D array that summarizes the content of this matrix.
///
- 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 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>();
+ for (int j = 0; j < left; j++)
+ {
+ columnsLeft.Add(FormatColumn(j, rows, upper, lower, rowEllipsis, verticalEllipsis, formatValue));
+ }
- if (format == null)
+ var columnsRight = new List>();
+ 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 FormatColumn(int column, int height, int upper, int lower, bool withEllipsis, string ellipsis, Func 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(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 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 formatValue)
+ {
+ return FormatStringArrayToString(
+ ToMatrixStringArray(upperRows, lowerRows, minLeftColumns, rightColumns, maxWidth, columnSeparator.Length, horizontalEllipsis, verticalEllipsis, diagonalEllipsis, formatValue),
+ columnSeparator, rowSeparator);
+ }
+
+ ///
+ /// Returns a string that summarizes the content of this matrix.
+ ///
+ 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));
+ }
+
+ ///
+ /// Returns a string that summarizes the content of this matrix.
+ ///
+ 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));
}
///
- /// Returns a that summarizes this matrix.
+ /// Returns a string that summarizes this matrix.
///
- 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));
}
///
- /// Returns a that summarizes this matrix.
+ /// Returns a string that summarizes this matrix.
/// The maximum number of cells can be configured in the class.
///
public override sealed string ToString()
{
- return string.Concat(ToTypeString(), Environment.NewLine, ToMatrixString(Control.MaxToStringRows, Control.MaxToStringColumns));
+ return string.Concat(ToTypeString(), Environment.NewLine, ToMatrixString());
}
///
- /// Returns a that summarizes this matrix.
+ /// Returns a string that summarizes this matrix.
/// The maximum number of cells can be configured in the class.
/// The format string is ignored.
///
- 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));
}
}
}