diff --git a/src/Numerics/LinearAlgebra/Double/IO/DelimitedWriter.cs b/src/Numerics/LinearAlgebra/Double/IO/DelimitedWriter.cs
new file mode 100644
index 00000000..d39186db
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Double/IO/DelimitedWriter.cs
@@ -0,0 +1,167 @@
+//
+// 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.
+//
+
+namespace MathNet.Numerics.LinearAlgebra.Double.IO
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.IO;
+
+ ///
+ /// Writes an to delimited text file. If the user does not
+ /// specify a delimiter, a tab separator is used.
+ ///
+ public class DelimitedWriter : MatrixWriter
+ {
+ ///
+ /// The delimiter to use.
+ ///
+ private readonly string _delimiter;
+
+ ///
+ /// The to use.
+ ///
+ private CultureInfo _cultureInfo = CultureInfo.CurrentCulture;
+
+ ///
+ /// Initializes a new instance of the class using
+ /// a comma as the delimiter.
+ ///
+ public DelimitedWriter()
+ {
+ _delimiter = ",";
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// using the given delimiter.
+ ///
+ ///
+ /// the delimiter to use.
+ ///
+ public DelimitedWriter(char delimiter)
+ {
+ _delimiter = new string(delimiter, 1);
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// using the given delimiter.
+ ///
+ ///
+ /// the delimiter to use.
+ ///
+ public DelimitedWriter(string delimiter)
+ {
+ _delimiter = delimiter;
+ }
+
+ ///
+ /// Gets or sets the column header values.
+ ///
+ /// The column header values.
+ /// Will write the column headers if the list is not empty or null.
+ public IList ColumnHeaders
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets or sets the to use when parsing the numbers.
+ ///
+ /// The culture info.
+ /// Defaults to CultureInfo.CurrentCulture.
+ public CultureInfo CultureInfo
+ {
+ get
+ {
+ return _cultureInfo;
+ }
+
+ set
+ {
+ if (value != null)
+ {
+ _cultureInfo = value;
+ }
+ }
+ }
+
+ ///
+ /// Writes the given to the given .
+ ///
+ /// The matrix to write.
+ /// The to write the matrix to.
+ /// The format to use on each element.
+ /// If either or is null.
+ 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);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/Double/IO/MatrixWriter.cs b/src/Numerics/LinearAlgebra/Double/IO/MatrixWriter.cs
new file mode 100644
index 00000000..8fb2c744
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Double/IO/MatrixWriter.cs
@@ -0,0 +1,195 @@
+//
+// 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.
+//
+
+using System;
+using System.IO;
+
+namespace MathNet.Numerics.LinearAlgebra.Double.IO
+{
+ ///
+ /// Base class to write a single to a file or stream.
+ ///
+ public abstract class MatrixWriter
+ {
+ ///
+ /// Writes the given to the given file. If the file already exists,
+ /// the file will be overwritten.
+ ///
+ /// The matrix to write.
+ /// The file to write the matrix to.
+ /// If either or is null.
+ 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);
+ }
+ }
+
+ ///
+ /// Writes the given to the given file. If the file already exists,
+ /// the file will be overwritten.
+ ///
+ /// the matrix to write.
+ /// The file to write the matrix to.
+ /// The format to use on each element.
+ /// If either or is null.
+ 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);
+ }
+ }
+
+ ///
+ /// Writes the given to the given stream.
+ ///
+ /// The matrix to write.
+ /// The to write the matrix to.
+ /// If either or is null.
+ 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);
+ }
+ }
+
+ ///
+ /// Writes the given to the given stream.
+ ///
+ /// The to write.
+ /// The to write the matrix to.
+ /// The format to use on each element.
+ /// If either or is null.
+ 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);
+ }
+ }
+
+ ///
+ /// Writes the given to the given .
+ ///
+ /// The matrix to write.
+ /// The to write the matrix to.
+ /// If either or is null.
+ 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);
+ }
+
+ ///
+ /// Writes the given to the given .
+ ///
+ /// The matrix to write.
+ /// The to write the matrix to.
+ /// The format to use on each element.
+ /// If either or is null.
+ 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);
+ }
+
+ ///
+ /// Subclasses must implement this method to do the actually writing.
+ ///
+ /// The matrix to serialize.
+ /// The to write the matrix to.
+ /// The format for the new matrix.
+ protected abstract void DoWriteMatrix(Matrix matrix, TextWriter writer, string format);
+ }
+}
diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj
index f3d49068..590991ef 100644
--- a/src/Numerics/Numerics.csproj
+++ b/src/Numerics/Numerics.csproj
@@ -108,7 +108,9 @@
+
+
diff --git a/src/Silverlight/Silverlight.csproj b/src/Silverlight/Silverlight.csproj
index 799928f7..7a5771eb 100644
--- a/src/Silverlight/Silverlight.csproj
+++ b/src/Silverlight/Silverlight.csproj
@@ -263,9 +263,15 @@
LinearAlgebra\Double\IO\DelimitedReader.cs
+
+ LinearAlgebra\Double\IO\DelimitedWriter.cs
+
LinearAlgebra\Double\IO\MatrixReader.cs
+
+ LinearAlgebra\Double\IO\MatrixWriter.cs
+
LinearAlgebra\Double\ISolver.cs
diff --git a/src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedReaderTests.cs b/src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedReaderTests.cs
index aeb92213..b4abab62 100644
--- a/src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedReaderTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedReaderTests.cs
@@ -49,7 +49,7 @@
+ Environment.NewLine
+ "'4'\t5\t6";
- var reader = new DelimitedReader('\t');
+ var reader = new DelimitedReader('\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();
+ var reader = new DelimitedReader();
var matrix = reader.ReadMatrix(new MemoryStream(Encoding.UTF8.GetBytes(data)));
Assert.AreEqual(3, matrix.RowCount);
Assert.AreEqual(3, matrix.ColumnCount);
diff --git a/src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedWriterTests.cs b/src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedWriterTests.cs
new file mode 100644
index 00000000..1dc493c6
--- /dev/null
+++ b/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);
+ }
+ }
+}
diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj
index e25bc83d..d266f694 100644
--- a/src/UnitTests/UnitTests.csproj
+++ b/src/UnitTests/UnitTests.csproj
@@ -96,6 +96,7 @@
+