diff --git a/src/MathNet.Numerics.5.1.ReSharper b/src/MathNet.Numerics.5.1.ReSharper
index 934aa504..108ae5fe 100644
--- a/src/MathNet.Numerics.5.1.ReSharper
+++ b/src/MathNet.Numerics.5.1.ReSharper
@@ -14,7 +14,11 @@
Wikipedia
Marsaglia
Xorshift
-λ
+λ
+Matlab
+Matlab
+Matlab
+Endian
diff --git a/src/Numerics/LinearAlgebra/Complex/IO/DelimitedWriter.cs b/src/Numerics/LinearAlgebra/Complex/IO/DelimitedWriter.cs
new file mode 100644
index 00000000..1a4627d7
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Complex/IO/DelimitedWriter.cs
@@ -0,0 +1,70 @@
+//
+// 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.Complex.IO
+{
+ using Generic;
+ using LinearAlgebra.IO;
+
+ ///
+ /// Writes an to delimited text file. If the user does not
+ /// specify a delimiter, a tab separator is used.
+ ///
+ public class DelimitedWriter : DelimitedWriter
+ {
+ ///
+ /// Initializes a new instance of the class.
+ /// a comma as the delimiter.
+ ///
+ public DelimitedWriter()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// using the given delimiter.
+ ///
+ ///
+ /// the delimiter to use.
+ ///
+ public DelimitedWriter(char delimiter) : base(delimiter)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// using the given delimiter.
+ ///
+ ///
+ /// the delimiter to use.
+ ///
+ public DelimitedWriter(string delimiter) : base(delimiter)
+ {
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/Complex/IO/MatlabReader.cs b/src/Numerics/LinearAlgebra/Complex/IO/MatlabReader.cs
new file mode 100644
index 00000000..1f838d96
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Complex/IO/MatlabReader.cs
@@ -0,0 +1,53 @@
+//
+// 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.Complex.IO
+{
+ using System.IO;
+ using LinearAlgebra.IO;
+
+ ///
+ /// Creates matrices from Matlab files.
+ ///
+ public class MatlabMatrixReader : MatlabMatrixReader
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Name of the file to read matrices from.
+ public MatlabMatrixReader(string filename) : base(filename)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The stream to reader matrices from.
+ public MatlabMatrixReader(Stream stream) : base(stream)
+ {
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/Complex32/IO/DelimitedWriter.cs b/src/Numerics/LinearAlgebra/Complex32/IO/DelimitedWriter.cs
new file mode 100644
index 00000000..1a7906a2
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Complex32/IO/DelimitedWriter.cs
@@ -0,0 +1,70 @@
+//
+// 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.Complex32.IO
+{
+ using Generic;
+ using LinearAlgebra.IO;
+
+ ///
+ /// Writes an to delimited text file. If the user does not
+ /// specify a delimiter, a tab separator is used.
+ ///
+ public class DelimitedWriter : DelimitedWriter
+ {
+ ///
+ /// Initializes a new instance of the class.
+ /// a comma as the delimiter.
+ ///
+ public DelimitedWriter()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// using the given delimiter.
+ ///
+ ///
+ /// the delimiter to use.
+ ///
+ public DelimitedWriter(char delimiter) : base(delimiter)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// using the given delimiter.
+ ///
+ ///
+ /// the delimiter to use.
+ ///
+ public DelimitedWriter(string delimiter) : base(delimiter)
+ {
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/Complex32/IO/MatlabReader.cs b/src/Numerics/LinearAlgebra/Complex32/IO/MatlabReader.cs
new file mode 100644
index 00000000..534f1eac
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Complex32/IO/MatlabReader.cs
@@ -0,0 +1,53 @@
+//
+// 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.Complex32.IO
+{
+ using System.IO;
+ using LinearAlgebra.IO;
+
+ ///
+ /// Creates matrices from Matlab files.
+ ///
+ public class MatlabMatrixReader : MatlabMatrixReader
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Name of the file to read matrices from.
+ public MatlabMatrixReader(string filename) : base(filename)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The stream to reader matrices from.
+ public MatlabMatrixReader(Stream stream) : base(stream)
+ {
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/Double/IO/DelimitedWriter.cs b/src/Numerics/LinearAlgebra/Double/IO/DelimitedWriter.cs
new file mode 100644
index 00000000..a2f8eb5f
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Double/IO/DelimitedWriter.cs
@@ -0,0 +1,70 @@
+//
+// 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 Generic;
+ using LinearAlgebra.IO;
+
+ ///
+ /// Writes an to delimited text file. If the user does not
+ /// specify a delimiter, a tab separator is used.
+ ///
+ public class DelimitedWriter : DelimitedWriter
+ {
+ ///
+ /// Initializes a new instance of the class.
+ /// a comma as the delimiter.
+ ///
+ public DelimitedWriter()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// using the given delimiter.
+ ///
+ ///
+ /// the delimiter to use.
+ ///
+ public DelimitedWriter(char delimiter) : base(delimiter)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// using the given delimiter.
+ ///
+ ///
+ /// the delimiter to use.
+ ///
+ public DelimitedWriter(string delimiter) : base(delimiter)
+ {
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabFile.cs b/src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabFile.cs
deleted file mode 100644
index c2de1b77..00000000
--- a/src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabFile.cs
+++ /dev/null
@@ -1,219 +0,0 @@
-//
-// 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.Matlab
-{
- using System.Collections.Generic;
- using Generic;
-
- ///
- /// Represents a Matlab file
- ///
- internal class MatlabFile
- {
- ///
- /// Matrices in a matlab file stored as 1-D arrays
- ///
- private readonly IDictionary> _matrices = new SortedList>();
-
- ///
- /// Gets or sets the header text.
- ///
- /// The header text.
- public string HeaderText { get; set; }
-
- ///
- /// Gets or sets the first name of the matrix.
- ///
- /// The first name of the matrix.
- public string FirstMatrixName { get; set; }
-
- ///
- /// Gets the first matrix.
- ///
- /// The first matrix.
- public Matrix FirstMatrix
- {
- get
- {
- if (string.IsNullOrEmpty(FirstMatrixName) || !_matrices.ContainsKey(FirstMatrixName))
- {
- return null;
- }
-
- return _matrices[FirstMatrixName];
- }
- }
-
- ///
- /// Gets the matrices.
- ///
- /// The matrices.
- public IDictionary> Matrices
- {
- get { return _matrices; }
- }
- }
-
- /*
- ///
- /// An
- ///
- ///
- ///
- internal class ListDictionary : IDictionary
- {
- private readonly IList _keys = new List();
- private readonly IList _values = new List();
-
- public void Add(T key, K value)
- {
- _keys.Add(key);
- _values.Add(value);
- }
-
- public bool ContainsKey(T key)
- {
- return _keys.Contains(key);
- }
-
- public ICollection 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 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 item)
- {
- Add(item.Key, item.Value);
- }
-
- public void Clear()
- {
- _keys.Clear();
- _values.Clear();
- }
-
- public bool Contains(KeyValuePair item)
- {
- return _keys.Contains(item.Key) && _values[_keys.IndexOf(item.Key)].Equals(item.Value);
- }
-
- public void CopyTo(KeyValuePair[] array, int arrayIndex)
- {
- for (int i = 0; i < _keys.Count; i++)
- {
- array[arrayIndex + i] = new KeyValuePair(_keys[i], _values[i]);
- }
- }
-
- public int Count
- {
- get { return _keys.Count; }
- }
-
- public bool IsReadOnly
- {
- get { return false; }
- }
-
- public bool Remove(KeyValuePair item)
- {
- if (Contains(item))
- {
- Remove(item.Key);
- return true;
- }
- return false;
- }
-
- public IEnumerator> GetEnumerator()
- {
- for (int i = 0; i < _keys.Count; i++)
- {
- yield return new KeyValuePair(_keys[i], _values[i]);
- }
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
-
- }*/
-}
diff --git a/src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabParser.cs b/src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabParser.cs
deleted file mode 100644
index bd61214e..00000000
--- a/src/Numerics/LinearAlgebra/Double/IO/Matlab/MatlabParser.cs
+++ /dev/null
@@ -1,536 +0,0 @@
-//
-// 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.Matlab
-{
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Text;
- using Common.IO.Matlab;
- using Generic;
- using Properties;
- using zlib;
-
- ///
- /// Parse a Matlab file
- ///
- internal class MatlabParser
- {
- ///
- /// Large Block Size
- ///
- private const int LargeBlockSize = 8;
-
- ///
- /// Little Endian Indicator
- ///
- private const byte LittleEndianIndicator = 0x49;
-
- ///
- /// Small Block Size
- ///
- private const int SmallBlockSize = 4;
-
- ///
- /// Holds the names of the matrices in the file.
- ///
- private readonly IList _names = new List();
-
- ///
- /// The stream to read the matlab file from.
- ///
- private readonly Stream _stream;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// Name of the file.
- public MatlabParser(string fileName)
- : this(fileName, new string[0])
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The stream to read from.
- public MatlabParser(Stream stream)
- : this(stream, new string[0])
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The stream to read from.
- /// The name of the objects to retrieve.
- public MatlabParser(Stream stream, IEnumerable objectNames)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- _stream = stream;
- SetNames(objectNames);
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// Name of the file.
- /// The name of the objects to retrieve.
- public MatlabParser(string fileName, IEnumerable objectNames)
- {
- if (string.IsNullOrEmpty(fileName))
- {
- throw new ArgumentException(Resources.StringNullOrEmpty, "filename");
- }
-
- _stream = File.OpenRead(fileName);
- SetNames(objectNames);
- }
-
- ///
- /// Copies the names of the objects to retrieve to a local field.
- ///
- /// The name of the objects to retrieve.
- private void SetNames(IEnumerable objectNames)
- {
- foreach (var name in objectNames)
- {
- _names.Add(name);
- }
- }
-
- ///
- /// Parses the file.
- ///
- /// The parsed Matlab file as a object.
- 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;
- }
-
- ///
- /// Aligns the data.
- ///
- /// The stream.
- /// The size of the array.
- /// if set to true if reading from a small block.
- 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);
- }
-
- ///
- /// Decompresses the block.
- ///
- /// The compressed data.
- /// The type data type contained in the block.
- /// The decompressed block.
- 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;
- }
-
- ///
- /// Adds a matrix from the actual file into our presentation of a matlab file.
- ///
- /// The data of the matrix.
- /// The instance.
- 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 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;
- }
- }
- }
- }
-
- ///
- /// Populates a sparse matrix.
- ///
- /// The reader.
- /// The number of rows.
- /// The number of columns.
- /// The size of the block.
- /// A populated sparse matrix.
- private static Matrix 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 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;
- }
-
- ///
- /// Populates a dense matrix.
- ///
- /// The type of data.
- /// The reader.
- /// The number of rows.
- /// The number of columns.
- /// Returns a populated dense matrix.
- private static Matrix PopulateDenseMatrix(DataType type, BinaryReader reader, int rows, int columns)
- {
- Matrix 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;
- }
- }
-}
diff --git a/src/Numerics/LinearAlgebra/Double/IO/MatlabReader.cs b/src/Numerics/LinearAlgebra/Double/IO/MatlabReader.cs
index f673a724..b502929a 100644
--- a/src/Numerics/LinearAlgebra/Double/IO/MatlabReader.cs
+++ b/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;
///
/// Creates matrices from Matlab files.
///
- public class MatlabMatrixReader
+ public class MatlabMatrixReader : MatlabMatrixReader
{
- ///
- /// The name of the file to read from.
- ///
- private readonly string _filename;
-
- ///
- /// The stream to read from if we are not reading from a file directly.
- ///
- private readonly Stream _stream;
-
///
/// Initializes a new instance of the class.
///
/// Name of the file to read matrices from.
- 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;
}
///
/// Initializes a new instance of the class.
///
/// The stream to reader matrices from.
- public MatlabMatrixReader(Stream stream)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- _stream = stream;
- }
-
- ///
- /// Reads the first matrix from the file or stream.
- ///
- ///
- /// If the matrix is stored as a sparse matrix, then a is returned. Otherwise, a
- /// is returned.
- ///
- public Matrix ReadMatrix()
- {
- return ReadMatrix(null);
- }
-
- ///
- /// Reads the named matrix from the file or stream.
- ///
- /// The name of the matrix to read.
- ///
- /// If the matrix is stored as a sparse matrix, then a is returned. Otherwise, a
- /// is returned. is returned if a matrix with the requests name doesn't exist.
- ///
- public Matrix 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 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;
- }
-
- ///
- /// Reads all matrices from the file or stream.
- ///
- /// All matrices from the file or stream.
- public Matrix[] ReadMatrices()
- {
- return ReadMatrices(new string[] { });
- }
-
- ///
- /// Reads the named matrices from the file or stream.
- ///
- /// The names of the matrices to retrieve.
- ///
- /// The named matrices from the file or stream.
- ///
- public Matrix[] ReadMatrices(IEnumerable 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[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;
}
}
}
diff --git a/src/Numerics/LinearAlgebra/Common/IO/Matlab/ArrayClass.cs b/src/Numerics/LinearAlgebra/IO/Matlab/ArrayClass.cs
similarity index 98%
rename from src/Numerics/LinearAlgebra/Common/IO/Matlab/ArrayClass.cs
rename to src/Numerics/LinearAlgebra/IO/Matlab/ArrayClass.cs
index bd6fb887..174dcda0 100644
--- a/src/Numerics/LinearAlgebra/Common/IO/Matlab/ArrayClass.cs
+++ b/src/Numerics/LinearAlgebra/IO/Matlab/ArrayClass.cs
@@ -26,7 +26,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
-namespace MathNet.Numerics.LinearAlgebra.Common.IO.Matlab
+namespace MathNet.Numerics.LinearAlgebra.IO.Matlab
{
///
/// Enumeration for the Matlab array types
diff --git a/src/Numerics/LinearAlgebra/Common/IO/Matlab/ArrayFlags.cs b/src/Numerics/LinearAlgebra/IO/Matlab/ArrayFlags.cs
similarity index 96%
rename from src/Numerics/LinearAlgebra/Common/IO/Matlab/ArrayFlags.cs
rename to src/Numerics/LinearAlgebra/IO/Matlab/ArrayFlags.cs
index 823def1f..621d6603 100644
--- a/src/Numerics/LinearAlgebra/Common/IO/Matlab/ArrayFlags.cs
+++ b/src/Numerics/LinearAlgebra/IO/Matlab/ArrayFlags.cs
@@ -26,7 +26,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
-namespace MathNet.Numerics.LinearAlgebra.Common.IO.Matlab
+namespace MathNet.Numerics.LinearAlgebra.IO.Matlab
{
using System;
diff --git a/src/Numerics/LinearAlgebra/Common/IO/Matlab/DataType.cs b/src/Numerics/LinearAlgebra/IO/Matlab/DataType.cs
similarity index 98%
rename from src/Numerics/LinearAlgebra/Common/IO/Matlab/DataType.cs
rename to src/Numerics/LinearAlgebra/IO/Matlab/DataType.cs
index 53995bbe..2938e444 100644
--- a/src/Numerics/LinearAlgebra/Common/IO/Matlab/DataType.cs
+++ b/src/Numerics/LinearAlgebra/IO/Matlab/DataType.cs
@@ -26,7 +26,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
-namespace MathNet.Numerics.LinearAlgebra.Common.IO.Matlab
+namespace MathNet.Numerics.LinearAlgebra.IO.Matlab
{
///
/// Matlab data types
diff --git a/src/Numerics/LinearAlgebra/IO/Matlab/MatlabFile.cs b/src/Numerics/LinearAlgebra/IO/Matlab/MatlabFile.cs
new file mode 100644
index 00000000..482395a7
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/IO/Matlab/MatlabFile.cs
@@ -0,0 +1,84 @@
+//
+// 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.IO.Matlab
+{
+ using System;
+ using System.Collections.Generic;
+ using Generic;
+
+ ///
+ /// Represents a Matlab file
+ ///
+ /// The data type of the matrix to return.
+ internal class MatlabFile where TDataType : struct, IEquatable, IFormattable
+ {
+ ///
+ /// Matrices in a matlab file stored as 1-D arrays
+ ///
+ private readonly IDictionary> _matrices = new SortedList>();
+
+ ///
+ /// Gets or sets the header text.
+ ///
+ /// The header text.
+ public string HeaderText { get; set; }
+
+ ///
+ /// Gets or sets the first name of the matrix.
+ ///
+ /// The first name of the matrix.
+ public string FirstMatrixName { get; set; }
+
+ ///
+ /// Gets the first matrix.
+ ///
+ /// The first matrix.
+ public Matrix FirstMatrix
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(FirstMatrixName) || !_matrices.ContainsKey(FirstMatrixName))
+ {
+ return null;
+ }
+
+ return _matrices[FirstMatrixName];
+ }
+ }
+
+ ///
+ /// Gets the matrices.
+ ///
+ /// The matrices.
+ public IDictionary> Matrices
+ {
+ get { return _matrices; }
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/IO/Matlab/MatlabParser.cs b/src/Numerics/LinearAlgebra/IO/Matlab/MatlabParser.cs
new file mode 100644
index 00000000..7e4b6010
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/IO/Matlab/MatlabParser.cs
@@ -0,0 +1,1534 @@
+//
+// 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.IO.Matlab
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Numerics;
+ using System.Reflection;
+ using System.Text;
+ using Generic;
+ using Properties;
+ using zlib;
+ using Complex32 = Numerics.Complex32;
+
+ ///
+ /// Parse a Matlab file
+ ///
+ /// The data type of the matrix.
+ internal class MatlabParser
+ where TDataType : struct, IEquatable, IFormattable
+ {
+ ///
+ /// Large Block Size
+ ///
+ private const int LargeBlockSize = 8;
+
+ ///
+ /// Little Endian Indicator
+ ///
+ private const byte LittleEndianIndicator = 0x49;
+
+ ///
+ /// Small Block Size
+ ///
+ private const int SmallBlockSize = 4;
+
+ ///
+ /// Holds the names of the matrices in the file.
+ ///
+ private readonly IList _names = new List();
+
+ ///
+ /// The stream to read the matlab file from.
+ ///
+ private readonly Stream _stream;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Name of the file.
+ public MatlabParser(string fileName)
+ : this(fileName, new string[0])
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The stream to read from.
+ public MatlabParser(Stream stream)
+ : this(stream, new string[0])
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The stream to read from.
+ /// The name of the objects to retrieve.
+ public MatlabParser(Stream stream, IEnumerable objectNames)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ _stream = stream;
+ SetNames(objectNames);
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Name of the file.
+ /// The name of the objects to retrieve.
+ public MatlabParser(string fileName, IEnumerable objectNames)
+ {
+ if (string.IsNullOrEmpty(fileName))
+ {
+ throw new ArgumentException(Resources.StringNullOrEmpty, "filename");
+ }
+
+ _stream = File.OpenRead(fileName);
+ SetNames(objectNames);
+ }
+
+ ///
+ /// Copies the names of the objects to retrieve to a local field.
+ ///
+ /// The name of the objects to retrieve.
+ private void SetNames(IEnumerable objectNames)
+ {
+ foreach (var name in objectNames)
+ {
+ _names.Add(name);
+ }
+ }
+
+ ///
+ /// Parses the file.
+ ///
+ /// The parsed Matlab file as a object.
+ 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;
+ }
+
+ ///
+ /// Aligns the data.
+ ///
+ /// The stream.
+ /// The size of the array.
+ /// if set to true if reading from a small block.
+ 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);
+ }
+
+ ///
+ /// Decompresses the block.
+ ///
+ /// The compressed data.
+ /// The type data type contained in the block.
+ /// The decompressed block.
+ 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;
+ }
+
+ ///
+ /// Adds a matrix from the actual file into our presentation of a matlab file.
+ ///
+ /// The data of the matrix.
+ /// The instance.
+ 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;
+
+ // 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 matrix;
+ switch (arrayClass)
+ {
+ case ArrayClass.Sparse:
+ matrix = PopulateSparseMatrix(reader, isComplex, rows, columns, size);
+ break;
+ case ArrayClass.Function:
+ case ArrayClass.Character:
+ case ArrayClass.Object:
+ case ArrayClass.Structure:
+ case ArrayClass.Cell:
+ case ArrayClass.Unknown:
+ throw new NotSupportedException();
+ default:
+ matrix = PopulateDenseMatrix(type, reader, isComplex, rows, columns);
+ break;
+ }
+
+ file.Matrices.Add(name, matrix);
+ if (file.FirstMatrixName == null)
+ {
+ file.FirstMatrixName = name;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Populates a sparse matrix.
+ ///
+ /// The reader.
+ /// if set to true if the Matlab complex flag is set.
+ /// The number of rows.
+ /// The number of columns.
+ /// The size of the block.
+ /// A populated sparse matrix.
+ private static Matrix PopulateSparseMatrix(BinaryReader reader, bool isComplex, 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);
+
+ var matrix = CreateMatrix(true, rows, columns);
+ var dataType = typeof(TDataType);
+
+ if (dataType == typeof(double))
+ {
+ if (isComplex)
+ {
+ throw new ArgumentException("Invalid TDataType. Matrix is stored as a complex matrix, but a real data type was given.");
+ }
+
+ PopulateDoubleSparseMatrix((Matrix)(object)matrix, type, ir, jc, reader);
+ }
+ else if (dataType == typeof(float))
+ {
+ if (isComplex)
+ {
+ throw new ArgumentException("Invalid TDataType. Matrix is stored as a complex matrix, but a real data type was given.");
+ }
+
+ PopulateSingleSparseMatrix((Matrix)(object)matrix, type, ir, jc, reader);
+ }
+ else if (dataType == typeof(Complex))
+ {
+ PopulateComplexSparseMatrix((Matrix)(object)matrix, type, isComplex, ir, jc, reader);
+ }
+ else if (dataType == typeof(Complex32))
+ {
+ PopulateComplex32SparseMatrix((Matrix)(object)matrix, type, isComplex, ir, jc, reader);
+ }
+ else
+ {
+ throw new NotSupportedException();
+ }
+
+ return matrix;
+ }
+
+ ///
+ /// Populates the double sparse matrix.
+ ///
+ /// The matrix to populate
+ /// The Matlab data type.
+ /// The row indices.
+ /// The column indices.
+ /// The reader to read from.
+ private static void PopulateDoubleSparseMatrix(Matrix matrix, DataType type, IList ir, IList jc, BinaryReader reader)
+ {
+ var col = 0;
+ for (var i = 0; i < ir.Count; i++)
+ {
+ var row = ir[i];
+ if (jc[col + 1] == i)
+ {
+ col++;
+ }
+
+ switch (type)
+ {
+ case DataType.Int8:
+ matrix.At(row, col, reader.ReadSByte());
+ break;
+ case DataType.UInt8:
+ matrix.At(row, col, reader.ReadByte());
+ break;
+ case DataType.Int16:
+ matrix.At(row, col, reader.ReadInt16());
+ break;
+ case DataType.UInt16:
+ matrix.At(row, col, reader.ReadUInt16());
+ break;
+ case DataType.Int32:
+ matrix.At(row, col, reader.ReadInt32());
+ break;
+ case DataType.UInt32:
+ matrix.At(row, col, reader.ReadUInt32());
+ break;
+ case DataType.Single:
+ matrix.At(row, col, reader.ReadSingle());
+ break;
+ case DataType.Int64:
+ matrix.At(row, col, reader.ReadInt64());
+ break;
+ case DataType.UInt64:
+ matrix.At(row, col, reader.ReadUInt64());
+ break;
+ case DataType.Double:
+ matrix.At(row, col, reader.ReadDouble());
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+ }
+
+ ///
+ /// Populates the float sparse matrix.
+ ///
+ /// The matrix to populate
+ /// The Matlab data type.
+ /// The row indices.
+ /// The column indices.
+ /// The reader to read from.
+ private static void PopulateSingleSparseMatrix(Matrix matrix, DataType type, IList ir, IList jc, BinaryReader reader)
+ {
+ var col = 0;
+ for (var i = 0; i < ir.Count; i++)
+ {
+ var row = ir[i];
+ if (jc[col + 1] == i)
+ {
+ col++;
+ }
+
+ switch (type)
+ {
+ case DataType.Int8:
+ matrix.At(row, col, reader.ReadSByte());
+ break;
+ case DataType.UInt8:
+ matrix.At(row, col, reader.ReadByte());
+ break;
+ case DataType.Int16:
+ matrix.At(row, col, reader.ReadInt16());
+ break;
+ case DataType.UInt16:
+ matrix.At(row, col, reader.ReadUInt16());
+ break;
+ case DataType.Int32:
+ matrix.At(row, col, reader.ReadInt32());
+ break;
+ case DataType.UInt32:
+ matrix.At(row, col, reader.ReadUInt32());
+ break;
+ case DataType.Single:
+ matrix.At(row, col, reader.ReadSingle());
+ break;
+ case DataType.Int64:
+ matrix.At(row, col, reader.ReadInt64());
+ break;
+ case DataType.UInt64:
+ matrix.At(row, col, reader.ReadUInt64());
+ break;
+ case DataType.Double:
+ matrix.At(row, col, Convert.ToSingle(reader.ReadDouble()));
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+ }
+
+ ///
+ /// Populates the complex sparse matrix.
+ ///
+ /// The matrix to populate
+ /// The Matlab data type.
+ /// if set to true if the Matlab complex flag is set.
+ /// The row indices.
+ /// The column indices.
+ /// The reader to read from.
+ private static void PopulateComplexSparseMatrix(Matrix matrix, DataType type, bool isComplex, IList ir, IList jc, BinaryReader reader)
+ {
+ var col = 0;
+ for (var i = 0; i < ir.Count; i++)
+ {
+ var row = ir[i];
+ if (jc[col + 1] == i)
+ {
+ col++;
+ }
+
+ switch (type)
+ {
+ case DataType.Int8:
+ matrix.At(row, col, reader.ReadSByte());
+ break;
+ case DataType.UInt8:
+ matrix.At(row, col, reader.ReadByte());
+ break;
+ case DataType.Int16:
+ matrix.At(row, col, reader.ReadInt16());
+ break;
+ case DataType.UInt16:
+ matrix.At(row, col, reader.ReadUInt16());
+ break;
+ case DataType.Int32:
+ matrix.At(row, col, reader.ReadInt32());
+ break;
+ case DataType.UInt32:
+ matrix.At(row, col, reader.ReadUInt32());
+ break;
+ case DataType.Single:
+ matrix.At(row, col, reader.ReadSingle());
+ break;
+ case DataType.Int64:
+ matrix.At(row, col, reader.ReadInt64());
+ break;
+ case DataType.UInt64:
+ matrix.At(row, col, reader.ReadUInt64());
+ break;
+ case DataType.Double:
+ matrix.At(row, col, reader.ReadDouble());
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+
+ if (isComplex)
+ {
+ // skip header
+ reader.ReadBytes(8);
+ col = 0;
+ for (var i = 0; i < ir.Count; i++)
+ {
+ var row = ir[i];
+ if (jc[col + 1] == i)
+ {
+ col++;
+ }
+
+ var real = matrix.At(row, col).Real;
+ switch (type)
+ {
+ case DataType.Int8:
+ matrix.At(row, col, new Complex(real, reader.ReadSByte()));
+ break;
+ case DataType.UInt8:
+ matrix.At(row, col, new Complex(real, reader.ReadByte()));
+ break;
+ case DataType.Int16:
+ matrix.At(row, col, new Complex(real, reader.ReadInt16()));
+ break;
+ case DataType.UInt16:
+ matrix.At(row, col, new Complex(real, reader.ReadUInt16()));
+ break;
+ case DataType.Int32:
+ matrix.At(row, col, new Complex(real, reader.ReadInt32()));
+ break;
+ case DataType.UInt32:
+ matrix.At(row, col, new Complex(real, reader.ReadUInt32()));
+ break;
+ case DataType.Single:
+ matrix.At(row, col, new Complex(real, reader.ReadSingle()));
+ break;
+ case DataType.Int64:
+ matrix.At(row, col, new Complex(real, reader.ReadInt64()));
+ break;
+ case DataType.UInt64:
+ matrix.At(row, col, new Complex(real, reader.ReadUInt64()));
+ break;
+ case DataType.Double:
+ matrix.At(row, col, new Complex(real, reader.ReadDouble()));
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+ }
+ }
+
+ ///
+ /// Populates the complex32 sparse matrix.
+ ///
+ /// The matrix to populate
+ /// The Matlab data type.
+ /// if set to true if the Matlab complex flag is set.
+ /// The row indices.
+ /// The column indices.
+ /// The reader to read from.
+ private static void PopulateComplex32SparseMatrix(Matrix matrix, DataType type, bool isComplex, IList ir, IList jc, BinaryReader reader)
+ {
+ var col = 0;
+ for (var i = 0; i < ir.Count; i++)
+ {
+ var row = ir[i];
+ if (jc[col + 1] == i)
+ {
+ col++;
+ }
+
+ switch (type)
+ {
+ case DataType.Int8:
+ matrix.At(row, col, reader.ReadSByte());
+ break;
+ case DataType.UInt8:
+ matrix.At(row, col, reader.ReadByte());
+ break;
+ case DataType.Int16:
+ matrix.At(row, col, reader.ReadInt16());
+ break;
+ case DataType.UInt16:
+ matrix.At(row, col, reader.ReadUInt16());
+ break;
+ case DataType.Int32:
+ matrix.At(row, col, reader.ReadInt32());
+ break;
+ case DataType.UInt32:
+ matrix.At(row, col, reader.ReadUInt32());
+ break;
+ case DataType.Single:
+ matrix.At(row, col, reader.ReadSingle());
+ break;
+ case DataType.Int64:
+ matrix.At(row, col, reader.ReadInt64());
+ break;
+ case DataType.UInt64:
+ matrix.At(row, col, reader.ReadUInt64());
+ break;
+ case DataType.Double:
+ matrix.At(row, col, Convert.ToSingle(reader.ReadDouble()));
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+
+ if (isComplex)
+ {
+ // skip header
+ reader.ReadBytes(8);
+ col = 0;
+ for (var i = 0; i < ir.Count; i++)
+ {
+ var row = ir[i];
+ if (jc[col + 1] == i)
+ {
+ col++;
+ }
+
+ var real = matrix.At(row, col).Real;
+ switch (type)
+ {
+ case DataType.Int8:
+ matrix.At(row, col, new Complex32(real, reader.ReadSByte()));
+ break;
+ case DataType.UInt8:
+ matrix.At(row, col, new Complex32(real, reader.ReadByte()));
+ break;
+ case DataType.Int16:
+ matrix.At(row, col, new Complex32(real, reader.ReadInt16()));
+ break;
+ case DataType.UInt16:
+ matrix.At(row, col, new Complex32(real, reader.ReadUInt16()));
+ break;
+ case DataType.Int32:
+ matrix.At(row, col, new Complex32(real, reader.ReadInt32()));
+ break;
+ case DataType.UInt32:
+ matrix.At(row, col, new Complex32(real, reader.ReadUInt32()));
+ break;
+ case DataType.Single:
+ matrix.At(row, col, new Complex32(real, reader.ReadSingle()));
+ break;
+ case DataType.Int64:
+ matrix.At(row, col, new Complex32(real, reader.ReadInt64()));
+ break;
+ case DataType.UInt64:
+ matrix.At(row, col, new Complex32(real, reader.ReadUInt64()));
+ break;
+ case DataType.Double:
+ matrix.At(row, col, new Complex32(real, Convert.ToSingle(reader.ReadDouble())));
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+ }
+ }
+
+ ///
+ /// Populates a dense matrix.
+ ///
+ /// The Matlab data type.
+ /// The reader to read from.
+ /// if set to true if the Matlab complex flag is set.
+ /// The number of rows.
+ /// The number of columns.
+ /// Returns a populated dense matrix.
+ private static Matrix PopulateDenseMatrix(DataType type, BinaryReader reader, bool isComplex, int rows, int columns)
+ {
+ var matrix = CreateMatrix(false, rows, columns);
+
+ var dataType = typeof(TDataType);
+
+ if (dataType == typeof(double))
+ {
+ if (isComplex)
+ {
+ throw new ArgumentException("Invalid TDataType. Matrix is stored as a complex matrix, but a real data type was given.");
+ }
+
+ PopulateDoubleDenseMatrix((Matrix)(object)matrix, type, reader, rows, columns);
+ }
+ else if (dataType == typeof(float))
+ {
+ if (isComplex)
+ {
+ throw new ArgumentException("Invalid TDataType. Matrix is stored as a complex matrix, but a real data type was given.");
+ }
+
+ PopulateSingleDenseMatrix((Matrix)(object)matrix, type, reader, rows, columns);
+ }
+ else if (dataType == typeof(Complex))
+ {
+ PopulateComplexDenseMatrix((Matrix)(object)matrix, type, isComplex, reader, rows, columns);
+ }
+ else if (dataType == typeof(Complex32))
+ {
+ PopulateComplex32DenseMatrix((Matrix)(object)matrix, type, isComplex, reader, rows, columns);
+ }
+ else
+ {
+ throw new NotSupportedException();
+ }
+
+ return matrix;
+ }
+
+ ///
+ /// Populates the double dense matrix.
+ ///
+ /// The matrix to populate.
+ /// The Matlab data type.
+ /// The reader to read from.
+ /// The number of rows.
+ /// The number of columns.
+ public static void PopulateDoubleDenseMatrix(Matrix matrix, DataType type, BinaryReader reader, int rows, int columns)
+ {
+ switch (type)
+ {
+ case DataType.Int8:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadSByte());
+ }
+ }
+
+ break;
+ case DataType.UInt8:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadByte());
+ }
+ }
+
+ break;
+ case DataType.Int16:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadInt16());
+ }
+ }
+
+ break;
+ case DataType.UInt16:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadUInt16());
+ }
+ }
+
+ break;
+ case DataType.Int32:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadInt32());
+ }
+ }
+
+ break;
+ case DataType.UInt32:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadUInt32());
+ }
+ }
+
+ break;
+ case DataType.Single:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadSingle());
+ }
+ }
+
+ break;
+ case DataType.Int64:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadInt64());
+ }
+ }
+
+ break;
+ case DataType.UInt64:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadUInt64());
+ }
+ }
+
+ break;
+ case DataType.Double:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadDouble());
+ }
+ }
+
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+
+ ///
+ /// Populates the complex dense matrix.
+ ///
+ /// The matrix to populate.
+ /// The Matlab data type.
+ /// if set to true if the Matlab complex flag is set.
+ /// The reader to read from.
+ /// The number of rows.
+ /// The number of columns.
+ public static void PopulateComplexDenseMatrix(Matrix matrix, DataType type, bool isComplex, BinaryReader reader, int rows, int columns)
+ {
+ switch (type)
+ {
+ case DataType.Int8:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadSByte());
+ }
+ }
+
+ break;
+ case DataType.UInt8:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadByte());
+ }
+ }
+
+ break;
+ case DataType.Int16:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadInt16());
+ }
+ }
+
+ break;
+ case DataType.UInt16:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadUInt16());
+ }
+ }
+
+ break;
+ case DataType.Int32:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadInt32());
+ }
+ }
+
+ break;
+ case DataType.UInt32:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadUInt32());
+ }
+ }
+
+ break;
+ case DataType.Single:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadSingle());
+ }
+ }
+
+ break;
+ case DataType.Int64:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadInt64());
+ }
+ }
+
+ break;
+ case DataType.UInt64:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadUInt64());
+ }
+ }
+
+ break;
+ case DataType.Double:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadDouble());
+ }
+ }
+
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+
+ if (isComplex)
+ {
+ switch (type)
+ {
+ case DataType.Int8:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex(matrix.At(i, j).Real, reader.ReadSByte()));
+ }
+ }
+
+ break;
+ case DataType.UInt8:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex(matrix.At(i, j).Real, reader.ReadByte()));
+ }
+ }
+
+ break;
+ case DataType.Int16:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex(matrix.At(i, j).Real, reader.ReadInt16()));
+ }
+ }
+
+ break;
+ case DataType.UInt16:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex(matrix.At(i, j).Real, reader.ReadUInt16()));
+ }
+ }
+
+ break;
+ case DataType.Int32:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex(matrix.At(i, j).Real, reader.ReadInt32()));
+ }
+ }
+
+ break;
+ case DataType.UInt32:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex(matrix.At(i, j).Real, reader.ReadUInt32()));
+ }
+ }
+
+ break;
+ case DataType.Single:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex(matrix.At(i, j).Real, reader.ReadSingle()));
+ }
+ }
+
+ break;
+ case DataType.Int64:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex(matrix.At(i, j).Real, reader.ReadInt64()));
+ }
+ }
+
+ break;
+ case DataType.UInt64:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex(matrix.At(i, j).Real, reader.ReadUInt64()));
+ }
+ }
+
+ break;
+ case DataType.Double:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex(matrix.At(i, j).Real, reader.ReadDouble()));
+ }
+ }
+
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+ }
+
+ ///
+ /// Populates the complex32 dense matrix.
+ ///
+ /// The matrix to populate.
+ /// The Matlab data type.
+ /// if set to true if the Matlab complex flag is set.
+ /// The reader to read from.
+ /// The number of rows.
+ /// The number of columns.
+ public static void PopulateComplex32DenseMatrix(Matrix matrix, DataType type, bool isComplex, BinaryReader reader, int rows, int columns)
+ {
+ switch (type)
+ {
+ case DataType.Int8:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadSByte());
+ }
+ }
+
+ break;
+ case DataType.UInt8:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadByte());
+ }
+ }
+
+ break;
+ case DataType.Int16:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadInt16());
+ }
+ }
+
+ break;
+ case DataType.UInt16:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadUInt16());
+ }
+ }
+
+ break;
+ case DataType.Int32:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadInt32());
+ }
+ }
+
+ break;
+ case DataType.UInt32:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadUInt32());
+ }
+ }
+
+ break;
+ case DataType.Single:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadSingle());
+ }
+ }
+
+ break;
+ case DataType.Int64:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadInt64());
+ }
+ }
+
+ break;
+ case DataType.UInt64:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadUInt64());
+ }
+ }
+
+ break;
+ case DataType.Double:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, Convert.ToSingle(reader.ReadDouble()));
+ }
+ }
+
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+
+ if (isComplex)
+ {
+ switch (type)
+ {
+ case DataType.Int8:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex32(matrix.At(i, j).Real, reader.ReadSByte()));
+ }
+ }
+
+ break;
+ case DataType.UInt8:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex32(matrix.At(i, j).Real, reader.ReadByte()));
+ }
+ }
+
+ break;
+ case DataType.Int16:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex32(matrix.At(i, j).Real, reader.ReadInt16()));
+ }
+ }
+
+ break;
+ case DataType.UInt16:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex32(matrix.At(i, j).Real, reader.ReadUInt16()));
+ }
+ }
+
+ break;
+ case DataType.Int32:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex32(matrix.At(i, j).Real, reader.ReadInt32()));
+ }
+ }
+
+ break;
+ case DataType.UInt32:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex32(matrix.At(i, j).Real, reader.ReadUInt32()));
+ }
+ }
+
+ break;
+ case DataType.Single:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex32(matrix.At(i, j).Real, reader.ReadSingle()));
+ }
+ }
+
+ break;
+ case DataType.Int64:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex32(matrix.At(i, j).Real, reader.ReadInt64()));
+ }
+ }
+
+ break;
+ case DataType.UInt64:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex32(matrix.At(i, j).Real, reader.ReadUInt64()));
+ }
+ }
+
+ break;
+ case DataType.Double:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, new Complex32(matrix.At(i, j).Real, Convert.ToSingle(reader.ReadDouble())));
+ }
+ }
+
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+ }
+
+ ///
+ /// Populates the float dense matrix.
+ ///
+ /// The matrix to populate.
+ /// The Matlab data type.
+ /// The reader to read from.
+ /// The number of rows.
+ /// The number of columns.
+ public static void PopulateSingleDenseMatrix(Matrix matrix, DataType type, BinaryReader reader, int rows, int columns)
+ {
+ switch (type)
+ {
+ case DataType.Int8:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadSByte());
+ }
+ }
+
+ break;
+ case DataType.UInt8:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadByte());
+ }
+ }
+
+ break;
+ case DataType.Int16:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadInt16());
+ }
+ }
+
+ break;
+ case DataType.UInt16:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadUInt16());
+ }
+ }
+
+ break;
+ case DataType.Int32:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadInt32());
+ }
+ }
+
+ break;
+ case DataType.UInt32:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadUInt32());
+ }
+ }
+
+ break;
+ case DataType.Single:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadSingle());
+ }
+ }
+
+ break;
+ case DataType.Int64:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadInt64());
+ }
+ }
+
+ break;
+ case DataType.UInt64:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, reader.ReadUInt64());
+ }
+ }
+
+ break;
+ case DataType.Double:
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, Convert.ToSingle(reader.ReadDouble()));
+ }
+ }
+
+ break;
+ default:
+ throw new NotSupportedException();
+ }
+ }
+
+ ///
+ /// Creates a matrix.
+ ///
+ /// if set to true, creates a sparse matrix.
+ /// The number of rows.
+ /// The number of columns.
+ /// A matrix with the specified storage.
+ private static Matrix CreateMatrix(bool sparse, int rows, int columns)
+ {
+ ConstructorInfo constructor;
+ var dataType = typeof(TDataType);
+
+ if (sparse)
+ {
+ if (dataType == typeof(double))
+ {
+ constructor = typeof(LinearAlgebra.Double.SparseMatrix).GetConstructor(new[] { typeof(int), typeof(int) });
+ }
+ else if (dataType == typeof(float))
+ {
+ constructor = typeof(LinearAlgebra.Single.SparseMatrix).GetConstructor(new[] { typeof(int), typeof(int) });
+ }
+ else if (dataType == typeof(Complex))
+ {
+ constructor = typeof(LinearAlgebra.Complex.SparseMatrix).GetConstructor(new[] { typeof(int), typeof(int) });
+ }
+ else if (dataType == typeof(Complex32))
+ {
+ constructor = typeof(LinearAlgebra.Complex32.SparseMatrix).GetConstructor(new[] { typeof(int), typeof(int) });
+ }
+ else
+ {
+ throw new NotSupportedException();
+ }
+ }
+ else
+ {
+ if (dataType == typeof(double))
+ {
+ constructor = typeof(LinearAlgebra.Double.DenseMatrix).GetConstructor(new[] { typeof(int), typeof(int) });
+ }
+ else if (dataType == typeof(float))
+ {
+ constructor = typeof(LinearAlgebra.Single.DenseMatrix).GetConstructor(new[] { typeof(int), typeof(int) });
+ }
+ else if (dataType == typeof(Complex))
+ {
+ constructor = typeof(LinearAlgebra.Complex.DenseMatrix).GetConstructor(new[] { typeof(int), typeof(int) });
+ }
+ else if (dataType == typeof(Complex32))
+ {
+ constructor = typeof(LinearAlgebra.Complex32.DenseMatrix).GetConstructor(new[] { typeof(int), typeof(int) });
+ }
+ else
+ {
+ throw new NotSupportedException();
+ }
+ }
+
+ return (Matrix)constructor.Invoke(new object[] { rows, columns });
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/IO/MatlabReader.cs b/src/Numerics/LinearAlgebra/IO/MatlabReader.cs
new file mode 100644
index 00000000..138e38c8
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/IO/MatlabReader.cs
@@ -0,0 +1,192 @@
+//
+// 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.IO
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using Generic;
+ using Matlab;
+ using Properties;
+
+ ///
+ /// Creates matrices from Matlab files.
+ ///
+ /// The data type of the Matrix. It can be either: double, float, Complex, or Complex32.
+ public class MatlabMatrixReader where TDataType : struct, IEquatable, IFormattable
+ {
+ ///
+ /// The name of the file to read from.
+ ///
+ private readonly string _filename;
+
+ ///
+ /// The stream to read from if we are not reading from a file directly.
+ ///
+ private readonly Stream _stream;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Name of the file to read matrices from.
+ 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;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The stream to reader matrices from.
+ public MatlabMatrixReader(Stream stream)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ _stream = stream;
+ }
+
+ ///
+ /// Reads the first matrix from the file or stream.
+ ///
+ ///
+ /// A sparse or dense matrix depending on how the matrix
+ /// is defined in the Matlab file.
+ ///
+ public Matrix ReadMatrix()
+ {
+ return ReadMatrix(null);
+ }
+
+ ///
+ /// Reads the named matrix from the file or stream.
+ ///
+ /// The name of the matrix to read.
+ ///
+ /// A sparse or dense matrix depending on how the matrix
+ /// is defined in the Matlab file.
+ /// is returned if a matrix with the requests name doesn't exist.
+ ///
+ public Matrix 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(stream, names);
+ var file = parser.Parse();
+
+ Matrix 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;
+ }
+
+ ///
+ /// Reads all matrices from the file or stream.
+ ///
+ /// All matrices from the file or stream.
+ public Matrix[] ReadMatrices()
+ {
+ return ReadMatrices(new string[] { });
+ }
+
+ ///
+ /// Reads the named matrices from the file or stream.
+ ///
+ /// The names of the matrices to retrieve.
+ ///
+ /// The named matrices from the file or stream.
+ ///
+ public Matrix[] ReadMatrices(IEnumerable 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[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;
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/Single/IO/DelimitedWriter.cs b/src/Numerics/LinearAlgebra/Single/IO/DelimitedWriter.cs
new file mode 100644
index 00000000..f674105e
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Single/IO/DelimitedWriter.cs
@@ -0,0 +1,70 @@
+//
+// 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.Single.IO
+{
+ using Generic;
+ using LinearAlgebra.IO;
+
+ ///
+ /// Writes an to delimited text file. If the user does not
+ /// specify a delimiter, a tab separator is used.
+ ///
+ public class DelimitedWriter : DelimitedWriter
+ {
+ ///
+ /// Initializes a new instance of the class.
+ /// a comma as the delimiter.
+ ///
+ public DelimitedWriter()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// using the given delimiter.
+ ///
+ ///
+ /// the delimiter to use.
+ ///
+ public DelimitedWriter(char delimiter) : base(delimiter)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// using the given delimiter.
+ ///
+ ///
+ /// the delimiter to use.
+ ///
+ public DelimitedWriter(string delimiter) : base(delimiter)
+ {
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/Single/IO/Matlab/MatlabFile.cs b/src/Numerics/LinearAlgebra/Single/IO/Matlab/MatlabFile.cs
deleted file mode 100644
index 01b216fe..00000000
--- a/src/Numerics/LinearAlgebra/Single/IO/Matlab/MatlabFile.cs
+++ /dev/null
@@ -1,219 +0,0 @@
-//
-// 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.Single.IO.Matlab
-{
- using System.Collections.Generic;
- using Generic;
-
- ///
- /// Represents a Matlab file
- ///
- internal class MatlabFile
- {
- ///
- /// Matrices in a matlab file stored as 1-D arrays
- ///
- private readonly IDictionary> _matrices = new SortedList>();
-
- ///
- /// Gets or sets the header text.
- ///
- /// The header text.
- public string HeaderText { get; set; }
-
- ///
- /// Gets or sets the first name of the matrix.
- ///
- /// The first name of the matrix.
- public string FirstMatrixName { get; set; }
-
- ///
- /// Gets the first matrix.
- ///
- /// The first matrix.
- public Matrix FirstMatrix
- {
- get
- {
- if (string.IsNullOrEmpty(FirstMatrixName) || !_matrices.ContainsKey(FirstMatrixName))
- {
- return null;
- }
-
- return _matrices[FirstMatrixName];
- }
- }
-
- ///
- /// Gets the matrices.
- ///
- /// The matrices.
- public IDictionary> Matrices
- {
- get { return _matrices; }
- }
- }
-
- /*
- ///
- /// An
- ///
- ///
- ///
- internal class ListDictionary : IDictionary
- {
- private readonly IList _keys = new List();
- private readonly IList _values = new List();
-
- public void Add(T key, K value)
- {
- _keys.Add(key);
- _values.Add(value);
- }
-
- public bool ContainsKey(T key)
- {
- return _keys.Contains(key);
- }
-
- public ICollection 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 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 item)
- {
- Add(item.Key, item.Value);
- }
-
- public void Clear()
- {
- _keys.Clear();
- _values.Clear();
- }
-
- public bool Contains(KeyValuePair item)
- {
- return _keys.Contains(item.Key) && _values[_keys.IndexOf(item.Key)].Equals(item.Value);
- }
-
- public void CopyTo(KeyValuePair[] array, int arrayIndex)
- {
- for (int i = 0; i < _keys.Count; i++)
- {
- array[arrayIndex + i] = new KeyValuePair(_keys[i], _values[i]);
- }
- }
-
- public int Count
- {
- get { return _keys.Count; }
- }
-
- public bool IsReadOnly
- {
- get { return false; }
- }
-
- public bool Remove(KeyValuePair item)
- {
- if (Contains(item))
- {
- Remove(item.Key);
- return true;
- }
- return false;
- }
-
- public IEnumerator> GetEnumerator()
- {
- for (int i = 0; i < _keys.Count; i++)
- {
- yield return new KeyValuePair(_keys[i], _values[i]);
- }
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
-
- }*/
-}
diff --git a/src/Numerics/LinearAlgebra/Single/IO/Matlab/MatlabParser.cs b/src/Numerics/LinearAlgebra/Single/IO/Matlab/MatlabParser.cs
deleted file mode 100644
index 5c626022..00000000
--- a/src/Numerics/LinearAlgebra/Single/IO/Matlab/MatlabParser.cs
+++ /dev/null
@@ -1,536 +0,0 @@
-//
-// 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.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;
-
- ///
- /// Parse a Matlab file
- ///
- internal class MatlabParser
- {
- ///
- /// Large Block Size
- ///
- private const int LargeBlockSize = 8;
-
- ///
- /// Little Endian Indicator
- ///
- private const byte LittleEndianIndicator = 0x49;
-
- ///
- /// Small Block Size
- ///
- private const int SmallBlockSize = 4;
-
- ///
- /// Holds the names of the matrices in the file.
- ///
- private readonly IList _names = new List();
-
- ///
- /// The stream to read the matlab file from.
- ///
- private readonly Stream _stream;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// Name of the file.
- public MatlabParser(string fileName)
- : this(fileName, new string[0])
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The stream to read from.
- public MatlabParser(Stream stream)
- : this(stream, new string[0])
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The stream to read from.
- /// The name of the objects to retrieve.
- public MatlabParser(Stream stream, IEnumerable objectNames)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- _stream = stream;
- SetNames(objectNames);
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// Name of the file.
- /// The name of the objects to retrieve.
- public MatlabParser(string fileName, IEnumerable objectNames)
- {
- if (string.IsNullOrEmpty(fileName))
- {
- throw new ArgumentException(Resources.StringNullOrEmpty, "filename");
- }
-
- _stream = File.OpenRead(fileName);
- SetNames(objectNames);
- }
-
- ///
- /// Copies the names of the objects to retrieve to a local field.
- ///
- /// The name of the objects to retrieve.
- private void SetNames(IEnumerable objectNames)
- {
- foreach (var name in objectNames)
- {
- _names.Add(name);
- }
- }
-
- ///
- /// Parses the file.
- ///
- /// The parsed Matlab file as a object.
- 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;
- }
-
- ///
- /// Aligns the data.
- ///
- /// The stream.
- /// The size of the array.
- /// if set to true if reading from a small block.
- 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);
- }
-
- ///
- /// Decompresses the block.
- ///
- /// The compressed data.
- /// The type data type contained in the block.
- /// The decompressed block.
- 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;
- }
-
- ///
- /// Adds a matrix from the actual file into our presentation of a matlab file.
- ///
- /// The data of the matrix.
- /// The instance.
- 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 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;
- }
- }
- }
- }
-
- ///
- /// Populates a sparse matrix.
- ///
- /// The reader.
- /// The number of rows.
- /// The number of columns.
- /// The size of the block.
- /// A populated sparse matrix.
- private static Matrix 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 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;
- }
-
- ///
- /// Populates a dense matrix.
- ///
- /// The type of data.
- /// The reader.
- /// The number of rows.
- /// The number of columns.
- /// Returns a populated dense matrix.
- private static Matrix PopulateDenseMatrix(DataType type, BinaryReader reader, int rows, int columns)
- {
- Matrix 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;
- }
- }
-}
diff --git a/src/Numerics/LinearAlgebra/Single/IO/MatlabReader.cs b/src/Numerics/LinearAlgebra/Single/IO/MatlabReader.cs
index 2c748eaa..9544af0b 100644
--- a/src/Numerics/LinearAlgebra/Single/IO/MatlabReader.cs
+++ b/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;
///
/// Creates matrices from Matlab files.
///
- public class MatlabMatrixReader
+ public class MatlabMatrixReader : MatlabMatrixReader
{
- ///
- /// The name of the file to read from.
- ///
- private readonly string _filename;
-
- ///
- /// The stream to read from if we are not reading from a file directly.
- ///
- private readonly Stream _stream;
-
///
/// Initializes a new instance of the class.
///
/// Name of the file to read matrices from.
- 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;
}
///
/// Initializes a new instance of the class.
///
/// The stream to reader matrices from.
- public MatlabMatrixReader(Stream stream)
- {
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- _stream = stream;
- }
-
- ///
- /// Reads the first matrix from the file or stream.
- ///
- ///
- /// If the matrix is stored as a sparse matrix, then a is returned. Otherwise, a
- /// is returned.
- ///
- public Matrix ReadMatrix()
- {
- return ReadMatrix(null);
- }
-
- ///
- /// Reads the named matrix from the file or stream.
- ///
- /// The name of the matrix to read.
- ///
- /// If the matrix is stored as a sparse matrix, then a is returned. Otherwise, a
- /// is returned. is returned if a matrix with the requests name doesn't exist.
- ///
- public Matrix 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 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;
- }
-
- ///
- /// Reads all matrices from the file or stream.
- ///
- /// All matrices from the file or stream.
- public Matrix[] ReadMatrices()
- {
- return ReadMatrices(new string[] { });
- }
-
- ///
- /// Reads the named matrices from the file or stream.
- ///
- /// The names of the matrices to retrieve.
- ///
- /// The named matrices from the file or stream.
- ///
- public Matrix[] ReadMatrices(IEnumerable 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[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;
}
}
}
diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj
index b40e4363..d76d3fb4 100644
--- a/src/Numerics/Numerics.csproj
+++ b/src/Numerics/Numerics.csproj
@@ -124,9 +124,15 @@
-
-
-
+
+
+
+
+
+
+
+
+
@@ -222,9 +228,8 @@
+
-
-
@@ -261,8 +266,8 @@
-
-
+
+
diff --git a/src/UnitTests/LinearAlgebraTests/Complex/IO/DelimitedWriterTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/IO/DelimitedWriterTests.cs
index a60a3893..d2a2575b 100644
--- a/src/UnitTests/LinearAlgebraTests/Complex/IO/DelimitedWriterTests.cs
+++ b/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(',');
+ 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('.')
+ 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(' ');
+ 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('\t')
+ var writer = new DelimitedWriter('\t')
{
ColumnHeaders = headers
};
diff --git a/src/UnitTests/LinearAlgebraTests/Complex/IO/MatlabReaderTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/IO/MatlabReaderTests.cs
new file mode 100644
index 00000000..d401fc78
--- /dev/null
+++ b/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);
+ }
+ }
+}
diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/IO/DelimitedWriterTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/IO/DelimitedWriterTests.cs
index b65a3737..f8c7a9a9 100644
--- a/src/UnitTests/LinearAlgebraTests/Complex32/IO/DelimitedWriterTests.cs
+++ b/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(',');
+ 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('.')
+ 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(' ');
+ 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('\t')
+ var writer = new DelimitedWriter('\t')
{
ColumnHeaders = headers
};
diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/IO/MatlabReaderTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/IO/MatlabReaderTests.cs
new file mode 100644
index 00000000..47504e3b
--- /dev/null
+++ b/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);
+ }
+ }
+}
diff --git a/src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedWriterTests.cs b/src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedWriterTests.cs
index 62cef298..8fa3cf63 100644
--- a/src/UnitTests/LinearAlgebraTests/Double/IO/DelimitedWriterTests.cs
+++ b/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(',');
+ 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('.')
+ 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(' ');
+ 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('\t')
+ var writer = new DelimitedWriter('\t')
{
ColumnHeaders = headers
};
diff --git a/src/UnitTests/LinearAlgebraTests/Single/IO/DelimitedWriterTests.cs b/src/UnitTests/LinearAlgebraTests/Single/IO/DelimitedWriterTests.cs
index d819220e..e8c1c3fc 100644
--- a/src/UnitTests/LinearAlgebraTests/Single/IO/DelimitedWriterTests.cs
+++ b/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(',');
+ 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('.')
+ 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(' ');
+ 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('\t')
+ var writer = new DelimitedWriter('\t')
{
ColumnHeaders = headers
};
diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj
index 57a8d2ac..40aca2c6 100644
--- a/src/UnitTests/UnitTests.csproj
+++ b/src/UnitTests/UnitTests.csproj
@@ -138,6 +138,7 @@
+
@@ -182,6 +183,7 @@
+