Browse Source

matlab: first take at then new matlab parser, still needs work

pull/36/head
Marcus Cuda 16 years ago
parent
commit
ffa9f92a06
  1. 6
      src/MathNet.Numerics.5.1.ReSharper
  2. 70
      src/Numerics/LinearAlgebra/Complex/IO/DelimitedWriter.cs
  3. 53
      src/Numerics/LinearAlgebra/Complex/IO/MatlabReader.cs
  4. 70
      src/Numerics/LinearAlgebra/Complex32/IO/DelimitedWriter.cs
  5. 53
      src/Numerics/LinearAlgebra/Complex32/IO/MatlabReader.cs
  6. 70
      src/Numerics/LinearAlgebra/Double/IO/DelimitedWriter.cs
  7. 219
      src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabFile.cs
  8. 536
      src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabParser.cs
  9. 145
      src/Numerics/LinearAlgebra/Double/IO/MatlabReader.cs
  10. 2
      src/Numerics/LinearAlgebra/IO/Matlab/ArrayClass.cs
  11. 2
      src/Numerics/LinearAlgebra/IO/Matlab/ArrayFlags.cs
  12. 2
      src/Numerics/LinearAlgebra/IO/Matlab/DataType.cs
  13. 84
      src/Numerics/LinearAlgebra/IO/Matlab/MatlabFile.cs
  14. 1534
      src/Numerics/LinearAlgebra/IO/Matlab/MatlabParser.cs
  15. 192
      src/Numerics/LinearAlgebra/IO/MatlabReader.cs
  16. 70
      src/Numerics/LinearAlgebra/Single/IO/DelimitedWriter.cs
  17. 219
      src/Numerics/LinearAlgebra/Single/IO/Matlab/MatlabFile.cs
  18. 536
      src/Numerics/LinearAlgebra/Single/IO/Matlab/MatlabParser.cs
  19. 145
      src/Numerics/LinearAlgebra/Single/IO/MatlabReader.cs
  20. 19
      src/Numerics/Numerics.csproj
  21. 10
      src/UnitTests/LinearAlgebraTests/Complex/IO/DelimitedWriterTests.cs
  22. 70
      src/UnitTests/LinearAlgebraTests/Complex/IO/MatlabReaderTests.cs
  23. 10
      src/UnitTests/LinearAlgebraTests/Complex32/IO/DelimitedWriterTests.cs
  24. 70
      src/UnitTests/LinearAlgebraTests/Complex32/IO/MatlabReaderTests.cs
  25. 10
      src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedWriterTests.cs
  26. 10
      src/UnitTests/LinearAlgebraTests/Single/IO/DelimitedWriterTests.cs
  27. 2
      src/UnitTests/UnitTests.csproj

6
src/MathNet.Numerics.5.1.ReSharper

@ -14,7 +14,11 @@
Wikipedia
Marsaglia
Xorshift
λ</UserWords>
λ
Matlab
Matlab
Matlab
Endian</UserWords>
</CustomDictionary>
</Dictionaries>
</CustomDictionaries>

70
src/Numerics/LinearAlgebra/Complex/IO/DelimitedWriter.cs

@ -0,0 +1,70 @@
// <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.Complex.IO
{
using Generic;
using LinearAlgebra.IO;
/// <summary>
/// Writes an <see cref="Matrix{TDataType}"/> to delimited text file. If the user does not
/// specify a delimiter, a tab separator is used.
/// </summary>
public class DelimitedWriter : DelimitedWriter<System.Numerics.Complex>
{
/// <summary>
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
/// a comma as the delimiter.
/// </summary>
public DelimitedWriter()
{
}
/// <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) : base(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(string delimiter) : base(delimiter)
{
}
}
}

53
src/Numerics/LinearAlgebra/Complex/IO/MatlabReader.cs

@ -0,0 +1,53 @@
// <copyright file="MatlabReader.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.Complex.IO
{
using System.IO;
using LinearAlgebra.IO;
/// <summary>
/// Creates matrices from Matlab files.
/// </summary>
public class MatlabMatrixReader : MatlabMatrixReader<System.Numerics.Complex>
{
/// <summary>
/// Initializes a new instance of the <see cref="MatlabMatrixReader"/> class.
/// </summary>
/// <param name="filename">Name of the file to read matrices from.</param>
public MatlabMatrixReader(string filename) : base(filename)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MatlabMatrixReader"/> class.
/// </summary>
/// <param name="stream">The stream to reader matrices from.</param>
public MatlabMatrixReader(Stream stream) : base(stream)
{
}
}
}

70
src/Numerics/LinearAlgebra/Complex32/IO/DelimitedWriter.cs

@ -0,0 +1,70 @@
// <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.Complex32.IO
{
using Generic;
using LinearAlgebra.IO;
/// <summary>
/// Writes an <see cref="Matrix{TDataType}"/> to delimited text file. If the user does not
/// specify a delimiter, a tab separator is used.
/// </summary>
public class DelimitedWriter : DelimitedWriter<Numerics.Complex32>
{
/// <summary>
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
/// a comma as the delimiter.
/// </summary>
public DelimitedWriter()
{
}
/// <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) : base(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(string delimiter) : base(delimiter)
{
}
}
}

53
src/Numerics/LinearAlgebra/Complex32/IO/MatlabReader.cs

@ -0,0 +1,53 @@
// <copyright file="MatlabReader.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.Complex32.IO
{
using System.IO;
using LinearAlgebra.IO;
/// <summary>
/// Creates matrices from Matlab files.
/// </summary>
public class MatlabMatrixReader : MatlabMatrixReader<Numerics.Complex32>
{
/// <summary>
/// Initializes a new instance of the <see cref="MatlabMatrixReader"/> class.
/// </summary>
/// <param name="filename">Name of the file to read matrices from.</param>
public MatlabMatrixReader(string filename) : base(filename)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MatlabMatrixReader"/> class.
/// </summary>
/// <param name="stream">The stream to reader matrices from.</param>
public MatlabMatrixReader(Stream stream) : base(stream)
{
}
}
}

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

@ -0,0 +1,70 @@
// <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 Generic;
using LinearAlgebra.IO;
/// <summary>
/// Writes an <see cref="Matrix{TDataType}"/> to delimited text file. If the user does not
/// specify a delimiter, a tab separator is used.
/// </summary>
public class DelimitedWriter : DelimitedWriter<double>
{
/// <summary>
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
/// a comma as the delimiter.
/// </summary>
public DelimitedWriter()
{
}
/// <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) : base(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(string delimiter) : base(delimiter)
{
}
}
}

219
src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabFile.cs

@ -1,219 +0,0 @@
// <copyright file="MatlabFile.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.Matlab
{
using System.Collections.Generic;
using Generic;
/// <summary>
/// Represents a Matlab file
/// </summary>
internal class MatlabFile
{
/// <summary>
/// Matrices in a matlab file stored as 1-D arrays
/// </summary>
private readonly IDictionary<string, Matrix<double>> _matrices = new SortedList<string, Matrix<double>>();
/// <summary>
/// Gets or sets the header text.
/// </summary>
/// <value>The header text.</value>
public string HeaderText { get; set; }
/// <summary>
/// Gets or sets the first name of the matrix.
/// </summary>
/// <value>The first name of the matrix.</value>
public string FirstMatrixName { get; set; }
/// <summary>
/// Gets the first matrix.
/// </summary>
/// <value>The first matrix.</value>
public Matrix<double> FirstMatrix
{
get
{
if (string.IsNullOrEmpty(FirstMatrixName) || !_matrices.ContainsKey(FirstMatrixName))
{
return null;
}
return _matrices[FirstMatrixName];
}
}
/// <summary>
/// Gets the matrices.
/// </summary>
/// <value>The matrices.</value>
public IDictionary<string, Matrix<double>> Matrices
{
get { return _matrices; }
}
}
/*
/// <summary>
/// An
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="K"></typeparam>
internal class ListDictionary<T, K> : IDictionary<T, K>
{
private readonly IList<T> _keys = new List<T>();
private readonly IList<K> _values = new List<K>();
public void Add(T key, K value)
{
_keys.Add(key);
_values.Add(value);
}
public bool ContainsKey(T key)
{
return _keys.Contains(key);
}
public ICollection<T> Keys
{
get { return _keys; }
}
public bool Remove(T key)
{
if (_keys.Contains(key))
{
int pos = _keys.IndexOf(key);
_values.RemoveAt(pos);
_values.RemoveAt(pos);
return true;
}
return false;
}
public bool TryGetValue(T key, out K value)
{
if (_keys.Contains(key))
{
value = _values[_keys.IndexOf(key)];
return true;
}
value = default(K);
return false;
}
public ICollection<K> Values
{
get { return _values; }
}
public K this[T key]
{
get
{
if (_keys.Contains(key))
{
return _values[_keys.IndexOf(key)];
}
throw new KeyNotFoundException();
}
set
{
if (_keys.Contains(key))
{
_values[_keys.IndexOf(key)] = value;
}
else
{
Add(key, value);
}
}
}
public void Add(KeyValuePair<T, K> item)
{
Add(item.Key, item.Value);
}
public void Clear()
{
_keys.Clear();
_values.Clear();
}
public bool Contains(KeyValuePair<T, K> item)
{
return _keys.Contains(item.Key) && _values[_keys.IndexOf(item.Key)].Equals(item.Value);
}
public void CopyTo(KeyValuePair<T, K>[] array, int arrayIndex)
{
for (int i = 0; i < _keys.Count; i++)
{
array[arrayIndex + i] = new KeyValuePair<T, K>(_keys[i], _values[i]);
}
}
public int Count
{
get { return _keys.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(KeyValuePair<T, K> item)
{
if (Contains(item))
{
Remove(item.Key);
return true;
}
return false;
}
public IEnumerator<KeyValuePair<T, K>> GetEnumerator()
{
for (int i = 0; i < _keys.Count; i++)
{
yield return new KeyValuePair<T, K>(_keys[i], _values[i]);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}*/
}

536
src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabParser.cs

@ -1,536 +0,0 @@
// <copyright file="MatlabParser.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.Matlab
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Common.IO.Matlab;
using Generic;
using Properties;
using zlib;
/// <summary>
/// Parse a Matlab file
/// </summary>
internal class MatlabParser
{
/// <summary>
/// Large Block Size
/// </summary>
private const int LargeBlockSize = 8;
/// <summary>
/// Little Endian Indicator
/// </summary>
private const byte LittleEndianIndicator = 0x49;
/// <summary>
/// Small Block Size
/// </summary>
private const int SmallBlockSize = 4;
/// <summary>
/// Holds the names of the matrices in the file.
/// </summary>
private readonly IList<string> _names = new List<string>();
/// <summary>
/// The stream to read the matlab file from.
/// </summary>
private readonly Stream _stream;
/// <summary>
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
/// </summary>
/// <param name="fileName">Name of the file.</param>
public MatlabParser(string fileName)
: this(fileName, new string[0])
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
/// </summary>
/// <param name="stream">The stream to read from.</param>
public MatlabParser(Stream stream)
: this(stream, new string[0])
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
/// </summary>
/// <param name="stream">The stream to read from.</param>
/// <param name="objectNames">The name of the objects to retrieve.</param>
public MatlabParser(Stream stream, IEnumerable<string> objectNames)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
_stream = stream;
SetNames(objectNames);
}
/// <summary>
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <param name="objectNames">The name of the objects to retrieve.</param>
public MatlabParser(string fileName, IEnumerable<string> objectNames)
{
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentException(Resources.StringNullOrEmpty, "filename");
}
_stream = File.OpenRead(fileName);
SetNames(objectNames);
}
/// <summary>
/// Copies the names of the objects to retrieve to a local field.
/// </summary>
/// <param name="objectNames">The name of the objects to retrieve.</param>
private void SetNames(IEnumerable<string> objectNames)
{
foreach (var name in objectNames)
{
_names.Add(name);
}
}
/// <summary>
/// Parses the file.
/// </summary>
/// <returns>The parsed Matlab file as a <see cref="MatlabFile"/> object.</returns>
public MatlabFile Parse()
{
var file = new MatlabFile();
using (var reader = new BinaryReader(_stream))
{
file.HeaderText = Encoding.ASCII.GetString(reader.ReadBytes(116));
// skipping subsystem offsets
reader.BaseStream.Position = 126;
if (reader.ReadByte() != LittleEndianIndicator)
{
throw new NotSupportedException(Resources.BigEndianNotSupported);
}
// skip version since it is always 0x0100.
reader.BaseStream.Position = 128;
var length = _stream.Length;
// for each data block add a matlab object to the file.
while (reader.BaseStream.Position < length)
{
var type = (DataType)reader.ReadInt16();
int size = reader.ReadInt16();
var smallBlock = true;
if (size == 0)
{
size = reader.ReadInt32();
smallBlock = false;
}
byte[] data;
if (type == DataType.Compressed)
{
data = DecompressBlock(reader.ReadBytes(size), ref type);
}
else
{
data = new byte[size];
reader.Read(data, 0, size);
AlignData(reader.BaseStream, size, smallBlock);
}
if (type == DataType.Matrix)
{
AddMatrix(data, file);
}
else
{
throw new NotSupportedException(string.Format(Resources.NotSupportedType, type));
}
}
}
return file;
}
/// <summary>
/// Aligns the data.
/// </summary>
/// <param name="stream">The stream.</param>
/// <param name="size">The size of the array.</param>
/// <param name="smallBlock">if set to <c>true</c> if reading from a small block.</param>
private static void AlignData(Stream stream, int size, bool smallBlock)
{
var blockSize = smallBlock ? SmallBlockSize : LargeBlockSize;
var offset = 0;
var mod = size % blockSize;
if (mod != 0)
{
offset = blockSize - mod;
}
stream.Seek(offset, SeekOrigin.Current);
}
/// <summary>
/// Decompresses the block.
/// </summary>
/// <param name="compressed">The compressed data.</param>
/// <param name="type">The type data type contained in the block.</param>
/// <returns>The decompressed block.</returns>
private static byte[] DecompressBlock(byte[] compressed, ref DataType type)
{
byte[] data;
using (var decompressed = new MemoryStream())
{
using (var decompressor = new ZOutputStream(decompressed))
{
decompressor.Write(compressed, 0, compressed.Length);
decompressed.Position = 0;
var buf = new byte[4];
decompressed.Read(buf, 0, 4);
type = (DataType)BitConverter.ToInt32(buf, 0);
decompressed.Read(buf, 0, 4);
var size = BitConverter.ToInt32(buf, 0);
data = new byte[size];
decompressed.Read(data, 0, size);
}
}
return data;
}
/// <summary>
/// Adds a matrix from the actual file into our presentation of a matlab file.
/// </summary>
/// <param name="data">The data of the matrix.</param>
/// <param name="file">The <see cref="MatlabFile"/> instance.</param>
private void AddMatrix(byte[] data, MatlabFile file)
{
using (var ms = new MemoryStream(data))
{
using (var reader = new BinaryReader(ms))
{
// skip tag - doesn't tell us anything we don't already know
reader.BaseStream.Seek(8, SeekOrigin.Current);
var arrayClass = (ArrayClass)reader.ReadByte();
var flags = reader.ReadByte();
var isComplex = (flags & (byte)ArrayFlags.Complex) == (byte)ArrayFlags.Complex;
if (isComplex)
{
throw new NotSupportedException(Resources.ComplexMatricesNotSupported);
}
// skip unneeded bytes
reader.BaseStream.Seek(10, SeekOrigin.Current);
var numDimensions = reader.ReadInt32() / 8;
if (numDimensions > 2)
{
throw new NotSupportedException(Resources.MoreThan2D);
}
var rows = reader.ReadInt32();
var columns = reader.ReadInt32();
// skip unneeded bytes
reader.BaseStream.Seek(2, SeekOrigin.Current);
int size = reader.ReadInt16();
var smallBlock = true;
if (size == 0)
{
size = reader.ReadInt32();
smallBlock = false;
}
var name = Encoding.ASCII.GetString(reader.ReadBytes(size));
AlignData(reader.BaseStream, size, smallBlock);
// only grab wanted objects
if (_names.Count != 0 && !_names.Contains(name))
{
return;
}
var type = (DataType)reader.ReadInt16();
size = reader.ReadInt16();
if (size == 0)
{
size = reader.ReadInt32();
}
Matrix<double> matrix;
switch (arrayClass)
{
case ArrayClass.Sparse:
matrix = PopulateSparseMatrix(reader, rows, columns, size);
break;
case ArrayClass.Function:
case ArrayClass.Character:
case ArrayClass.Object:
case ArrayClass.Structure:
case ArrayClass.Cell:
case ArrayClass.Unknown:
throw new NotImplementedException();
default:
matrix = PopulateDenseMatrix(type, reader, rows, columns);
break;
}
file.Matrices.Add(name, matrix);
if (file.FirstMatrixName == null)
{
file.FirstMatrixName = name;
}
}
}
}
/// <summary>
/// Populates a sparse matrix.
/// </summary>
/// <param name="reader">The reader.</param>
/// <param name="rows">The number of rows.</param>
/// <param name="columns">The number of columns.</param>
/// <param name="size">The size of the block.</param>
/// <returns>A populated sparse matrix.</returns>
private static Matrix<double> PopulateSparseMatrix(BinaryReader reader, int rows, int columns, int size)
{
// populate the row data array
var ir = new int[size / 4];
for (var i = 0; i < ir.Length; i++)
{
ir[i] = reader.ReadInt32();
}
AlignData(reader.BaseStream, size, false);
// skip data type since it will always be int32
reader.BaseStream.Seek(4, SeekOrigin.Current);
// populate the column data array
var jcsize = reader.ReadInt32();
var jc = new int[jcsize / 4];
for (var j = 0; j < jc.Length; j++)
{
jc[j] = reader.ReadInt32();
}
AlignData(reader.BaseStream, jcsize, false);
var type = (DataType)reader.ReadInt32();
// skip length since we already no it for the number of rows
reader.BaseStream.Seek(4, SeekOrigin.Current);
Matrix<double> matrix = new SparseMatrix(rows, columns);
var col = 0;
for (var i = 0; i < ir.Length; i++)
{
var row = ir[i];
if (jc[col + 1] == i)
{
col++;
}
switch (type)
{
case DataType.Int8:
matrix[row, col] = reader.ReadSByte();
break;
case DataType.UInt8:
matrix[row, col] = reader.ReadByte();
break;
case DataType.Int16:
matrix[row, col] = reader.ReadInt16();
break;
case DataType.UInt16:
matrix[row, col] = reader.ReadUInt16();
break;
case DataType.Int32:
matrix[row, col] = reader.ReadInt32();
break;
case DataType.UInt32:
matrix[row, col] = reader.ReadUInt32();
break;
case DataType.Single:
matrix[row, col] = reader.ReadSingle();
break;
case DataType.Int64:
matrix[row, col] = reader.ReadInt64();
break;
case DataType.UInt64:
matrix[row, col] = reader.ReadUInt64();
break;
case DataType.Double:
matrix[row, col] = reader.ReadDouble();
break;
default:
throw new NotSupportedException();
}
}
return matrix;
}
/// <summary>
/// Populates a dense matrix.
/// </summary>
/// <param name="type">The type of data.</param>
/// <param name="reader">The reader.</param>
/// <param name="rows">The number of rows.</param>
/// <param name="columns">The number of columns.</param>
/// <returns>Returns a populated dense matrix.</returns>
private static Matrix<double> PopulateDenseMatrix(DataType type, BinaryReader reader, int rows, int columns)
{
Matrix<double> matrix = new DenseMatrix(rows, columns);
switch (type)
{
case DataType.Int8:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadSByte();
}
}
break;
case DataType.UInt8:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadByte();
}
}
break;
case DataType.Int16:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadInt16();
}
}
break;
case DataType.UInt16:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadUInt16();
}
}
break;
case DataType.Int32:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadInt32();
}
}
break;
case DataType.UInt32:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadUInt32();
}
}
break;
case DataType.Single:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadSingle();
}
}
break;
case DataType.Int64:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadInt64();
}
}
break;
case DataType.UInt64:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadUInt64();
}
}
break;
case DataType.Double:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadDouble();
}
}
break;
default:
throw new NotSupportedException();
}
return matrix;
}
}
}

145
src/Numerics/LinearAlgebra/Double/IO/MatlabReader.cs

@ -3,9 +3,7 @@
// 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
@ -28,163 +26,28 @@
namespace MathNet.Numerics.LinearAlgebra.Double.IO
{
using System;
using System.Collections.Generic;
using System.IO;
using Generic;
using Matlab;
using Properties;
using LinearAlgebra.IO;
/// <summary>
/// Creates matrices from Matlab files.
/// </summary>
public class MatlabMatrixReader
public class MatlabMatrixReader : MatlabMatrixReader<double>
{
/// <summary>
/// The name of the file to read from.
/// </summary>
private readonly string _filename;
/// <summary>
/// The stream to read from if we are not reading from a file directly.
/// </summary>
private readonly Stream _stream;
/// <summary>
/// Initializes a new instance of the <see cref="MatlabMatrixReader"/> class.
/// </summary>
/// <param name="filename">Name of the file to read matrices from.</param>
public MatlabMatrixReader(string filename)
public MatlabMatrixReader(string filename) : base(filename)
{
if (string.IsNullOrEmpty(filename))
{
throw new ArgumentException(Resources.StringNullOrEmpty, "filename");
}
if (!File.Exists(filename))
{
throw new FileNotFoundException(Resources.FileDoesNotExist, "filename");
}
_filename = filename;
}
/// <summary>
/// Initializes a new instance of the <see cref="MatlabMatrixReader"/> class.
/// </summary>
/// <param name="stream">The stream to reader matrices from.</param>
public MatlabMatrixReader(Stream stream)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
_stream = stream;
}
/// <summary>
/// Reads the first matrix from the file or stream.
/// </summary>
/// <returns>
/// If the matrix is stored as a sparse matrix, then a <see cref="SparseMatrix"/> is returned. Otherwise, a <see cref="DenseMatrix"/>
/// is returned.
/// </returns>
public Matrix<double> ReadMatrix()
{
return ReadMatrix(null);
}
/// <summary>
/// Reads the named matrix from the file or stream.
/// </summary>
/// <param name="matrixName">The name of the matrix to read.</param>
/// <returns>
/// If the matrix is stored as a sparse matrix, then a <see cref="SparseMatrix"/> is returned. Otherwise, a <see cref="DenseMatrix"/>
/// is returned. <see langword="null"/> is returned if a matrix with the requests name doesn't exist.
/// </returns>
public Matrix<double> ReadMatrix(string matrixName)
public MatlabMatrixReader(Stream stream) : base(stream)
{
Stream stream;
if (_filename == null)
{
stream = _stream;
_stream.Seek(0, SeekOrigin.Begin);
}
else
{
stream = new FileStream(_filename, FileMode.Open, FileAccess.Read);
}
var names = string.IsNullOrEmpty(matrixName) ? new string[] { } : new[] { matrixName };
var parser = new MatlabParser(stream, names);
var file = parser.Parse();
Matrix<double> matrix = null;
if (string.IsNullOrEmpty(matrixName))
{
matrix = file.FirstMatrix;
}
else if (file.Matrices.ContainsKey(matrixName))
{
matrix = file.Matrices[matrixName];
}
if (_filename != null)
{
stream.Close();
stream.Dispose();
}
return matrix;
}
/// <summary>
/// Reads all matrices from the file or stream.
/// </summary>
/// <returns>All matrices from the file or stream.</returns>
public Matrix<double>[] ReadMatrices()
{
return ReadMatrices(new string[] { });
}
/// <summary>
/// Reads the named matrices from the file or stream.
/// </summary>
/// <param name="names">The names of the matrices to retrieve.</param>
/// <returns>
/// The named matrices from the file or stream.
/// </returns>
public Matrix<double>[] ReadMatrices(IEnumerable<string> names)
{
Stream stream;
if (_filename == null)
{
stream = _stream;
_stream.Seek(0, SeekOrigin.Begin);
}
else
{
stream = new BufferedStream(new FileStream(_filename, FileMode.Open, FileAccess.Read));
}
var parser = new MatlabParser(stream, names);
var file = parser.Parse();
var matrices = new Matrix<double>[file.Matrices.Count];
var i = 0;
foreach (var matrix in file.Matrices.Values)
{
matrices[i++] = matrix;
}
if (_filename != null)
{
stream.Close();
stream.Dispose();
}
return matrices;
}
}
}

2
src/Numerics/LinearAlgebra/Common/IO/Matlab/ArrayClass.cs → src/Numerics/LinearAlgebra/IO/Matlab/ArrayClass.cs

@ -26,7 +26,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Common.IO.Matlab
namespace MathNet.Numerics.LinearAlgebra.IO.Matlab
{
/// <summary>
/// Enumeration for the Matlab array types

2
src/Numerics/LinearAlgebra/Common/IO/Matlab/ArrayFlags.cs → src/Numerics/LinearAlgebra/IO/Matlab/ArrayFlags.cs

@ -26,7 +26,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Common.IO.Matlab
namespace MathNet.Numerics.LinearAlgebra.IO.Matlab
{
using System;

2
src/Numerics/LinearAlgebra/Common/IO/Matlab/DataType.cs → src/Numerics/LinearAlgebra/IO/Matlab/DataType.cs

@ -26,7 +26,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra.Common.IO.Matlab
namespace MathNet.Numerics.LinearAlgebra.IO.Matlab
{
/// <summary>
/// Matlab data types

84
src/Numerics/LinearAlgebra/IO/Matlab/MatlabFile.cs

@ -0,0 +1,84 @@
// <copyright file="MatlabFile.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.IO.Matlab
{
using System;
using System.Collections.Generic;
using Generic;
/// <summary>
/// Represents a Matlab file
/// </summary>
/// <typeparam name="TDataType">The data type of the matrix to return.</typeparam>
internal class MatlabFile<TDataType> where TDataType : struct, IEquatable<TDataType>, IFormattable
{
/// <summary>
/// Matrices in a matlab file stored as 1-D arrays
/// </summary>
private readonly IDictionary<string, Matrix<TDataType>> _matrices = new SortedList<string, Matrix<TDataType>>();
/// <summary>
/// Gets or sets the header text.
/// </summary>
/// <value>The header text.</value>
public string HeaderText { get; set; }
/// <summary>
/// Gets or sets the first name of the matrix.
/// </summary>
/// <value>The first name of the matrix.</value>
public string FirstMatrixName { get; set; }
/// <summary>
/// Gets the first matrix.
/// </summary>
/// <value>The first matrix.</value>
public Matrix<TDataType> FirstMatrix
{
get
{
if (string.IsNullOrEmpty(FirstMatrixName) || !_matrices.ContainsKey(FirstMatrixName))
{
return null;
}
return _matrices[FirstMatrixName];
}
}
/// <summary>
/// Gets the matrices.
/// </summary>
/// <value>The matrices.</value>
public IDictionary<string, Matrix<TDataType>> Matrices
{
get { return _matrices; }
}
}
}

1534
src/Numerics/LinearAlgebra/IO/Matlab/MatlabParser.cs

File diff suppressed because it is too large

192
src/Numerics/LinearAlgebra/IO/MatlabReader.cs

@ -0,0 +1,192 @@
// <copyright file="MatlabReader.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.IO
{
using System;
using System.Collections.Generic;
using System.IO;
using Generic;
using Matlab;
using Properties;
/// <summary>
/// Creates matrices from Matlab files.
/// </summary>
/// <typeparam name="TDataType">The data type of the Matrix. It can be either: double, float, Complex, or Complex32.</typeparam>
public class MatlabMatrixReader<TDataType> where TDataType : struct, IEquatable<TDataType>, IFormattable
{
/// <summary>
/// The name of the file to read from.
/// </summary>
private readonly string _filename;
/// <summary>
/// The stream to read from if we are not reading from a file directly.
/// </summary>
private readonly Stream _stream;
/// <summary>
/// Initializes a new instance of the <see cref="MatlabMatrixReader{TDataType}"/> class.
/// </summary>
/// <param name="filename">Name of the file to read matrices from.</param>
public MatlabMatrixReader(string filename)
{
if (string.IsNullOrEmpty(filename))
{
throw new ArgumentException(Resources.StringNullOrEmpty, "filename");
}
if (!File.Exists(filename))
{
throw new FileNotFoundException(Resources.FileDoesNotExist, "filename");
}
_filename = filename;
}
/// <summary>
/// Initializes a new instance of the <see cref="MatlabMatrixReader{TDataType}"/> class.
/// </summary>
/// <param name="stream">The stream to reader matrices from.</param>
public MatlabMatrixReader(Stream stream)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
_stream = stream;
}
/// <summary>
/// Reads the first matrix from the file or stream.
/// </summary>
/// <returns>
/// A sparse or dense matrix depending on how the matrix
/// is defined in the Matlab file.
/// </returns>
public Matrix<TDataType> ReadMatrix()
{
return ReadMatrix(null);
}
/// <summary>
/// Reads the named matrix from the file or stream.
/// </summary>
/// <param name="matrixName">The name of the matrix to read.</param>
/// <returns>
/// A sparse or dense matrix depending on how the matrix
/// is defined in the Matlab file.
/// <see langword="null"/> is returned if a matrix with the requests name doesn't exist.
/// </returns>
public Matrix<TDataType> ReadMatrix(string matrixName)
{
Stream stream;
if (_filename == null)
{
stream = _stream;
_stream.Seek(0, SeekOrigin.Begin);
}
else
{
stream = new FileStream(_filename, FileMode.Open, FileAccess.Read);
}
var names = string.IsNullOrEmpty(matrixName) ? new string[] { } : new[] { matrixName };
var parser = new MatlabParser<TDataType>(stream, names);
var file = parser.Parse();
Matrix<TDataType> matrix = null;
if (string.IsNullOrEmpty(matrixName))
{
matrix = file.FirstMatrix;
}
else if (file.Matrices.ContainsKey(matrixName))
{
matrix = file.Matrices[matrixName];
}
if (_filename != null)
{
stream.Close();
stream.Dispose();
}
return matrix;
}
/// <summary>
/// Reads all matrices from the file or stream.
/// </summary>
/// <returns>All matrices from the file or stream.</returns>
public Matrix<TDataType>[] ReadMatrices()
{
return ReadMatrices(new string[] { });
}
/// <summary>
/// Reads the named matrices from the file or stream.
/// </summary>
/// <param name="names">The names of the matrices to retrieve.</param>
/// <returns>
/// The named matrices from the file or stream.
/// </returns>
public Matrix<TDataType>[] ReadMatrices(IEnumerable<string> names)
{
Stream stream;
if (_filename == null)
{
stream = _stream;
_stream.Seek(0, SeekOrigin.Begin);
}
else
{
stream = new BufferedStream(new FileStream(_filename, FileMode.Open, FileAccess.Read));
}
var parser = new MatlabParser<TDataType>(stream, names);
var file = parser.Parse();
var matrices = new Matrix<TDataType>[file.Matrices.Count];
var i = 0;
foreach (var matrix in file.Matrices.Values)
{
matrices[i++] = matrix;
}
if (_filename != null)
{
stream.Close();
stream.Dispose();
}
return matrices;
}
}
}

70
src/Numerics/LinearAlgebra/Single/IO/DelimitedWriter.cs

@ -0,0 +1,70 @@
// <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.Single.IO
{
using Generic;
using LinearAlgebra.IO;
/// <summary>
/// Writes an <see cref="Matrix{TDataType}"/> to delimited text file. If the user does not
/// specify a delimiter, a tab separator is used.
/// </summary>
public class DelimitedWriter : DelimitedWriter<float>
{
/// <summary>
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
/// a comma as the delimiter.
/// </summary>
public DelimitedWriter()
{
}
/// <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) : base(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(string delimiter) : base(delimiter)
{
}
}
}

219
src/Numerics/LinearAlgebra/Single/IO/Matlab/MatlabFile.cs

@ -1,219 +0,0 @@
// <copyright file="MatlabFile.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.Single.IO.Matlab
{
using System.Collections.Generic;
using Generic;
/// <summary>
/// Represents a Matlab file
/// </summary>
internal class MatlabFile
{
/// <summary>
/// Matrices in a matlab file stored as 1-D arrays
/// </summary>
private readonly IDictionary<string, Matrix<float>> _matrices = new SortedList<string, Matrix<float>>();
/// <summary>
/// Gets or sets the header text.
/// </summary>
/// <value>The header text.</value>
public string HeaderText { get; set; }
/// <summary>
/// Gets or sets the first name of the matrix.
/// </summary>
/// <value>The first name of the matrix.</value>
public string FirstMatrixName { get; set; }
/// <summary>
/// Gets the first matrix.
/// </summary>
/// <value>The first matrix.</value>
public Matrix<float> FirstMatrix
{
get
{
if (string.IsNullOrEmpty(FirstMatrixName) || !_matrices.ContainsKey(FirstMatrixName))
{
return null;
}
return _matrices[FirstMatrixName];
}
}
/// <summary>
/// Gets the matrices.
/// </summary>
/// <value>The matrices.</value>
public IDictionary<string, Matrix<float>> Matrices
{
get { return _matrices; }
}
}
/*
/// <summary>
/// An
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="K"></typeparam>
internal class ListDictionary<T, K> : IDictionary<T, K>
{
private readonly IList<T> _keys = new List<T>();
private readonly IList<K> _values = new List<K>();
public void Add(T key, K value)
{
_keys.Add(key);
_values.Add(value);
}
public bool ContainsKey(T key)
{
return _keys.Contains(key);
}
public ICollection<T> Keys
{
get { return _keys; }
}
public bool Remove(T key)
{
if (_keys.Contains(key))
{
int pos = _keys.IndexOf(key);
_values.RemoveAt(pos);
_values.RemoveAt(pos);
return true;
}
return false;
}
public bool TryGetValue(T key, out K value)
{
if (_keys.Contains(key))
{
value = _values[_keys.IndexOf(key)];
return true;
}
value = default(K);
return false;
}
public ICollection<K> Values
{
get { return _values; }
}
public K this[T key]
{
get
{
if (_keys.Contains(key))
{
return _values[_keys.IndexOf(key)];
}
throw new KeyNotFoundException();
}
set
{
if (_keys.Contains(key))
{
_values[_keys.IndexOf(key)] = value;
}
else
{
Add(key, value);
}
}
}
public void Add(KeyValuePair<T, K> item)
{
Add(item.Key, item.Value);
}
public void Clear()
{
_keys.Clear();
_values.Clear();
}
public bool Contains(KeyValuePair<T, K> item)
{
return _keys.Contains(item.Key) && _values[_keys.IndexOf(item.Key)].Equals(item.Value);
}
public void CopyTo(KeyValuePair<T, K>[] array, int arrayIndex)
{
for (int i = 0; i < _keys.Count; i++)
{
array[arrayIndex + i] = new KeyValuePair<T, K>(_keys[i], _values[i]);
}
}
public int Count
{
get { return _keys.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(KeyValuePair<T, K> item)
{
if (Contains(item))
{
Remove(item.Key);
return true;
}
return false;
}
public IEnumerator<KeyValuePair<T, K>> GetEnumerator()
{
for (int i = 0; i < _keys.Count; i++)
{
yield return new KeyValuePair<T, K>(_keys[i], _values[i]);
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}*/
}

536
src/Numerics/LinearAlgebra/Single/IO/Matlab/MatlabParser.cs

@ -1,536 +0,0 @@
// <copyright file="MatlabParser.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.Single.IO.Matlab
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Common.IO.Matlab;
using Generic;
using Properties;
using zlib;
/// <summary>
/// Parse a Matlab file
/// </summary>
internal class MatlabParser
{
/// <summary>
/// Large Block Size
/// </summary>
private const int LargeBlockSize = 8;
/// <summary>
/// Little Endian Indicator
/// </summary>
private const byte LittleEndianIndicator = 0x49;
/// <summary>
/// Small Block Size
/// </summary>
private const int SmallBlockSize = 4;
/// <summary>
/// Holds the names of the matrices in the file.
/// </summary>
private readonly IList<string> _names = new List<string>();
/// <summary>
/// The stream to read the matlab file from.
/// </summary>
private readonly Stream _stream;
/// <summary>
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
/// </summary>
/// <param name="fileName">Name of the file.</param>
public MatlabParser(string fileName)
: this(fileName, new string[0])
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
/// </summary>
/// <param name="stream">The stream to read from.</param>
public MatlabParser(Stream stream)
: this(stream, new string[0])
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
/// </summary>
/// <param name="stream">The stream to read from.</param>
/// <param name="objectNames">The name of the objects to retrieve.</param>
public MatlabParser(Stream stream, IEnumerable<string> objectNames)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
_stream = stream;
SetNames(objectNames);
}
/// <summary>
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <param name="objectNames">The name of the objects to retrieve.</param>
public MatlabParser(string fileName, IEnumerable<string> objectNames)
{
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentException(Resources.StringNullOrEmpty, "filename");
}
_stream = File.OpenRead(fileName);
SetNames(objectNames);
}
/// <summary>
/// Copies the names of the objects to retrieve to a local field.
/// </summary>
/// <param name="objectNames">The name of the objects to retrieve.</param>
private void SetNames(IEnumerable<string> objectNames)
{
foreach (var name in objectNames)
{
_names.Add(name);
}
}
/// <summary>
/// Parses the file.
/// </summary>
/// <returns>The parsed Matlab file as a <see cref="MatlabFile"/> object.</returns>
public MatlabFile Parse()
{
var file = new MatlabFile();
using (var reader = new BinaryReader(_stream))
{
file.HeaderText = Encoding.ASCII.GetString(reader.ReadBytes(116));
// skipping subsystem offsets
reader.BaseStream.Position = 126;
if (reader.ReadByte() != LittleEndianIndicator)
{
throw new NotSupportedException(Resources.BigEndianNotSupported);
}
// skip version since it is always 0x0100.
reader.BaseStream.Position = 128;
var length = _stream.Length;
// for each data block add a matlab object to the file.
while (reader.BaseStream.Position < length)
{
var type = (DataType)reader.ReadInt16();
int size = reader.ReadInt16();
var smallBlock = true;
if (size == 0)
{
size = reader.ReadInt32();
smallBlock = false;
}
byte[] data;
if (type == DataType.Compressed)
{
data = DecompressBlock(reader.ReadBytes(size), ref type);
}
else
{
data = new byte[size];
reader.Read(data, 0, size);
AlignData(reader.BaseStream, size, smallBlock);
}
if (type == DataType.Matrix)
{
AddMatrix(data, file);
}
else
{
throw new NotSupportedException(string.Format(Resources.NotSupportedType, type));
}
}
}
return file;
}
/// <summary>
/// Aligns the data.
/// </summary>
/// <param name="stream">The stream.</param>
/// <param name="size">The size of the array.</param>
/// <param name="smallBlock">if set to <c>true</c> if reading from a small block.</param>
private static void AlignData(Stream stream, int size, bool smallBlock)
{
var blockSize = smallBlock ? SmallBlockSize : LargeBlockSize;
var offset = 0;
var mod = size % blockSize;
if (mod != 0)
{
offset = blockSize - mod;
}
stream.Seek(offset, SeekOrigin.Current);
}
/// <summary>
/// Decompresses the block.
/// </summary>
/// <param name="compressed">The compressed data.</param>
/// <param name="type">The type data type contained in the block.</param>
/// <returns>The decompressed block.</returns>
private static byte[] DecompressBlock(byte[] compressed, ref DataType type)
{
byte[] data;
using (var decompressed = new MemoryStream())
{
using (var decompressor = new ZOutputStream(decompressed))
{
decompressor.Write(compressed, 0, compressed.Length);
decompressed.Position = 0;
var buf = new byte[4];
decompressed.Read(buf, 0, 4);
type = (DataType)BitConverter.ToInt32(buf, 0);
decompressed.Read(buf, 0, 4);
var size = BitConverter.ToInt32(buf, 0);
data = new byte[size];
decompressed.Read(data, 0, size);
}
}
return data;
}
/// <summary>
/// Adds a matrix from the actual file into our presentation of a matlab file.
/// </summary>
/// <param name="data">The data of the matrix.</param>
/// <param name="file">The <see cref="MatlabFile"/> instance.</param>
private void AddMatrix(byte[] data, MatlabFile file)
{
using (var ms = new MemoryStream(data))
{
using (var reader = new BinaryReader(ms))
{
// skip tag - doesn't tell us anything we don't already know
reader.BaseStream.Seek(8, SeekOrigin.Current);
var arrayClass = (ArrayClass)reader.ReadByte();
var flags = reader.ReadByte();
var isComplex = (flags & (byte)ArrayFlags.Complex) == (byte)ArrayFlags.Complex;
if (isComplex)
{
throw new NotSupportedException(Resources.ComplexMatricesNotSupported);
}
// skip unneeded bytes
reader.BaseStream.Seek(10, SeekOrigin.Current);
var numDimensions = reader.ReadInt32() / 8;
if (numDimensions > 2)
{
throw new NotSupportedException(Resources.MoreThan2D);
}
var rows = reader.ReadInt32();
var columns = reader.ReadInt32();
// skip unneeded bytes
reader.BaseStream.Seek(2, SeekOrigin.Current);
int size = reader.ReadInt16();
var smallBlock = true;
if (size == 0)
{
size = reader.ReadInt32();
smallBlock = false;
}
var name = Encoding.ASCII.GetString(reader.ReadBytes(size));
AlignData(reader.BaseStream, size, smallBlock);
// only grab wanted objects
if (_names.Count != 0 && !_names.Contains(name))
{
return;
}
var type = (DataType)reader.ReadInt16();
size = reader.ReadInt16();
if (size == 0)
{
size = reader.ReadInt32();
}
Matrix<float> matrix;
switch (arrayClass)
{
case ArrayClass.Sparse:
matrix = PopulateSparseMatrix(reader, rows, columns, size);
break;
case ArrayClass.Function:
case ArrayClass.Character:
case ArrayClass.Object:
case ArrayClass.Structure:
case ArrayClass.Cell:
case ArrayClass.Unknown:
throw new NotImplementedException();
default:
matrix = PopulateDenseMatrix(type, reader, rows, columns);
break;
}
file.Matrices.Add(name, matrix);
if (file.FirstMatrixName == null)
{
file.FirstMatrixName = name;
}
}
}
}
/// <summary>
/// Populates a sparse matrix.
/// </summary>
/// <param name="reader">The reader.</param>
/// <param name="rows">The number of rows.</param>
/// <param name="columns">The number of columns.</param>
/// <param name="size">The size of the block.</param>
/// <returns>A populated sparse matrix.</returns>
private static Matrix<float> PopulateSparseMatrix(BinaryReader reader, int rows, int columns, int size)
{
// populate the row data array
var ir = new int[size / 4];
for (var i = 0; i < ir.Length; i++)
{
ir[i] = reader.ReadInt32();
}
AlignData(reader.BaseStream, size, false);
// skip data type since it will always be int32
reader.BaseStream.Seek(4, SeekOrigin.Current);
// populate the column data array
var jcsize = reader.ReadInt32();
var jc = new int[jcsize / 4];
for (var j = 0; j < jc.Length; j++)
{
jc[j] = reader.ReadInt32();
}
AlignData(reader.BaseStream, jcsize, false);
var type = (DataType)reader.ReadInt32();
// skip length since we already no it for the number of rows
reader.BaseStream.Seek(4, SeekOrigin.Current);
Matrix<float> matrix = new SparseMatrix(rows, columns);
var col = 0;
for (var i = 0; i < ir.Length; i++)
{
var row = ir[i];
if (jc[col + 1] == i)
{
col++;
}
switch (type)
{
case DataType.Int8:
matrix[row, col] = reader.ReadSByte();
break;
case DataType.UInt8:
matrix[row, col] = reader.ReadByte();
break;
case DataType.Int16:
matrix[row, col] = reader.ReadInt16();
break;
case DataType.UInt16:
matrix[row, col] = reader.ReadUInt16();
break;
case DataType.Int32:
matrix[row, col] = reader.ReadInt32();
break;
case DataType.UInt32:
matrix[row, col] = reader.ReadUInt32();
break;
case DataType.Single:
matrix[row, col] = reader.ReadSingle();
break;
case DataType.Int64:
matrix[row, col] = reader.ReadInt64();
break;
case DataType.UInt64:
matrix[row, col] = reader.ReadUInt64();
break;
case DataType.Double:
matrix[row, col] = (float)reader.ReadDouble();
break;
default:
throw new NotSupportedException();
}
}
return matrix;
}
/// <summary>
/// Populates a dense matrix.
/// </summary>
/// <param name="type">The type of data.</param>
/// <param name="reader">The reader.</param>
/// <param name="rows">The number of rows.</param>
/// <param name="columns">The number of columns.</param>
/// <returns>Returns a populated dense matrix.</returns>
private static Matrix<float> PopulateDenseMatrix(DataType type, BinaryReader reader, int rows, int columns)
{
Matrix<float> matrix = new DenseMatrix(rows, columns);
switch (type)
{
case DataType.Int8:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadSByte();
}
}
break;
case DataType.UInt8:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadByte();
}
}
break;
case DataType.Int16:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadInt16();
}
}
break;
case DataType.UInt16:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadUInt16();
}
}
break;
case DataType.Int32:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadInt32();
}
}
break;
case DataType.UInt32:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadUInt32();
}
}
break;
case DataType.Single:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadSingle();
}
}
break;
case DataType.Int64:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadInt64();
}
}
break;
case DataType.UInt64:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = reader.ReadUInt64();
}
}
break;
case DataType.Double:
for (var j = 0; j < columns; j++)
{
for (var i = 0; i < rows; i++)
{
matrix[i, j] = (float)reader.ReadDouble();
}
}
break;
default:
throw new NotSupportedException();
}
return matrix;
}
}
}

145
src/Numerics/LinearAlgebra/Single/IO/MatlabReader.cs

@ -3,9 +3,7 @@
// 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
@ -28,163 +26,28 @@
namespace MathNet.Numerics.LinearAlgebra.Single.IO
{
using System;
using System.Collections.Generic;
using System.IO;
using Generic;
using Matlab;
using Properties;
using LinearAlgebra.IO;
/// <summary>
/// Creates matrices from Matlab files.
/// </summary>
public class MatlabMatrixReader
public class MatlabMatrixReader : MatlabMatrixReader<float>
{
/// <summary>
/// The name of the file to read from.
/// </summary>
private readonly string _filename;
/// <summary>
/// The stream to read from if we are not reading from a file directly.
/// </summary>
private readonly Stream _stream;
/// <summary>
/// Initializes a new instance of the <see cref="MatlabMatrixReader"/> class.
/// </summary>
/// <param name="filename">Name of the file to read matrices from.</param>
public MatlabMatrixReader(string filename)
public MatlabMatrixReader(string filename) : base(filename)
{
if (string.IsNullOrEmpty(filename))
{
throw new ArgumentException(Resources.StringNullOrEmpty, "filename");
}
if (!File.Exists(filename))
{
throw new FileNotFoundException(Resources.FileDoesNotExist, "filename");
}
_filename = filename;
}
/// <summary>
/// Initializes a new instance of the <see cref="MatlabMatrixReader"/> class.
/// </summary>
/// <param name="stream">The stream to reader matrices from.</param>
public MatlabMatrixReader(Stream stream)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
_stream = stream;
}
/// <summary>
/// Reads the first matrix from the file or stream.
/// </summary>
/// <returns>
/// If the matrix is stored as a sparse matrix, then a <see cref="SparseMatrix"/> is returned. Otherwise, a <see cref="DenseMatrix"/>
/// is returned.
/// </returns>
public Matrix<float> ReadMatrix()
{
return ReadMatrix(null);
}
/// <summary>
/// Reads the named matrix from the file or stream.
/// </summary>
/// <param name="matrixName">The name of the matrix to read.</param>
/// <returns>
/// If the matrix is stored as a sparse matrix, then a <see cref="SparseMatrix"/> is returned. Otherwise, a <see cref="DenseMatrix"/>
/// is returned. <see langword="null"/> is returned if a matrix with the requests name doesn't exist.
/// </returns>
public Matrix<float> ReadMatrix(string matrixName)
public MatlabMatrixReader(Stream stream) : base(stream)
{
Stream stream;
if (_filename == null)
{
stream = _stream;
_stream.Seek(0, SeekOrigin.Begin);
}
else
{
stream = new FileStream(_filename, FileMode.Open, FileAccess.Read);
}
var names = string.IsNullOrEmpty(matrixName) ? new string[] { } : new[] { matrixName };
var parser = new MatlabParser(stream, names);
var file = parser.Parse();
Matrix<float> matrix = null;
if (string.IsNullOrEmpty(matrixName))
{
matrix = file.FirstMatrix;
}
else if (file.Matrices.ContainsKey(matrixName))
{
matrix = file.Matrices[matrixName];
}
if (_filename != null)
{
stream.Close();
stream.Dispose();
}
return matrix;
}
/// <summary>
/// Reads all matrices from the file or stream.
/// </summary>
/// <returns>All matrices from the file or stream.</returns>
public Matrix<float>[] ReadMatrices()
{
return ReadMatrices(new string[] { });
}
/// <summary>
/// Reads the named matrices from the file or stream.
/// </summary>
/// <param name="names">The names of the matrices to retrieve.</param>
/// <returns>
/// The named matrices from the file or stream.
/// </returns>
public Matrix<float>[] ReadMatrices(IEnumerable<string> names)
{
Stream stream;
if (_filename == null)
{
stream = _stream;
_stream.Seek(0, SeekOrigin.Begin);
}
else
{
stream = new BufferedStream(new FileStream(_filename, FileMode.Open, FileAccess.Read));
}
var parser = new MatlabParser(stream, names);
var file = parser.Parse();
var matrices = new Matrix<float>[file.Matrices.Count];
var i = 0;
foreach (var matrix in file.Matrices.Values)
{
matrices[i++] = matrix;
}
if (_filename != null)
{
stream.Close();
stream.Dispose();
}
return matrices;
}
}
}

19
src/Numerics/Numerics.csproj

@ -124,9 +124,15 @@
<Compile Include="Distributions\Multivariate\InverseWishart.cs" />
<Compile Include="Distributions\Multivariate\MatrixNormal.cs" />
<Compile Include="Distributions\Multivariate\Wishart.cs" />
<Compile Include="LinearAlgebra\Common\IO\Matlab\ArrayClass.cs" />
<Compile Include="LinearAlgebra\Common\IO\Matlab\ArrayFlags.cs" />
<Compile Include="LinearAlgebra\Common\IO\Matlab\DataType.cs" />
<Compile Include="LinearAlgebra\Complex32\IO\DelimitedWriter.cs" />
<Compile Include="LinearAlgebra\Complex32\IO\MatlabReader.cs" />
<Compile Include="LinearAlgebra\Complex\IO\DelimitedWriter.cs" />
<Compile Include="LinearAlgebra\Complex\IO\MatlabReader.cs" />
<Compile Include="LinearAlgebra\Double\IO\DelimitedWriter.cs" />
<Compile Include="LinearAlgebra\IO\MatlabReader.cs" />
<Compile Include="LinearAlgebra\IO\Matlab\ArrayClass.cs" />
<Compile Include="LinearAlgebra\IO\Matlab\ArrayFlags.cs" />
<Compile Include="LinearAlgebra\IO\Matlab\DataType.cs" />
<Compile Include="LinearAlgebra\Complex32\DenseMatrix.cs" />
<Compile Include="LinearAlgebra\Complex32\DenseVector.cs" />
<Compile Include="LinearAlgebra\Complex32\DiagonalMatrix.cs" />
@ -222,9 +228,8 @@
<Compile Include="LinearAlgebra\Single\Factorization\UserQR.cs" />
<Compile Include="LinearAlgebra\Single\Factorization\UserSvd.cs" />
<Compile Include="LinearAlgebra\Single\IO\DelimitedReader.cs" />
<Compile Include="LinearAlgebra\Single\IO\DelimitedWriter.cs" />
<Compile Include="LinearAlgebra\Single\IO\MatlabReader.cs" />
<Compile Include="LinearAlgebra\Single\IO\Matlab\MatlabFile.cs" />
<Compile Include="LinearAlgebra\Single\IO\Matlab\MatlabParser.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\Iterative\BiCgStab.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\Iterative\CompositeSolver.cs" />
<Compile Include="LinearAlgebra\Single\Solvers\Iterative\GpBiCg.cs" />
@ -261,8 +266,8 @@
<Compile Include="LinearAlgebra\Double\Factorization\UserQR.cs" />
<Compile Include="LinearAlgebra\Double\Factorization\UserSvd.cs" />
<Compile Include="LinearAlgebra\Double\IO\MatlabReader.cs" />
<Compile Include="LinearAlgebra\Double\IO\Matlab\MatlabFile.cs" />
<Compile Include="LinearAlgebra\Double\IO\Matlab\MatlabParser.cs" />
<Compile Include="LinearAlgebra\IO\Matlab\MatlabFile.cs" />
<Compile Include="LinearAlgebra\IO\Matlab\MatlabParser.cs" />
<Compile Include="LinearAlgebra\Generic\ISolver.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\IIterativeSolver.cs" />
<Compile Include="LinearAlgebra\Generic\Solvers\IIterativeSolverSetup.cs" />

10
src/UnitTests/LinearAlgebraTests/Complex/IO/DelimitedWriterTests.cs

@ -5,7 +5,7 @@
using System.Numerics;
using System.IO;
using LinearAlgebra.Complex;
using LinearAlgebra.IO;
using LinearAlgebra.Complex.IO;
using MbUnit.Framework;
[TestFixture]
@ -15,7 +15,7 @@
public void CanWriteCommaDelimitedData()
{
var matrix = new DenseMatrix(new[,] { { new Complex(1.1, 1.1), new Complex(2.2, 2.2), new Complex(3.3, 3.3) }, { new Complex(4.4, 4.4), new Complex(5.5, 5.5), new Complex(6.6, 6.6) }, { new Complex(7.7, 7.7), new Complex(8.8, 8.8), new Complex(9.9, 9.9) } });
var writer = new DelimitedWriter<Complex>(',');
var writer = new DelimitedWriter(',');
var stream = new MemoryStream();
writer.WriteMatrix(matrix, stream);
var data = stream.ToArray();
@ -32,7 +32,7 @@
{
var matrix = new DenseMatrix(new[,] { { new Complex(1.1, 1.1), new Complex(2.2, 2.2), new Complex(3.3, 3.3) }, { new Complex(4.4, 4.4), new Complex(5.5, 5.5), new Complex(6.6, 6.6) }, { new Complex(7.7, 7.7), new Complex(8.8, 8.8), new Complex(9.9, 9.9) } });
var culture = new CultureInfo("tr-TR");
var writer = new DelimitedWriter<Complex>('.')
var writer = new DelimitedWriter('.')
{
CultureInfo = culture
};
@ -51,7 +51,7 @@
public void CanWriteSpaceDelimitedData()
{
var matrix = new DenseMatrix(new[,] { { new Complex(1.1, 1.1), new Complex(2.2, 2.2), new Complex(3.3, 3.3) }, { new Complex(4.4, 4.4), new Complex(5.5, 5.5), new Complex(6.6, 6.6) }, { new Complex(7.7, 7.7), new Complex(8.8, 8.8), new Complex(9.9, 9.9) } });
var writer = new DelimitedWriter<Complex>(' ');
var writer = new DelimitedWriter(' ');
var stream = new MemoryStream();
writer.WriteMatrix(matrix, stream);
var data = stream.ToArray();
@ -68,7 +68,7 @@
{
var matrix = new DenseMatrix(new[,] { { new Complex(1.1, 1.1), new Complex(2.2, 2.2), new Complex(3.3, 3.3) }, { new Complex(4.4, 4.4), new Complex(5.5, 5.5), new Complex(6.6, 6.6) }, { new Complex(7.7, 7.7), new Complex(8.8, 8.8), new Complex(9.9, 9.9) } });
var headers = new[] { "a", "b", "c" };
var writer = new DelimitedWriter<Complex>('\t')
var writer = new DelimitedWriter('\t')
{
ColumnHeaders = headers
};

70
src/UnitTests/LinearAlgebraTests/Complex/IO/MatlabReaderTests.cs

@ -0,0 +1,70 @@

namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.IO
{
using LinearAlgebra.Double;
using LinearAlgebra.Double.IO;
using MbUnit.Framework;
[TestFixture]
public class MatlabMatrixReaderTest
{
[Test]
public void CanReadNonComplexAllMatrices()
{
var dmr = new MatlabMatrixReader("./data/Matlab/collection.mat");
var matrices = dmr.ReadMatrices();
Assert.AreEqual(30, matrices.Length);
foreach (var matrix in matrices)
{
Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
}
}
[Test]
public void CanReadNonComplexFirstMatrix()
{
var dmr = new MatlabMatrixReader("./data/Matlab/A.mat");
var matrix = dmr.ReadMatrix();
Assert.AreEqual(100, matrix.RowCount);
Assert.AreEqual(100, matrix.ColumnCount);
Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
AssertHelpers.AlmostEqual(100.108979553704, matrix.FrobeniusNorm(), 13);
}
[Test]
public void CanReadNonComplexNamedMatrices()
{
var dmr = new MatlabMatrixReader("./data/Matlab/collection.mat");
var matrices = dmr.ReadMatrices(new[] { "Ad", "Au64" });
Assert.AreEqual(2, matrices.Length);
foreach (var matrix in matrices)
{
Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
}
}
[Test]
public void CanReadNonComplexNamedMatrix()
{
var dmr = new MatlabMatrixReader("./data/Matlab/collection.mat");
var matrices = dmr.ReadMatrices(new[] { "Ad" });
Assert.AreEqual(1, matrices.Length);
Assert.AreEqual(100, matrices[0].RowCount);
Assert.AreEqual(100, matrices[0].ColumnCount);
AssertHelpers.AlmostEqual(100.431635988639, matrices[0].FrobeniusNorm(), 13);
Assert.AreEqual(typeof(DenseMatrix), matrices[0].GetType());
}
[Test]
public void CanReadNonComplexNamedSparseMatrix()
{
var dmr = new MatlabMatrixReader("./data/Matlab/sparse-small.mat");
var matrix = dmr.ReadMatrix("S");
Assert.AreEqual(100, matrix.RowCount);
Assert.AreEqual(100, matrix.ColumnCount);
Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
AssertHelpers.AlmostEqual(17.6385090630805, matrix.FrobeniusNorm(), 12);
}
}
}

10
src/UnitTests/LinearAlgebraTests/Complex32/IO/DelimitedWriterTests.cs

@ -4,8 +4,8 @@
using System.Globalization;
using System.IO;
using LinearAlgebra.Complex32;
using LinearAlgebra.Complex32.IO;
using Numerics;
using LinearAlgebra.IO;
using MbUnit.Framework;
[TestFixture]
@ -15,7 +15,7 @@
public void CanWriteCommaDelimitedData()
{
var matrix = new DenseMatrix(new[,] { { new Complex32(1.1f, 1.1f), new Complex32(2.2f, 2.2f), new Complex32(3.3f, 3.3f) }, { new Complex32(4.4f, 4.4f), new Complex32(5.5f, 5.5f), new Complex32(6.6f, 6.6f) }, { new Complex32(7.7f, 7.7f), new Complex32(8.8f, 8.8f), new Complex32(9.9f, 9.9f) } });
var writer = new DelimitedWriter<Complex32>(',');
var writer = new DelimitedWriter(',');
var stream = new MemoryStream();
writer.WriteMatrix(matrix, stream);
var data = stream.ToArray();
@ -32,7 +32,7 @@
{
var matrix = new DenseMatrix(new[,] { { new Complex32(1.1f, 1.1f), new Complex32(2.2f, 2.2f), new Complex32(3.3f, 3.3f) }, { new Complex32(4.4f, 4.4f), new Complex32(5.5f, 5.5f), new Complex32(6.6f, 6.6f) }, { new Complex32(7.7f, 7.7f), new Complex32(8.8f, 8.8f), new Complex32(9.9f, 9.9f) } });
var culture = new CultureInfo("tr-TR");
var writer = new DelimitedWriter<Complex32>('.')
var writer = new DelimitedWriter('.')
{
CultureInfo = culture
};
@ -51,7 +51,7 @@
public void CanWriteSpaceDelimitedData()
{
var matrix = new DenseMatrix(new[,] { { new Complex32(1.1f, 1.1f), new Complex32(2.2f, 2.2f), new Complex32(3.3f, 3.3f) }, { new Complex32(4.4f, 4.4f), new Complex32(5.5f, 5.5f), new Complex32(6.6f, 6.6f) }, { new Complex32(7.7f, 7.7f), new Complex32(8.8f, 8.8f), new Complex32(9.9f, 9.9f) } });
var writer = new DelimitedWriter<Complex32>(' ');
var writer = new DelimitedWriter(' ');
var stream = new MemoryStream();
writer.WriteMatrix(matrix, stream);
var data = stream.ToArray();
@ -68,7 +68,7 @@
{
var matrix = new DenseMatrix(new[,] { { new Complex32(1.1f, 1.1f), new Complex32(2.2f, 2.2f), new Complex32(3.3f, 3.3f) }, { new Complex32(4.4f, 4.4f), new Complex32(5.5f, 5.5f), new Complex32(6.6f, 6.6f) }, { new Complex32(7.7f, 7.7f), new Complex32(8.8f, 8.8f), new Complex32(9.9f, 9.9f) } });
var headers = new[] { "a", "b", "c" };
var writer = new DelimitedWriter<Complex32>('\t')
var writer = new DelimitedWriter('\t')
{
ColumnHeaders = headers
};

70
src/UnitTests/LinearAlgebraTests/Complex32/IO/MatlabReaderTests.cs

@ -0,0 +1,70 @@

namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.IO
{
using LinearAlgebra.Double;
using LinearAlgebra.Double.IO;
using MbUnit.Framework;
[TestFixture]
public class MatlabMatrixReaderTest
{
[Test]
public void CanReadNonComplexAllMatrices()
{
var dmr = new MatlabMatrixReader("./data/Matlab/collection.mat");
var matrices = dmr.ReadMatrices();
Assert.AreEqual(30, matrices.Length);
foreach (var matrix in matrices)
{
Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
}
}
[Test]
public void CanReadNonComplexFirstMatrix()
{
var dmr = new MatlabMatrixReader("./data/Matlab/A.mat");
var matrix = dmr.ReadMatrix();
Assert.AreEqual(100, matrix.RowCount);
Assert.AreEqual(100, matrix.ColumnCount);
Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
AssertHelpers.AlmostEqual(100.108979553704, matrix.FrobeniusNorm(), 13);
}
[Test]
public void CanReadNonComplexNamedMatrices()
{
var dmr = new MatlabMatrixReader("./data/Matlab/collection.mat");
var matrices = dmr.ReadMatrices(new[] { "Ad", "Au64" });
Assert.AreEqual(2, matrices.Length);
foreach (var matrix in matrices)
{
Assert.AreEqual(typeof(DenseMatrix), matrix.GetType());
}
}
[Test]
public void CanReadNonComplexNamedMatrix()
{
var dmr = new MatlabMatrixReader("./data/Matlab/collection.mat");
var matrices = dmr.ReadMatrices(new[] { "Ad" });
Assert.AreEqual(1, matrices.Length);
Assert.AreEqual(100, matrices[0].RowCount);
Assert.AreEqual(100, matrices[0].ColumnCount);
AssertHelpers.AlmostEqual(100.431635988639, matrices[0].FrobeniusNorm(), 13);
Assert.AreEqual(typeof(DenseMatrix), matrices[0].GetType());
}
[Test]
public void CanReadNonComplexNamedSparseMatrix()
{
var dmr = new MatlabMatrixReader("./data/Matlab/sparse-small.mat");
var matrix = dmr.ReadMatrix("S");
Assert.AreEqual(100, matrix.RowCount);
Assert.AreEqual(100, matrix.ColumnCount);
Assert.AreEqual(typeof(SparseMatrix), matrix.GetType());
AssertHelpers.AlmostEqual(17.6385090630805, matrix.FrobeniusNorm(), 12);
}
}
}

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

@ -4,7 +4,7 @@
using System.Globalization;
using System.IO;
using LinearAlgebra.Double;
using LinearAlgebra.IO;
using LinearAlgebra.Double.IO;
using MbUnit.Framework;
[TestFixture]
@ -14,7 +14,7 @@
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<double>(',');
var writer = new DelimitedWriter(',');
var stream = new MemoryStream();
writer.WriteMatrix(matrix, stream);
var data = stream.ToArray();
@ -31,7 +31,7 @@
{
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<double>('.')
var writer = new DelimitedWriter('.')
{
CultureInfo = culture
};
@ -50,7 +50,7 @@
public void CanWriteSpaceDelimitedData()
{
var matrix = new SparseMatrix(new[,] { { 1.1, 0, 0 }, { 0, 5.5, 0 }, { 0, 0, 9.9 } });
var writer = new DelimitedWriter<double>(' ');
var writer = new DelimitedWriter(' ');
var stream = new MemoryStream();
writer.WriteMatrix(matrix, stream);
var data = stream.ToArray();
@ -67,7 +67,7 @@
{
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<double>('\t')
var writer = new DelimitedWriter('\t')
{
ColumnHeaders = headers
};

10
src/UnitTests/LinearAlgebraTests/Single/IO/DelimitedWriterTests.cs

@ -3,8 +3,6 @@
using System;
using System.Globalization;
using System.IO;
using System.Text;
using LinearAlgebra.IO;
using LinearAlgebra.Single;
using LinearAlgebra.Single.IO;
using MbUnit.Framework;
@ -16,7 +14,7 @@
public void CanWriteCommaDelimitedData()
{
var matrix = new DenseMatrix(new[,] { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f }, { 7.7f, 8.8f, 9.9f } });
var writer = new DelimitedWriter<float>(',');
var writer = new DelimitedWriter(',');
var stream = new MemoryStream();
writer.WriteMatrix(matrix, stream);
var data = stream.ToArray();
@ -33,7 +31,7 @@
{
var matrix = new DenseMatrix(new[,] { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f }, { 7.7f, 8.8f, 9.9f } });
var culture = new CultureInfo("tr-TR");
var writer = new DelimitedWriter<float>('.')
var writer = new DelimitedWriter('.')
{
CultureInfo = culture
};
@ -52,7 +50,7 @@
public void CanWriteSpaceDelimitedData()
{
var matrix = new SparseMatrix(new[,] { { 1.1f, 0, 0 }, { 0, 5.5f, 0 }, { 0, 0, 9.9f } });
var writer = new DelimitedWriter<float>(' ');
var writer = new DelimitedWriter(' ');
var stream = new MemoryStream();
writer.WriteMatrix(matrix, stream);
var data = stream.ToArray();
@ -69,7 +67,7 @@
{
var matrix = new UserDefinedMatrix(new[,] { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f }, { 7.7f, 8.8f, 9.9f } });
var headers = new[] { "a", "b", "c" };
var writer = new DelimitedWriter<float>('\t')
var writer = new DelimitedWriter('\t')
{
ColumnHeaders = headers
};

2
src/UnitTests/UnitTests.csproj

@ -138,6 +138,7 @@
<Compile Include="LinearAlgebraTests\Complex32\Factorization\UserSvdTests.cs" />
<Compile Include="LinearAlgebraTests\Complex32\IO\DelimitedReaderTests.cs" />
<Compile Include="LinearAlgebraTests\Complex32\IO\DelimitedWriterTests.cs" />
<Compile Include="LinearAlgebraTests\Complex32\IO\MatlabReaderTests.cs" />
<Compile Include="LinearAlgebraTests\Complex32\MatrixLoader.cs" />
<Compile Include="LinearAlgebraTests\Complex32\MatrixTests.Arithmetic.cs" />
<Compile Include="LinearAlgebraTests\Complex32\MatrixTests.cs" />
@ -182,6 +183,7 @@
<Compile Include="LinearAlgebraTests\Complex\Factorization\UserSvdTests.cs" />
<Compile Include="LinearAlgebraTests\Complex\IO\DelimitedReaderTests.cs" />
<Compile Include="LinearAlgebraTests\Complex\IO\DelimitedWriterTests.cs" />
<Compile Include="LinearAlgebraTests\Complex\IO\MatlabReaderTests.cs" />
<Compile Include="LinearAlgebraTests\Complex\MatrixLoader.cs" />
<Compile Include="LinearAlgebraTests\Complex\MatrixTests.Arithmetic.cs" />
<Compile Include="LinearAlgebraTests\Complex\MatrixTests.cs" />

Loading…
Cancel
Save