From a9bd17eb96ed45c3f992898de055a5a14c138c36 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Fri, 29 Mar 2013 16:38:13 +0100 Subject: [PATCH] LA: Rework ToString for matrices and vectors #100 --- src/Numerics/Control.cs | 16 +- .../LinearAlgebra/Complex/SparseVector.cs | 10 -- .../LinearAlgebra/Complex32/SparseVector.cs | 10 -- src/Numerics/LinearAlgebra/Double/Matrix.cs | 2 +- .../LinearAlgebra/Double/SparseVector.cs | 10 -- .../LinearAlgebra/Generic/Matrix.BCL.cs | 140 +++++++++++---- .../LinearAlgebra/Generic/Vector.BCL.cs | 162 ++++++++++++------ .../LinearAlgebra/Single/SparseVector.cs | 10 -- 8 files changed, 234 insertions(+), 126 deletions(-) diff --git a/src/Numerics/Control.cs b/src/Numerics/Control.cs index 8fc5e0ee..0c71a313 100644 --- a/src/Numerics/Control.cs +++ b/src/Numerics/Control.cs @@ -4,7 +4,7 @@ // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // -// Copyright (c) 2009-2010 Math.NET +// Copyright (c) 2009-2013 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -54,6 +54,10 @@ namespace MathNet.Numerics CheckDistributionParameters = true; ThreadSafeRandomNumberGenerators = true; + // ToString & Formatting + MaxToStringColumns = 6; + MaxToStringRows = 8; + // Parallelization & Threading _numberOfThreads = Environment.ProcessorCount; DisableParallelization = _numberOfThreads < 2; @@ -174,5 +178,15 @@ namespace MathNet.Numerics { return !DisableParallelization && NumberOfParallelWorkerThreads >= 2 && elements >= ParallelizeElements; } + + /// + /// Maximum number of columns to print in ToString methods by default. + /// + public static int MaxToStringColumns { get; set; } + + /// + /// Maximum number of rows to print in ToString methods by default. + /// + public static int MaxToStringRows { get; set; } } } diff --git a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs index 0ecb330b..1ce1d42e 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs @@ -1034,15 +1034,5 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return ret; } #endregion - - public override string ToString(string format, IFormatProvider formatProvider) - { - if (Count > 20) - { - return String.Format("SparseVectorOfComplex({0},{1},{2})", Count, _storage.ValueCount, GetHashCode()); - } - - return base.ToString(format, formatProvider); - } } } diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs index a3f731f5..4ce331c4 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs @@ -1034,15 +1034,5 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return ret; } #endregion - - public override string ToString(string format, IFormatProvider formatProvider) - { - if (Count > 20) - { - return String.Format("SparseVectorOfComplex32({0},{1},{2})", Count, _storage.ValueCount, GetHashCode()); - } - - return base.ToString(format, formatProvider); - } } } diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs index f8992e59..724c8638 100644 --- a/src/Numerics/LinearAlgebra/Double/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs @@ -30,10 +30,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double { - using System; using Generic; using Properties; using Storage; + using System; /// /// double version of the class. diff --git a/src/Numerics/LinearAlgebra/Double/SparseVector.cs b/src/Numerics/LinearAlgebra/Double/SparseVector.cs index d22d3c8b..510eed82 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseVector.cs @@ -1068,15 +1068,5 @@ namespace MathNet.Numerics.LinearAlgebra.Double } #endregion - - public override string ToString(string format, IFormatProvider formatProvider) - { - if (Count > 20) - { - return String.Format("SparseVectorOfDouble({0},{1},{2})", Count, _storage.ValueCount, GetHashCode()); - } - - return base.ToString(format, formatProvider); - } } } diff --git a/src/Numerics/LinearAlgebra/Generic/Matrix.BCL.cs b/src/Numerics/LinearAlgebra/Generic/Matrix.BCL.cs index c41b4bfc..7a6d7501 100644 --- a/src/Numerics/LinearAlgebra/Generic/Matrix.BCL.cs +++ b/src/Numerics/LinearAlgebra/Generic/Matrix.BCL.cs @@ -75,67 +75,147 @@ namespace MathNet.Numerics.LinearAlgebra.Generic return Storage.GetHashCode(); } +#if !PORTABLE + /// - /// Returns a that represents this instance. + /// Creates a new object that is a copy of the current instance. /// /// - /// A that represents this instance. + /// A new object that is a copy of this instance. /// - public override string ToString() + object ICloneable.Clone() { - return ToString(null, null); + return Clone(); } +#endif + /// - /// Returns a that represents this instance. + /// Returns a that describes the type, dimensions and shape of this matrix. /// - /// - /// The format to use. - /// - /// - /// The format provider to use. - /// - /// - /// A that represents this instance. - /// - public virtual string ToString(string format, IFormatProvider formatProvider = null) + public virtual string ToTypeString() + { + return string.Format("{0} {1}x{2}-{3}", GetType().Name, RowCount, ColumnCount, typeof(T).Name); + } + + /// + /// Returns a that represents the content of this matrix. + /// + public string ToMatrixString(int maxRows, int maxColumns, IFormatProvider provider) + { + return ToMatrixString(maxRows, maxColumns, 12, "G6", provider); + } + + /// + /// Returns a that represents the content of this matrix. + /// + public string ToMatrixString(int maxRows, int maxColumns, int padding, string format, IFormatProvider provider) { - var separator = (formatProvider.GetTextInfo().ListSeparator); + int rowN = RowCount <= maxRows ? RowCount : maxRows < 3 ? maxRows : maxRows - 1; + bool rowDots = maxRows < RowCount; + bool rowLast = rowDots && maxRows > 2; + + int colN = ColumnCount <= maxColumns ? ColumnCount : maxColumns < 3 ? maxColumns : maxColumns - 1; + bool colDots = maxColumns < ColumnCount; + bool colLast = colDots && maxColumns > 2; + + const string separator = " "; + const string dots = "..."; + string pdots = "...".PadLeft(padding); + var stringBuilder = new StringBuilder(); - for (var row = 0; row < RowCount; row++) + for (var row = 0; row < rowN; row++) + { + stringBuilder.Append(At(row, 0).ToString(format, provider).PadLeft(padding)); + for (var column = 1; column < colN; column++) + { + stringBuilder.Append(separator); + stringBuilder.Append(At(row, column).ToString(format, provider).PadLeft(padding)); + } + if (colDots) + { + stringBuilder.Append(separator); + stringBuilder.Append(dots); + if (colLast) + { + stringBuilder.Append(separator); + stringBuilder.Append(At(row, ColumnCount - 1).ToString(format, provider).PadLeft(12)); + } + } + stringBuilder.Append(Environment.NewLine); + } + + if (rowDots) { - for (var column = 0; column < ColumnCount; column++) + stringBuilder.Append(pdots); + for (var column = 1; column < colN; column++) + { + stringBuilder.Append(separator); + stringBuilder.Append(pdots); + } + if (colDots) { - stringBuilder.Append(At(row, column).ToString(format, formatProvider)); - if (column != ColumnCount - 1) + stringBuilder.Append(separator); + stringBuilder.Append(dots); + if (colLast) { stringBuilder.Append(separator); + stringBuilder.Append(pdots); } } + stringBuilder.Append(Environment.NewLine); + } - if (row != RowCount - 1) + if (rowLast) + { + stringBuilder.Append(At(RowCount - 1, 0).ToString(format, provider).PadLeft(padding)); + for (var column = 1; column < colN; column++) { - stringBuilder.Append(Environment.NewLine); + stringBuilder.Append(separator); + stringBuilder.Append(At(RowCount - 1, column).ToString(format, provider).PadLeft(padding)); } + if (colDots) + { + stringBuilder.Append(separator); + stringBuilder.Append(dots); + if (colLast) + { + stringBuilder.Append(separator); + stringBuilder.Append(At(RowCount - 1, ColumnCount - 1).ToString(format, provider).PadLeft(padding)); + } + } + stringBuilder.Append(Environment.NewLine); } return stringBuilder.ToString(); } -#if !PORTABLE + /// + /// Returns a that summarizes this matrix. + /// + public string ToString(int maxRows, int maxColumns, IFormatProvider provider = null) + { + return string.Concat(ToTypeString(), Environment.NewLine, ToMatrixString(maxRows, maxColumns, provider)); + } /// - /// Creates a new object that is a copy of the current instance. + /// Returns a that summarizes this matrix. + /// The maximum number of cells can be configured in the class. /// - /// - /// A new object that is a copy of this instance. - /// - object ICloneable.Clone() + public override sealed string ToString() { - return Clone(); + return string.Concat(ToTypeString(), Environment.NewLine, ToMatrixString(Control.MaxToStringRows, Control.MaxToStringColumns, null)); } -#endif + /// + /// Returns a 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) + { + return string.Concat(ToTypeString(), Environment.NewLine, ToMatrixString(Control.MaxToStringRows, Control.MaxToStringColumns, formatProvider)); + } } } diff --git a/src/Numerics/LinearAlgebra/Generic/Vector.BCL.cs b/src/Numerics/LinearAlgebra/Generic/Vector.BCL.cs index befe51c3..c727e601 100644 --- a/src/Numerics/LinearAlgebra/Generic/Vector.BCL.cs +++ b/src/Numerics/LinearAlgebra/Generic/Vector.BCL.cs @@ -77,60 +77,6 @@ namespace MathNet.Numerics.LinearAlgebra.Generic return Storage.GetHashCode(); } - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override sealed string ToString() - { - return ToString(null, null); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// An that supplies culture-specific formatting information. - /// - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return ToString(null, formatProvider); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// The format to use. - /// - /// - /// An that supplies culture-specific formatting information. - /// - /// - /// A that represents this instance. - /// - public virtual string ToString(string format, IFormatProvider formatProvider = null) - { - var separator = (formatProvider.GetTextInfo().ListSeparator); - var stringBuilder = new StringBuilder(); - - for (var index = 0; index < Count; index++) - { - stringBuilder.Append(At(index).ToString(format, formatProvider)); - if (index != Count - 1) - { - stringBuilder.Append(separator); - } - } - - return stringBuilder.ToString(); - } - #if !PORTABLE /// @@ -292,5 +238,113 @@ namespace MathNet.Numerics.LinearAlgebra.Generic { return Storage.Enumerate().GetEnumerator(); } + + /// + /// Returns a that describes the type, dimensions and shape of this vector. + /// + public virtual string ToTypeString() + { + return string.Format("{0} {1}-{2}", GetType().Name, Count, typeof(T).Name); + } + + /// + /// Returns a that represents the content of this vector, row by row. + /// + public string ToVectorString(int maxLines, int maxPerLine, IFormatProvider provider) + { + return ToVectorString(maxLines, maxPerLine, 12, "G6", provider); + } + + /// + /// Returns a that represents the content of this vector, row by row. + /// + public string ToVectorString(int maxLines, int maxPerLine, int padding, string format, IFormatProvider provider) + { + int fullLines = Count/maxPerLine; + int lastLine = Count%maxPerLine; + bool incomplete = false; + + if (fullLines > maxLines || fullLines == maxLines && lastLine > 0) + { + fullLines = maxLines - 1; + lastLine = maxPerLine - 1; + incomplete = true; + } + + const string separator = " "; + string pdots = "...".PadLeft(padding); + + var stringBuilder = new StringBuilder(); + + var iterator = GetEnumerator(); + for (var line = 0; line < fullLines; line++) + { + iterator.MoveNext(); + stringBuilder.Append(iterator.Current.ToString(format, provider).PadLeft(padding)); + for (var column = 1; column < maxPerLine; column++) + { + stringBuilder.Append(separator); + iterator.MoveNext(); + stringBuilder.Append(iterator.Current.ToString(format, provider).PadLeft(padding)); + } + stringBuilder.Append(Environment.NewLine); + } + + if (lastLine > 0) + { + iterator.MoveNext(); + stringBuilder.Append(iterator.Current.ToString(format, provider).PadLeft(padding)); + for (var column = 1; column < lastLine; column++) + { + stringBuilder.Append(separator); + iterator.MoveNext(); + stringBuilder.Append(iterator.Current.ToString(format, provider).PadLeft(padding)); + } + if (incomplete) + { + stringBuilder.Append(separator); + stringBuilder.Append(pdots); + } + stringBuilder.Append(Environment.NewLine); + } + + return stringBuilder.ToString(); + } + + /// + /// Returns a that summarizes this vector. + /// + public string ToString(int maxLines, int maxPerLine, IFormatProvider provider = null) + { + return string.Concat(ToTypeString(), Environment.NewLine, ToVectorString(maxLines, maxPerLine, provider)); + } + + /// + /// Returns a that summarizes this vector. + /// The maximum number of cells can be configured in the class. + /// + public override sealed string ToString() + { + return string.Concat(ToTypeString(), Environment.NewLine, ToVectorString(Control.MaxToStringRows, Control.MaxToStringColumns, null)); + } + + /// + /// Returns a that summarizes this vector. + /// The maximum number of cells can be configured in the class. + /// The format string is ignored. + /// + public string ToString(string format, IFormatProvider formatProvider) + { + return string.Concat(ToTypeString(), Environment.NewLine, ToVectorString(Control.MaxToStringRows, Control.MaxToStringColumns, formatProvider)); + } + + /// + /// Returns a that summarizes this vector. + /// + [Obsolete("Scheduled for removal in v3.0.")] + public string ToString(IFormatProvider formatProvider) + { + return ToString(null, formatProvider); + } } } diff --git a/src/Numerics/LinearAlgebra/Single/SparseVector.cs b/src/Numerics/LinearAlgebra/Single/SparseVector.cs index 7b27df71..a5edeae0 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseVector.cs @@ -1072,15 +1072,5 @@ namespace MathNet.Numerics.LinearAlgebra.Single } #endregion - - public override string ToString(string format, IFormatProvider formatProvider) - { - if (Count > 20) - { - return String.Format("SparseVectorOfSingle({0},{1},{2})", Count, _storage.ValueCount, GetHashCode()); - } - - return base.ToString(format, formatProvider); - } } }