diff --git a/src/Numerics/LinearAlgebra/Double/IO/DelimitedReader.cs b/src/Numerics/LinearAlgebra/Double/IO/DelimitedReader.cs new file mode 100644 index 00000000..3f923adf --- /dev/null +++ b/src/Numerics/LinearAlgebra/Double/IO/DelimitedReader.cs @@ -0,0 +1,196 @@ +// +// 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; + using System.Reflection; + using System.Text.RegularExpressions; + + /// + /// Creates a from a delimited text file. If the user does not + /// specify a delimiter, then any whitespace is used. + /// + /// The type of the matrix to return. + public class DelimitedReader : MatrixReader + where TMatrix : Matrix + { + /// + /// Constructor to create matrix instance. + /// + private static readonly ConstructorInfo Constructor = typeof(TMatrix).GetConstructor(new[] { typeof(int), typeof(int) }); + + /// + /// Whitespace regular expression. + /// + private static readonly Regex WhiteSpace = new Regex(@"[\s]+"); + + /// + /// The delimiter to use. + /// + private readonly Regex _delimiter; + + /// + /// The to use. + /// + private CultureInfo _cultureInfo = CultureInfo.CurrentCulture; + + /// + /// Initializes a new instance of the class using + /// any whitespace as the delimiter. + /// + public DelimitedReader() + { + _delimiter = WhiteSpace; + } + + /// + /// Initializes a new instance of the class. + /// + /// The delimiter to use. + public DelimitedReader(char delimiter) + { + _delimiter = new Regex("[" + new string(delimiter, 1) + "]+"); + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// The delimiter to use. + /// + /// + /// If is . + /// + public DelimitedReader(string delimiter) + { + if (delimiter == null) + { + throw new ArgumentNullException("delimiter"); + } + + _delimiter = new Regex("[" + delimiter + "]+"); + } + + /// + /// 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; + } + } + } + + /// + /// Gets or sets a value indicating whether the files has a header row. + /// + /// + /// true if this instance has a header row; otherwise, false. + /// + /// Defaults to . + public bool HasHeaderRow + { + get; + set; + } + + /// + /// Performs the actual reading. + /// + /// The to read the matrix from. + /// + /// A matrix containing the data from the . is returned if the is empty. + /// + protected override TMatrix DoReadMatrix(Stream stream) + { + var data = new List(); + + // max is used to supports files like: + // 1,2 + // 3,4,5,6 + // 7 + // this creates a 3x4 matrix: + // 1, 2, 0 ,0 + // 3, 4, 5, 6 + // 7, 0, 0, 0 + var max = -1; + var reader = new StreamReader(stream); + var line = reader.ReadLine(); + if (HasHeaderRow) + { + line = reader.ReadLine(); + } + + while (line != null) + { + line = line.Trim(); + if (line.Length > 0) + { + var row = _delimiter.Split(line); + max = Math.Max(max, row.Length); + data.Add(row); + } + + line = reader.ReadLine(); + } + + var ret = (TMatrix)Constructor.Invoke(new object[] { data.Count, max }); + + if (data.Count != 0) + { + for (var i = 0; i < data.Count; i++) + { + var row = data[i]; + for (var j = 0; j < row.Length; j++) + { + // strip off quotes + var value = row[j].Replace("'", string.Empty).Replace("\"", string.Empty); + ret[i, j] = double.Parse(value, NumberStyles.Any, _cultureInfo); + } + } + } + + reader.Close(); + reader.Dispose(); + return ret; + } + } +} diff --git a/src/Numerics/LinearAlgebra/Double/IO/MatrixReader.cs b/src/Numerics/LinearAlgebra/Double/IO/MatrixReader.cs new file mode 100644 index 00000000..aa1e6d80 --- /dev/null +++ b/src/Numerics/LinearAlgebra/Double/IO/MatrixReader.cs @@ -0,0 +1,83 @@ +// +// 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.IO; + using Properties; + + /// + /// Base class to read a single from a file or stream. + /// + /// The type of Matrix to return. + public abstract class MatrixReader where TMatrix : Matrix + { + /// + /// Reads a from a file. + /// + /// The file to read the matrix from. + /// A containing the data from the file. is returned if the file is empty. + /// If is . + /// If the file doesn't exist. + /// If a value is not a number or not in a valid format. + /// If a value represents a number less than or greater than . + public Matrix ReadMatrix(string file) + { + if (file == null) + { + throw new ArgumentNullException("file", Resources.StringNullOrEmpty); + } + + return ReadMatrix(File.OpenRead(file)); + } + + /// + /// Reads a from a . + /// + /// The to read the matrix from. + /// A matrix containing the data from the . is returned if the is empty. + /// If is . + /// If a value is not a number or not in a valid format. + /// If a value represents a number less than or greater than . + public TMatrix ReadMatrix(Stream stream) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + return DoReadMatrix(stream); + } + + /// + /// Subclasses override this method to do the actual reading. + /// + /// The to read the matrix from. + /// A matrix containing the data from the . is returned if the is empty. + protected abstract TMatrix DoReadMatrix(Stream stream); + } +} diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index 7c7ac1fc..f3d49068 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -107,6 +107,8 @@ + + @@ -264,9 +266,7 @@ true - - - +