Browse Source

LA: fix indexing bug in new ToVectorString/ToMatrixString routines

provider
Christoph Ruegg 12 years ago
parent
commit
7424447edb
  1. 36
      src/Numerics/LinearAlgebra/Matrix.BCL.cs
  2. 3
      src/Numerics/LinearAlgebra/Vector.BCL.cs
  3. 13
      src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs
  4. 10
      src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs

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

@ -106,13 +106,18 @@ namespace MathNet.Numerics.LinearAlgebra
public string[,] ToMatrixStringArray(int upperRows, int lowerRows, int leftColumns, int rightColumns, public string[,] ToMatrixStringArray(int upperRows, int lowerRows, int leftColumns, int rightColumns,
string horizontalEllipsis, string verticalEllipsis, string diagonalEllipsis, Func<T, string> formatValue) string horizontalEllipsis, string verticalEllipsis, string diagonalEllipsis, Func<T, string> formatValue)
{ {
upperRows = Math.Max(upperRows, 1);
lowerRows = Math.Max(lowerRows, 0);
leftColumns = Math.Max(leftColumns, 1);
rightColumns = Math.Max(rightColumns, 0);
int upper = RowCount <= upperRows ? RowCount : upperRows; int upper = RowCount <= upperRows ? RowCount : upperRows;
int lower = RowCount <= upperRows ? 0 : RowCount <= upperRows + lowerRows ? RowCount - upperRows : lowerRows; int lower = RowCount <= upperRows ? 0 : RowCount <= upperRows + lowerRows ? RowCount - upperRows : lowerRows;
bool rowEllipsis = RowCount > upper + lower; bool rowEllipsis = RowCount > upper + lower;
int rows = rowEllipsis ? upper + lower + 1 : upper + lower; int rows = rowEllipsis ? upper + lower + 1 : upper + lower;
int left = ColumnCount <= leftColumns ? ColumnCount : leftColumns; int left = ColumnCount <= leftColumns ? ColumnCount : leftColumns;
int right = ColumnCount <= leftColumns ? 0 : ColumnCount <= leftColumns + rightColumns ? RowCount - leftColumns : rightColumns; int right = ColumnCount <= leftColumns ? 0 : ColumnCount <= leftColumns + rightColumns ? ColumnCount - leftColumns : rightColumns;
bool colEllipsis = ColumnCount > left + right; bool colEllipsis = ColumnCount > left + right;
int cols = colEllipsis ? left + right + 1 : left + right; int cols = colEllipsis ? left + right + 1 : left + right;
@ -123,43 +128,51 @@ namespace MathNet.Numerics.LinearAlgebra
{ {
array[i, j] = formatValue(At(i, j)); array[i, j] = formatValue(At(i, j));
} }
int colOffset = left;
if (colEllipsis) if (colEllipsis)
{ {
array[i, left] = horizontalEllipsis; array[i, left] = horizontalEllipsis;
colOffset++;
} }
for (int j = 0; j < right; j++) for (int j = 0; j < right; j++)
{ {
array[i, left + 1 + j] = formatValue(At(i, ColumnCount - right + j)); array[i, colOffset + j] = formatValue(At(i, ColumnCount - right + j));
} }
} }
int rowOffset = upper;
if (rowEllipsis) if (rowEllipsis)
{ {
for (int j = 0; j < left; j++) for (int j = 0; j < left; j++)
{ {
array[upper, j] = verticalEllipsis; array[upper, j] = verticalEllipsis;
} }
int colOffset = left;
if (colEllipsis) if (colEllipsis)
{ {
array[upper, left] = diagonalEllipsis; array[upper, left] = diagonalEllipsis;
colOffset++;
} }
for (int j = 0; j < right; j++) for (int j = 0; j < right; j++)
{ {
array[upper, left + 1 + j] = verticalEllipsis; array[upper, colOffset + j] = verticalEllipsis;
} }
rowOffset++;
} }
for (int i = 0; i < lower; i++) for (int i = 0; i < lower; i++)
{ {
for (int j = 0; j < left; j++) for (int j = 0; j < left; j++)
{ {
array[upper + 1 + i, j] = formatValue(At(RowCount - lower + i, j)); array[rowOffset + i, j] = formatValue(At(RowCount - lower + i, j));
} }
int colOffset = left;
if (colEllipsis) if (colEllipsis)
{ {
array[upper + 1 + i, left] = horizontalEllipsis; array[rowOffset + i, left] = horizontalEllipsis;
colOffset++;
} }
for (int j = 0; j < right; j++) for (int j = 0; j < right; j++)
{ {
array[upper + 1 + i, left + 1 + j] = formatValue(At(RowCount - lower + i, ColumnCount - right + j)); array[rowOffset + i, colOffset + j] = formatValue(At(RowCount - lower + i, ColumnCount - right + j));
} }
} }
return array; return array;
@ -171,13 +184,18 @@ namespace MathNet.Numerics.LinearAlgebra
public string[,] ToMatrixStringArray(int upperRows, int lowerRows, int minLeftColumns, int rightColumns, int maxWidth, int padding, 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) string horizontalEllipsis, string verticalEllipsis, string diagonalEllipsis, Func<T, string> formatValue)
{ {
upperRows = Math.Max(upperRows, 1);
lowerRows = Math.Max(lowerRows, 0);
minLeftColumns = Math.Max(minLeftColumns, 1);
maxWidth = Math.Max(maxWidth, 12);
int upper = RowCount <= upperRows ? RowCount : upperRows; int upper = RowCount <= upperRows ? RowCount : upperRows;
int lower = RowCount <= upperRows ? 0 : RowCount <= upperRows + lowerRows ? RowCount - upperRows : lowerRows; int lower = RowCount <= upperRows ? 0 : RowCount <= upperRows + lowerRows ? RowCount - upperRows : lowerRows;
bool rowEllipsis = RowCount > upper + lower; bool rowEllipsis = RowCount > upper + lower;
int rows = rowEllipsis ? upper + lower + 1 : upper + lower; int rows = rowEllipsis ? upper + lower + 1 : upper + lower;
int left = ColumnCount <= minLeftColumns ? ColumnCount : minLeftColumns; int left = ColumnCount <= minLeftColumns ? ColumnCount : minLeftColumns;
int right = ColumnCount <= minLeftColumns ? 0 : ColumnCount <= minLeftColumns + rightColumns ? RowCount - minLeftColumns : rightColumns; int right = ColumnCount <= minLeftColumns ? 0 : ColumnCount <= minLeftColumns + rightColumns ? ColumnCount - minLeftColumns : rightColumns;
var columnsLeft = new List<Tuple<int, string[]>>(); var columnsLeft = new List<Tuple<int, string[]>>();
for (int j = 0; j < left; j++) for (int j = 0; j < left; j++)
@ -328,7 +346,9 @@ namespace MathNet.Numerics.LinearAlgebra
format = "G6"; format = "G6";
} }
return ToMatrixString(maxRows - 2, 2, maxColumns - 2, 2, "..", "..", "..", " ", Environment.NewLine, x => x.ToString(format, provider)); int bottom = maxRows > 4 ? 2 : 0;
int right = maxColumns > 4 ? 2 : 0;
return ToMatrixString(maxRows - bottom, bottom, maxColumns - right, right, "..", "..", "..", " ", Environment.NewLine, x => x.ToString(format, provider));
} }
/// <summary> /// <summary>

3
src/Numerics/LinearAlgebra/Vector.BCL.cs

@ -261,6 +261,9 @@ namespace MathNet.Numerics.LinearAlgebra
public string[,] ToVectorStringArray(int maxPerColumn, int maxWidth, int padding, string ellipsis, Func<T, string> formatValue) public string[,] ToVectorStringArray(int maxPerColumn, int maxWidth, int padding, string ellipsis, Func<T, string> formatValue)
{ {
maxPerColumn = Math.Max(maxPerColumn, 1);
maxWidth = Math.Max(maxWidth, 12);
var columns = new List<Tuple<int, string[]>>(); var columns = new List<Tuple<int, string[]>>();
int chars = 0; int chars = 0;
int offset = 0; int offset = 0;

13
src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs

@ -196,5 +196,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
AssertHelpers.AlmostEqual(d7, d.Power(7), 10); AssertHelpers.AlmostEqual(d7, d.Power(7), 10);
AssertHelpers.AlmostEqual(d8, d.Power(8), 10); AssertHelpers.AlmostEqual(d8, d.Power(8), 10);
} }
[Test]
public void MatrixToMatrixString()
{
var m = Matrix<double>.Build.Dense(20, 10);
for (int i = 1; i < 25; i++)
{
for (int j = 1; j < 25; j++)
{
GC.KeepAlive(m.ToMatrixString(i, j));
}
}
}
} }
} }

10
src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs

@ -320,5 +320,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
} }
} }
} }
[Test]
public void VectorToVectorString()
{
var v = Vector<double>.Build.Dense(20);
for (int i = 1; i < 25; i++)
{
GC.KeepAlive(v.ToVectorString(i, 80));
}
}
} }
} }

Loading…
Cancel
Save