Browse Source

io: ported delimited writer. added support for different cultures and column headers

la-knuth
Marcus Cuda 16 years ago
parent
commit
2838a63876
  1. 167
      src/Numerics/LinearAlgebra/Double/IO/DelimitedWriter.cs
  2. 195
      src/Numerics/LinearAlgebra/Double/IO/MatrixWriter.cs
  3. 2
      src/Numerics/Numerics.csproj
  4. 6
      src/Silverlight/Silverlight.csproj
  5. 4
      src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedReaderTests.cs
  6. 90
      src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedWriterTests.cs
  7. 1
      src/UnitTests/UnitTests.csproj

167
src/Numerics/LinearAlgebra/Double/IO/DelimitedWriter.cs

@ -0,0 +1,167 @@
// <copyright file="DelimitedWriter.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Double.IO
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
/// <summary>
/// Writes an <see cref="Matrix"/> to delimited text file. If the user does not
/// specify a delimiter, a tab separator is used.
/// </summary>
public class DelimitedWriter : MatrixWriter
{
/// <summary>
/// The delimiter to use.
/// </summary>
private readonly string _delimiter;
/// <summary>
/// The <see cref="CultureInfo"/> to use.
/// </summary>
private CultureInfo _cultureInfo = CultureInfo.CurrentCulture;
/// <summary>
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class using
/// a comma as the delimiter.
/// </summary>
public DelimitedWriter()
{
_delimiter = ",";
}
/// <summary>
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class
/// using the given delimiter.
/// </summary>
/// <param name="delimiter">
/// the delimiter to use.
/// </param>
public DelimitedWriter(char delimiter)
{
_delimiter = new string(delimiter, 1);
}
/// <summary>
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class
/// using the given delimiter.
/// </summary>
/// <param name="delimiter">
/// the delimiter to use.
/// </param>
public DelimitedWriter(string delimiter)
{
_delimiter = delimiter;
}
/// <summary>
/// Gets or sets the column header values.
/// </summary>
/// <value>The column header values.</value>
/// <remarks>Will write the column headers if the list is not empty or <c>null</c>.</remarks>
public IList<string> ColumnHeaders
{
get;
set;
}
/// <summary>
/// Gets or sets the <see cref="CultureInfo"/> to use when parsing the numbers.
/// </summary>
/// <value>The culture info.</value>
/// <remarks>Defaults to <c>CultureInfo.CurrentCulture</c>.</remarks>
public CultureInfo CultureInfo
{
get
{
return _cultureInfo;
}
set
{
if (value != null)
{
_cultureInfo = value;
}
}
}
/// <summary>
/// Writes the given <see cref="Matrix"/> to the given <see cref="TextWriter"/>.
/// </summary>
/// <param name="matrix">The matrix to write.</param>
/// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</param>
/// <param name="format">The format to use on each element.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="writer"/> is <c>null</c>.</exception>
protected override void DoWriteMatrix(Matrix matrix, TextWriter writer, string format)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (writer == null)
{
throw new ArgumentNullException("writer");
}
if (ColumnHeaders != null && ColumnHeaders.Count > 0)
{
for (var i = 0; i < ColumnHeaders.Count - 1; i++)
{
writer.Write(ColumnHeaders[i]);
writer.Write(_delimiter);
}
writer.WriteLine(ColumnHeaders[ColumnHeaders.Count - 1]);
}
var cols = matrix.ColumnCount - 1;
var rows = matrix.RowCount - 1;
for (var i = 0; i < matrix.RowCount; i++)
{
for (var j = 0; j < matrix.ColumnCount; j++)
{
writer.Write(matrix[i, j].ToString(format, _cultureInfo));
if (j != cols)
{
writer.Write(_delimiter);
}
}
if (i != rows)
{
writer.Write(Environment.NewLine);
}
}
}
}
}

195
src/Numerics/LinearAlgebra/Double/IO/MatrixWriter.cs

@ -0,0 +1,195 @@
// <copyright file="MatrixWriter.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using System.IO;
namespace MathNet.Numerics.LinearAlgebra.Double.IO
{
/// <summary>
/// Base class to write a single <see cref="Matrix"/> to a file or stream.
/// </summary>
public abstract class MatrixWriter
{
/// <summary>
/// Writes the given <see cref="Matrix"/> to the given file. If the file already exists,
/// the file will be overwritten.
/// </summary>
/// <param name="matrix">The matrix to write.</param>
/// <param name="file">The file to write the matrix to.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="file"/> is <c>null</c>.</exception>
public void WriteMatrix(Matrix matrix, string file)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (file == null)
{
throw new ArgumentNullException("file");
}
using (var writer = new StreamWriter(file))
{
DoWriteMatrix(matrix, writer, null);
}
}
/// <summary>
/// Writes the given <see cref="Matrix"/> to the given file. If the file already exists,
/// the file will be overwritten.
/// </summary>
/// <param name="matrix">the matrix to write.</param>
/// <param name="file">The file to write the matrix to.</param>
/// <param name="format">The format to use on each element.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="file"/> is <c>null</c>.</exception>
public void WriteMatrix(Matrix matrix, string file, string format)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (file == null)
{
throw new ArgumentNullException("file");
}
if (File.Exists(file))
{
File.Delete(file);
}
using (var writer = new StreamWriter(file))
{
DoWriteMatrix(matrix, writer, format);
}
}
/// <summary>
/// Writes the given <see cref="Matrix"/> to the given stream.
/// </summary>
/// <param name="matrix">The matrix to write.</param>
/// <param name="stream">The <see cref="Stream"/> to write the matrix to.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="stream"/> is <c>null</c>.</exception>
public void WriteMatrix(Matrix matrix, Stream stream)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (stream == null)
{
throw new ArgumentNullException("stream");
}
using (var writer = new StreamWriter(stream))
{
DoWriteMatrix(matrix, writer, null);
}
}
/// <summary>
/// Writes the given <see cref="Matrix"/> to the given stream.
/// </summary>
/// <param name="matrix">The <see cref="TextWriter"/> to write.</param>
/// <param name="stream">The <see cref="Stream"/> to write the matrix to.</param>
/// <param name="format">The format to use on each element.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="stream"/> is <c>null</c>.</exception>
public void WriteMatrix(Matrix matrix, Stream stream, string format)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (stream == null)
{
throw new ArgumentNullException("stream");
}
using (var writer = new StreamWriter(stream))
{
DoWriteMatrix(matrix, writer, format);
}
}
/// <summary>
/// Writes the given <see cref="Matrix"/> to the given <see cref="TextWriter"/>.
/// </summary>
/// <param name="matrix">The matrix to write.</param>
/// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="writer"/> is <c>null</c>.</exception>
public void WriteMatrix(Matrix matrix, TextWriter writer)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (writer == null)
{
throw new ArgumentNullException("writer");
}
DoWriteMatrix(matrix, writer, null);
}
/// <summary>
/// Writes the given <see cref="Matrix"/> to the given <see cref="TextWriter"/>.
/// </summary>
/// <param name="matrix">The matrix to write.</param>
/// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</param>
/// <param name="format">The format to use on each element.</param>
/// <exception cref="ArgumentNullException">If either <paramref name="matrix"/> or <paramref name="writer"/> is <c>null</c>.</exception>
public void WriteMatrix(Matrix matrix, TextWriter writer, string format)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (writer == null)
{
throw new ArgumentNullException("writer");
}
DoWriteMatrix(matrix, writer, format);
}
/// <summary>
/// Subclasses must implement this method to do the actually writing.
/// </summary>
/// <param name="matrix">The matrix to serialize.</param>
/// <param name="writer">The <see cref="TextWriter"/> to write the matrix to.</param>
/// <param name="format">The format for the new matrix.</param>
protected abstract void DoWriteMatrix(Matrix matrix, TextWriter writer, string format);
}
}

2
src/Numerics/Numerics.csproj

@ -108,7 +108,9 @@
<Compile Include="LinearAlgebra\Double\Factorization\UserQR.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\UserSvd.cs" />
<Compile Include="LinearAlgebra\Double\IO\DelimitedReader.cs" />
<Compile Include="LinearAlgebra\Double\IO\DelimitedWriter.cs" />
<Compile Include="LinearAlgebra\Double\IO\MatrixReader.cs" />
<Compile Include="LinearAlgebra\Double\IO\MatrixWriter.cs" />
<Compile Include="LinearAlgebra\Double\ISolver.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\QR.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\Svd.cs" />

6
src/Silverlight/Silverlight.csproj

@ -263,9 +263,15 @@
<Compile Include="..\Numerics\LinearAlgebra\Double\IO\DelimitedReader.cs">
<Link>LinearAlgebra\Double\IO\DelimitedReader.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\IO\DelimitedWriter.cs">
<Link>LinearAlgebra\Double\IO\DelimitedWriter.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\IO\MatrixReader.cs">
<Link>LinearAlgebra\Double\IO\MatrixReader.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\IO\MatrixWriter.cs">
<Link>LinearAlgebra\Double\IO\MatrixWriter.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\ISolver.cs">
<Link>LinearAlgebra\Double\ISolver.cs</Link>
</Compile>

4
src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedReaderTests.cs

@ -49,7 +49,7 @@
+ Environment.NewLine
+ "'4'\t5\t6";
var reader = new DelimitedReader<DenseMatrix>('\t');
var reader = new DelimitedReader<SparseMatrix>('\t');
var matrix = reader.ReadMatrix(new MemoryStream(Encoding.UTF8.GetBytes(data)));
Assert.AreEqual(3, matrix.RowCount);
Assert.AreEqual(3, matrix.ColumnCount);
@ -73,7 +73,7 @@
""2.2"" 0.3e1
'4' 5 6
";
var reader = new DelimitedReader<DenseMatrix>();
var reader = new DelimitedReader<UserDefinedMatrix>();
var matrix = reader.ReadMatrix(new MemoryStream(Encoding.UTF8.GetBytes(data)));
Assert.AreEqual(3, matrix.RowCount);
Assert.AreEqual(3, matrix.ColumnCount);

90
src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedWriterTests.cs

@ -0,0 +1,90 @@
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.IO
{
using System;
using System.Globalization;
using System.IO;
using System.Text;
using LinearAlgebra.Double;
using LinearAlgebra.Double.IO;
using MbUnit.Framework;
[TestFixture]
public class DelimitedWriterTests
{
[Test]
public void CanWriteCommaDelimitedData()
{
var matrix = new DenseMatrix(new[,] { { 1.1, 2.2, 3.3 }, { 4.4, 5.5, 6.6 }, { 7.7, 8.8, 9.9 } });
var writer = new DelimitedWriter(',');
var stream = new MemoryStream();
writer.WriteMatrix(matrix, stream);
var data = stream.ToArray();
var reader = new StreamReader(new MemoryStream(data));
var text = reader.ReadToEnd();
const string expected = @"1.1,2.2,3.3
4.4,5.5,6.6
7.7,8.8,9.9";
Assert.AreEqual(expected, text);
}
[Test]
public void CanWritePeriodDelimitedData()
{
var matrix = new DenseMatrix(new[,] { { 1.1, 2.2, 3.3 }, { 4.4, 5.5, 6.6 }, { 7.7, 8.8, 9.9 } });
var culture = new CultureInfo("tr-TR");
var writer = new DelimitedWriter('.')
{
CultureInfo = culture
};
var stream = new MemoryStream();
writer.WriteMatrix(matrix, stream);
var data = stream.ToArray();
var reader = new StreamReader(new MemoryStream(data));
var text = reader.ReadToEnd();
const string expected = @"1,1.2,2.3,3
4,4.5,5.6,6
7,7.8,8.9,9";
Assert.AreEqual(expected, text);
}
[Test]
public void CanWriteSpaceDelimitedData()
{
var matrix = new SparseMatrix(new[,] { { 1.1, 0, 0 }, { 0, 5.5, 0 }, { 0, 0, 9.9 } });
var writer = new DelimitedWriter(' ');
var stream = new MemoryStream();
writer.WriteMatrix(matrix, stream);
var data = stream.ToArray();
var reader = new StreamReader(new MemoryStream(data));
var text = reader.ReadToEnd();
const string expected = @"1.1 0 0
0 5.5 0
0 0 9.9";
Assert.AreEqual(expected, text);
}
[Test]
public void CanWriteTabDelimitedData()
{
var matrix = new UserDefinedMatrix(new[,] { { 1.1, 2.2, 3.3 }, { 4.4, 5.5, 6.6 }, { 7.7, 8.8, 9.9 } });
var headers = new[] { "a", "b", "c" };
var writer = new DelimitedWriter('\t')
{
ColumnHeaders = headers
};
var stream = new MemoryStream();
writer.WriteMatrix(matrix, stream);
var data = stream.ToArray();
var reader = new StreamReader(new MemoryStream(data));
var text = reader.ReadToEnd();
var expected = "a\tb\tc"
+ Environment.NewLine
+ "1.1\t2.2\t3.3"
+ Environment.NewLine
+ "4.4\t5.5\t6.6"
+ Environment.NewLine
+ "7.7\t8.8\t9.9";
Assert.AreEqual(expected, text);
}
}
}

1
src/UnitTests/UnitTests.csproj

@ -96,6 +96,7 @@
<Compile Include="LinearAlgebraTests\Double\Factorization\UserSvdTests.cs" />
<Compile Include="LinearAlgebraTests\Double\Factorization\SvdTests.cs" />
<Compile Include="LinearAlgebraTests\Double\Factorization\QRTests.cs" />
<Compile Include="LinearAlgebraTests\Double\IO\DelimitedWriterTests.cs" />
<Compile Include="LinearAlgebraTests\Double\IO\DelimitedReaderTests.cs" />
<Compile Include="LinearAlgebraTests\Double\SparseMatrixTests.cs" />
<Compile Include="PermutationTest.cs" />

Loading…
Cancel
Save