diff --git a/src/Data/Matlab/ArrayClass.cs b/src/Data/Matlab/ArrayClass.cs
index 13d48cde..3241fe2e 100644
--- a/src/Data/Matlab/ArrayClass.cs
+++ b/src/Data/Matlab/ArrayClass.cs
@@ -31,7 +31,7 @@
namespace MathNet.Numerics.Data.Matlab
{
///
- /// Enumeration for the Matlab array types
+ /// Enumeration for the MATLAB array types
///
internal enum ArrayClass : byte
{
diff --git a/src/Data/Matlab/ArrayFlags.cs b/src/Data/Matlab/ArrayFlags.cs
index d46b7d1e..5e1debc7 100644
--- a/src/Data/Matlab/ArrayFlags.cs
+++ b/src/Data/Matlab/ArrayFlags.cs
@@ -33,7 +33,7 @@ using System;
namespace MathNet.Numerics.Data.Matlab
{
///
- /// Matlab Array Flags
+ /// MATLAB Array Flags
///
[Flags]
internal enum ArrayFlags
diff --git a/src/Data/Matlab/DataType.cs b/src/Data/Matlab/DataType.cs
index e3ef4dac..df850313 100644
--- a/src/Data/Matlab/DataType.cs
+++ b/src/Data/Matlab/DataType.cs
@@ -31,7 +31,7 @@
namespace MathNet.Numerics.Data.Matlab
{
///
- /// Matlab data types
+ /// MATLAB data types
///
internal enum DataType
{
diff --git a/src/Data/Matlab/Matlab.csproj b/src/Data/Matlab/Matlab.csproj
index c70a1bc7..6e4f7cff 100644
--- a/src/Data/Matlab/Matlab.csproj
+++ b/src/Data/Matlab/Matlab.csproj
@@ -51,6 +51,8 @@
+
+
diff --git a/src/Data/Matlab/MatlabFile.cs b/src/Data/Matlab/MatlabFile.cs
index 46322ec6..ab4cd184 100644
--- a/src/Data/Matlab/MatlabFile.cs
+++ b/src/Data/Matlab/MatlabFile.cs
@@ -35,13 +35,13 @@ using MathNet.Numerics.LinearAlgebra;
namespace MathNet.Numerics.Data.Matlab
{
///
- /// Represents a Matlab file
+ /// 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
+ /// Matrices in a MATLAB file stored as 1-D arrays
///
readonly IDictionary> _matrices = new SortedList>();
@@ -49,19 +49,19 @@ namespace MathNet.Numerics.Data.Matlab
/// Gets or sets the header text.
///
/// The header text.
- public string HeaderText { get; set; }
+ internal string HeaderText { get; set; }
///
/// Gets or sets the first name of the matrix.
///
/// The first name of the matrix.
- public string FirstMatrixName { get; set; }
+ internal string FirstMatrixName { get; set; }
///
/// Gets the first matrix.
///
/// The first matrix.
- public Matrix FirstMatrix
+ internal Matrix FirstMatrix
{
get
{
@@ -78,7 +78,7 @@ namespace MathNet.Numerics.Data.Matlab
/// Gets the matrices.
///
/// The matrices.
- public IDictionary> Matrices
+ internal IDictionary> Matrices
{
get { return _matrices; }
}
diff --git a/src/Data/Matlab/MatlabParser.cs b/src/Data/Matlab/MatlabParser.cs
index 31f44b9b..addf924e 100644
--- a/src/Data/Matlab/MatlabParser.cs
+++ b/src/Data/Matlab/MatlabParser.cs
@@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
-// Copyright (c) 2009-2013 Math.NET
+// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -32,7 +32,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
-using System.Numerics;
using System.Text;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.Properties;
@@ -40,7 +39,7 @@ using MathNet.Numerics.Properties;
namespace MathNet.Numerics.Data.Matlab
{
///
- /// Parse a Matlab file
+ /// Parse a MATLAB file
///
/// The data type of the matrix.
internal class MatlabParser
@@ -67,7 +66,7 @@ namespace MathNet.Numerics.Data.Matlab
readonly IList _names = new List();
///
- /// The stream to read the matlab file from.
+ /// The stream to read the MATLAB file from.
///
readonly Stream _stream;
@@ -75,7 +74,7 @@ namespace MathNet.Numerics.Data.Matlab
/// Initializes a new instance of the class.
///
/// Name of the file.
- public MatlabParser(string fileName)
+ internal MatlabParser(string fileName)
: this(fileName, new string[0])
{
}
@@ -84,7 +83,7 @@ namespace MathNet.Numerics.Data.Matlab
/// Initializes a new instance of the class.
///
/// The stream to read from.
- public MatlabParser(Stream stream)
+ internal MatlabParser(Stream stream)
: this(stream, new string[0])
{
}
@@ -94,7 +93,7 @@ namespace MathNet.Numerics.Data.Matlab
///
/// The stream to read from.
/// The name of the objects to retrieve.
- public MatlabParser(Stream stream, IEnumerable objectNames)
+ internal MatlabParser(Stream stream, IEnumerable objectNames)
{
if (stream == null)
{
@@ -110,7 +109,7 @@ namespace MathNet.Numerics.Data.Matlab
///
/// Name of the file.
/// The name of the objects to retrieve.
- public MatlabParser(string fileName, IEnumerable objectNames)
+ MatlabParser(string fileName, IEnumerable objectNames)
{
if (string.IsNullOrEmpty(fileName))
{
@@ -136,8 +135,8 @@ namespace MathNet.Numerics.Data.Matlab
///
/// Parses the file.
///
- /// The parsed Matlab file as a object.
- public MatlabFile Parse()
+ /// The parsed MATLAB file as a object.
+ internal MatlabFile Parse()
{
var file = new MatlabFile();
@@ -157,7 +156,7 @@ namespace MathNet.Numerics.Data.Matlab
reader.BaseStream.Position = 128;
var length = _stream.Length;
- // for each data block add a Matlab object to the file.
+ // for each data block add a MATLAB object to the file.
while (reader.BaseStream.Position < length)
{
var type = (DataType)reader.ReadInt16();
@@ -201,7 +200,7 @@ namespace MathNet.Numerics.Data.Matlab
/// The stream.
/// The size of the array.
/// if set to true if reading from a small block.
- static void AlignData(Stream stream, int size, bool smallBlock)
+ internal static void AlignData(Stream stream, int size, bool smallBlock)
{
var blockSize = smallBlock ? SmallBlockSize : LargeBlockSize;
var offset = 0;
@@ -224,1363 +223,102 @@ namespace MathNet.Numerics.Data.Matlab
{
byte[] data;
using (var compressedStream = new MemoryStream(compressed, 2, compressed.Length - 6))
+ using (var decompressor = new DeflateStream(compressedStream, CompressionMode.Decompress))
+ using (var decompressed = new MemoryStream())
{
- using (var decompressor = new DeflateStream(compressedStream, CompressionMode.Decompress))
- using (var decompressed = new MemoryStream())
- {
- decompressor.CopyTo(decompressed);
- 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);
- }
+ decompressor.CopyTo(decompressed);
+ 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.
+ /// Adds a matrix from the actual file into our presentation of a MATLAB file.
///
/// The data of the matrix.
/// The instance.
void AddMatrix(byte[] data, MatlabFile file)
{
using (var ms = new MemoryStream(data))
+ using (var reader = new BinaryReader(ms))
{
- 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, size);
- 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.
- 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();
- }
+ // skip tag - doesn't tell us anything we don't already know
+ reader.BaseStream.Seek(8, SeekOrigin.Current);
- AlignData(reader.BaseStream, size, false);
+ var arrayClass = (ArrayClass)reader.ReadByte();
+ var flags = reader.ReadByte();
+ var isComplex = (flags & (byte)ArrayFlags.Complex) == (byte)ArrayFlags.Complex;
- // skip data type since it will always be int32
- reader.BaseStream.Seek(4, SeekOrigin.Current);
+ // skip unneeded bytes
+ reader.BaseStream.Seek(10, 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();
- var dataSize = reader.ReadInt32();
-
- var matrix = Matrix.Build.Sparse(rows, columns);
- var dataType = typeof (TDataType);
-
- if (dataType == typeof (double))
- {
- if (isComplex)
+ var numDimensions = reader.ReadInt32()/8;
+ if (numDimensions > 2)
{
- throw new ArgumentException("Invalid TDataType. Matrix is stored as a complex matrix, but a real data type was given.");
+ throw new NotSupportedException(Resources.MoreThan2D);
}
- 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.");
- }
+ var rows = reader.ReadInt32();
+ var columns = reader.ReadInt32();
- PopulateSingleSparseMatrix((Matrix)(object)matrix, type, ir, jc, reader);
- }
- else if (dataType == typeof (Complex))
- {
- PopulateComplexSparseMatrix((Matrix)(object)matrix, type, isComplex, ir, jc, reader, dataSize);
- }
- else if (dataType == typeof (Complex32))
- {
- PopulateComplex32SparseMatrix((Matrix)(object)matrix, type, isComplex, ir, jc, reader, dataSize);
- }
- 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.
- 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];
- while (jc[col + 1] == i)
+ // skip unneeded bytes
+ reader.BaseStream.Seek(2, SeekOrigin.Current);
+ int size = reader.ReadInt16();
+ var smallBlock = true;
+ if (size == 0)
{
- col++;
+ size = reader.ReadInt32();
+ smallBlock = false;
}
- 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();
- }
- }
- }
+ var name = Encoding.ASCII.GetString(reader.ReadBytes(size));
+ AlignData(reader.BaseStream, size, smallBlock);
- ///
- /// Populates the float sparse matrix.
- ///
- /// The matrix to populate
- /// The Matlab data type.
- /// The row indices.
- /// The column indices.
- /// The reader to read from.
- 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];
- while (jc[col + 1] == i)
+ // only grab wanted objects
+ if (_names.Count != 0 && !_names.Contains(name))
{
- col++;
+ return;
}
- switch (type)
+ var type = (DataType)reader.ReadInt16();
+ size = reader.ReadInt16();
+ if (size == 0)
{
- 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.
- /// The length of the stored data.
- static void PopulateComplexSparseMatrix(Matrix matrix, DataType type, bool isComplex, IList ir, IList jc, BinaryReader reader, int dataSize)
- {
- var col = 0;
- for (var i = 0; i < ir.Count; i++)
- {
- var row = ir[i];
- while (jc[col + 1] == i)
- {
- col++;
+ size = reader.ReadInt32();
}
- switch (type)
+ Matrix matrix;
+ switch (arrayClass)
{
- 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:
+ case ArrayClass.Sparse:
+ matrix = SparseArrayReader.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();
- }
- }
-
- if (isComplex)
- {
- var skip = dataSize%8;
-
- // skip pad
- reader.ReadBytes(skip);
-
- // skip header
- type = (DataType)reader.ReadInt32();
- reader.ReadInt32();
- col = 0;
- for (var i = 0; i < ir.Count; i++)
- {
- var row = ir[i];
- while (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.
- /// The length of the stored data.
- static void PopulateComplex32SparseMatrix(Matrix matrix, DataType type, bool isComplex, IList ir, IList jc, BinaryReader reader, int dataSize)
- {
- var col = 0;
- for (var i = 0; i < ir.Count; i++)
- {
- var row = ir[i];
- while (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)
- {
- var skip = dataSize%8;
-
- // skip pad
- reader.ReadBytes(skip);
-
- // skip header
- type = (DataType)reader.ReadInt32();
- reader.ReadInt32();
-
- col = 0;
- for (var i = 0; i < ir.Count; i++)
- {
- var row = ir[i];
- while (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.
- /// The length of the stored data.
- /// Returns a populated dense matrix.
- static Matrix PopulateDenseMatrix(DataType type, BinaryReader reader, bool isComplex, int rows, int columns, int size)
- {
- var dataType = typeof (TDataType);
- Matrix matrix;
- if (type == DataType.Double && dataType == typeof (double))
- {
- var count = rows*columns;
- var data = new double[count];
- Buffer.BlockCopy(reader.ReadBytes(count*Constants.SizeOfDouble), 0, data, 0, count*Constants.SizeOfDouble);
- matrix = (Matrix)(object)new LinearAlgebra.Double.DenseMatrix(rows, columns, data);
- }
- else if (type == DataType.Single && dataType == typeof (float))
- {
- var count = rows*columns;
- var data = new float[count];
- Buffer.BlockCopy(reader.ReadBytes(count*Constants.SizeOfFloat), 0, data, 0, count*Constants.SizeOfFloat);
- matrix = (Matrix)(object)new LinearAlgebra.Single.DenseMatrix(rows, columns, data);
- }
- else
- {
- matrix = Matrix.Build.Dense(rows, columns);
-
- 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, size);
- }
- else if (dataType == typeof (Complex32))
- {
- PopulateComplex32DenseMatrix((Matrix)(object)matrix, type, isComplex, reader, rows, columns, size);
- }
- 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.
- /// The length of the stored data.
- public static void PopulateComplexDenseMatrix(Matrix matrix, DataType type, bool isComplex, BinaryReader reader, int rows, int columns, int dataSize)
- {
- 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)
- {
- var skip = dataSize%8;
-
- // skip pad
- reader.ReadBytes(skip);
-
- // skip header
- type = (DataType)reader.ReadInt32();
- reader.ReadInt32();
-
- 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()));
- }
- }
-
+ matrix = NumericArrayReader.PopulateDenseMatrix(type, reader, isComplex, rows, columns, size);
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.
- /// The length of the stored data.
- public static void PopulateComplex32DenseMatrix(Matrix matrix, DataType type, bool isComplex, BinaryReader reader, int rows, int columns, int dataSize)
- {
- 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)
- {
- var skip = dataSize%8;
-
- // skip pad
- reader.ReadBytes(skip);
-
- // skip header
- type = (DataType)reader.ReadInt32();
- reader.ReadInt32();
-
- switch (type)
+ file.Matrices.Add(name, matrix);
+ if (file.FirstMatrixName == null)
{
- 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();
+ file.FirstMatrixName = name;
}
}
}
-
- ///
- /// 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();
- }
- }
}
}
diff --git a/src/Data/Matlab/MatlabReader.cs b/src/Data/Matlab/MatlabReader.cs
index d4043df4..fdef0882 100644
--- a/src/Data/Matlab/MatlabReader.cs
+++ b/src/Data/Matlab/MatlabReader.cs
@@ -37,7 +37,7 @@ using MathNet.Numerics.LinearAlgebra;
namespace MathNet.Numerics.Data.Matlab
{
///
- /// Creates matrices from Matlab files.
+ /// Creates matrices from MATLAB files.
///
public static class MatlabMatrixReader
{
diff --git a/src/Data/Matlab/MatlabWriter.cs b/src/Data/Matlab/MatlabWriter.cs
index bb9967ae..3445d156 100644
--- a/src/Data/Matlab/MatlabWriter.cs
+++ b/src/Data/Matlab/MatlabWriter.cs
@@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
-// Copyright (c) 2009-2013 Math.NET
+// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -41,7 +41,7 @@ using MathNet.Numerics.Properties;
namespace MathNet.Numerics.Data.Matlab
{
///
- /// Writes matrices to a Matlab file.
+ /// Writes matrices to a MATLAB file.
///
public class MatlabMatrixWriter : IDisposable
{
@@ -68,7 +68,7 @@ namespace MathNet.Numerics.Data.Matlab
///
/// Initializes a new instance of the class.
///
- /// The name of the Matlab file to save the matrices to.
+ /// The name of the MATLAB file to save the matrices to.
public MatlabMatrixWriter(string filename)
{
if (string.IsNullOrEmpty(filename))
@@ -95,7 +95,7 @@ namespace MathNet.Numerics.Data.Matlab
}
///
- /// Writes the given to the file.
+ /// Writes the given to the file.
///
/// The matrix to write.
/// The name of the matrix to store in the file.
@@ -125,7 +125,7 @@ namespace MathNet.Numerics.Data.Matlab
_headerWritten = true;
}
- // write datatype
+ // write data type
_writer.Write((int)DataType.Compressed);
byte[] data;
@@ -212,7 +212,7 @@ namespace MathNet.Numerics.Data.Matlab
/// The writer we are using.
/// The array class we are writing.
/// if set to true if this a complex matrix.
- /// The name name of the matrix.
+ /// The name of the matrix.
/// The number of rows.
/// The columns of columns.
/// The maximum number of non-zero elements.
@@ -228,7 +228,7 @@ namespace MathNet.Numerics.Data.Matlab
writer.Write((int)DataType.UInt32);
writer.Write(8);
- // write array class and flags
+ // write array class and flags
writer.Write((byte)arrayClass);
if (isComplex)
{
diff --git a/src/Data/Matlab/NumericArrayReader.cs b/src/Data/Matlab/NumericArrayReader.cs
new file mode 100644
index 00000000..799ce4c2
--- /dev/null
+++ b/src/Data/Matlab/NumericArrayReader.cs
@@ -0,0 +1,257 @@
+//
+// 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-2014 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.IO;
+using System.Numerics;
+using MathNet.Numerics.LinearAlgebra;
+
+namespace MathNet.Numerics.Data.Matlab
+{
+ internal static class NumericArrayReader
+ where TDataType : struct, IEquatable, IFormattable
+ {
+ ///
+ /// 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.
+ /// The length of the stored data.
+ /// Returns a populated dense matrix.
+ public static Matrix PopulateDenseMatrix(DataType type, BinaryReader reader, bool isComplex, int rows, int columns, int size)
+ {
+ var dataType = typeof (TDataType);
+ Matrix matrix;
+ if (type == DataType.Double && dataType == typeof (double))
+ {
+ var count = rows*columns;
+ var data = new double[count];
+ Buffer.BlockCopy(reader.ReadBytes(count*Constants.SizeOfDouble), 0, data, 0, count*Constants.SizeOfDouble);
+ matrix = (Matrix)(object)new LinearAlgebra.Double.DenseMatrix(rows, columns, data);
+ }
+ else if (type == DataType.Single && dataType == typeof (float))
+ {
+ var count = rows*columns;
+ var data = new float[count];
+ Buffer.BlockCopy(reader.ReadBytes(count*Constants.SizeOfFloat), 0, data, 0, count*Constants.SizeOfFloat);
+ matrix = (Matrix)(object)new LinearAlgebra.Single.DenseMatrix(rows, columns, data);
+ }
+ else
+ {
+ matrix = Matrix.Build.Dense(rows, columns);
+
+ 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, size);
+ }
+ else if (dataType == typeof (Complex32))
+ {
+ PopulateComplex32DenseMatrix((Matrix)(object)matrix, type, isComplex, reader, rows, columns, size);
+ }
+ 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.
+ static void PopulateDoubleDenseMatrix(Matrix matrix, DataType type, BinaryReader reader, int rows, int columns)
+ {
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, ReadDoubleValue(type, reader));
+ }
+ }
+ }
+
+ ///
+ /// 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.
+ /// The length of the stored data.
+ static void PopulateComplexDenseMatrix(Matrix matrix, DataType type, bool isComplex, BinaryReader reader, int rows, int columns, int dataSize)
+ {
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, ReadDoubleValue(type, reader));
+ }
+ }
+
+ if (isComplex)
+ {
+ var skip = dataSize%8;
+
+ // skip pad
+ reader.ReadBytes(skip);
+
+ // skip header
+ type = (DataType)reader.ReadInt32();
+ reader.ReadInt32();
+
+ 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, ReadDoubleValue(type, reader)));
+ }
+ }
+ }
+ }
+
+ ///
+ /// 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.
+ /// The length of the stored data.
+ static void PopulateComplex32DenseMatrix(Matrix matrix, DataType type, bool isComplex, BinaryReader reader, int rows, int columns, int dataSize)
+ {
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, (float)ReadDoubleValue(type, reader));
+ }
+ }
+
+ if (isComplex)
+ {
+ var skip = dataSize%8;
+
+ // skip pad
+ reader.ReadBytes(skip);
+
+ // skip header
+ type = (DataType)reader.ReadInt32();
+ reader.ReadInt32();
+
+ 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, (float)ReadDoubleValue(type, reader)));
+ }
+ }
+ }
+ }
+
+ ///
+ /// 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.
+ static void PopulateSingleDenseMatrix(Matrix matrix, DataType type, BinaryReader reader, int rows, int columns)
+ {
+ for (var j = 0; j < columns; j++)
+ {
+ for (var i = 0; i < rows; i++)
+ {
+ matrix.At(i, j, (float)ReadDoubleValue(type, reader));
+ }
+ }
+ }
+
+ static double ReadDoubleValue(DataType type, BinaryReader reader)
+ {
+ switch (type)
+ {
+ case DataType.Double:
+ return reader.ReadDouble();
+ case DataType.Int8:
+ return reader.ReadSByte();
+ case DataType.UInt8:
+ return reader.ReadByte();
+ case DataType.Int16:
+ return reader.ReadInt16();
+ case DataType.UInt16:
+ return reader.ReadUInt16();
+ case DataType.Int32:
+ return reader.ReadInt32();
+ case DataType.UInt32:
+ return reader.ReadUInt32();
+ case DataType.Single:
+ return reader.ReadSingle();
+ case DataType.Int64:
+ return reader.ReadInt64();
+ case DataType.UInt64:
+ return reader.ReadUInt64();
+ default:
+ throw new NotSupportedException();
+ }
+ }
+ }
+}
diff --git a/src/Data/Matlab/SparseArrayReader.cs b/src/Data/Matlab/SparseArrayReader.cs
new file mode 100644
index 00000000..3d7aabf3
--- /dev/null
+++ b/src/Data/Matlab/SparseArrayReader.cs
@@ -0,0 +1,251 @@
+//
+// 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-2014 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.IO;
+using System.Numerics;
+using MathNet.Numerics.LinearAlgebra;
+using MathNet.Numerics.LinearAlgebra.Storage;
+
+namespace MathNet.Numerics.Data.Matlab
+{
+ internal static class SparseArrayReader
+ where TDataType : struct, IEquatable, IFormattable
+ {
+ ///
+ /// 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.
+ public static Matrix PopulateSparseMatrix(BinaryReader reader, bool isComplex, int rows, int columns, int size)
+ {
+ // Create matrix with CSR storage.
+ var matrix = Matrix.Build.Sparse(columns, rows);
+
+ // MATLAB sparse matrices are actually stored as CSC, so just read the data and then transpose.
+ var storage = matrix.Storage as SparseCompressedRowMatrixStorage;
+
+ // populate the row data array
+ var ir = storage.ColumnIndices = new int[size/4];
+ for (var i = 0; i < ir.Length; i++)
+ {
+ ir[i] = reader.ReadInt32();
+ }
+
+ MatlabParser.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 = storage.RowPointers;
+ if (jc.Length != jcsize/4)
+ {
+ throw new Exception("invalid jcsize");
+ }
+
+ for (var j = 0; j < jc.Length; j++)
+ {
+ jc[j] = reader.ReadInt32();
+ }
+
+ MatlabParser.AlignData(reader.BaseStream, jcsize, false);
+
+ var type = (DataType)reader.ReadInt32();
+ var dataSize = reader.ReadInt32();
+
+ var dataType = typeof (TDataType);
+
+ // Allocate memory for matrix values
+ var data = storage.Values = new TDataType[jc[columns]];
+
+ 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(type, (double[])(object)data, 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(type, (float[])(object)data, reader);
+ }
+ else if (dataType == typeof (Complex))
+ {
+ PopulateComplexSparseMatrix(type, isComplex, (Complex[])(object)data, reader, dataSize);
+ }
+ else if (dataType == typeof (Complex32))
+ {
+ PopulateComplex32SparseMatrix(type, isComplex, (Complex32[])(object)data, reader, dataSize);
+ }
+ else
+ {
+ throw new NotSupportedException();
+ }
+
+ return matrix.Transpose();
+ }
+
+ ///
+ /// Populates the double sparse matrix.
+ ///
+ /// The MATLAB data type.
+ /// The matrix values array.
+ /// The reader to read from.
+ static void PopulateDoubleSparseMatrix(DataType type, double[] data, BinaryReader reader)
+ {
+ for (var i = 0; i < data.Length; i++)
+ {
+ data[i] = ReadDoubleValue(type, reader);
+ }
+ }
+
+ ///
+ /// Populates the float sparse matrix.
+ ///
+ /// The MATLAB data type.
+ /// The matrix values array.
+ /// The reader to read from.
+ static void PopulateSingleSparseMatrix(DataType type, float[] data, BinaryReader reader)
+ {
+ for (var i = 0; i < data.Length; i++)
+ {
+ data[i] = (float)ReadDoubleValue(type, reader);
+ }
+ }
+
+ ///
+ /// Populates the complex sparse matrix.
+ ///
+ /// The MATLAB data type.
+ /// if set to true if the MATLAB complex flag is set.
+ /// The matrix values array.
+ /// The reader to read from.
+ /// The length of the stored data.
+ static void PopulateComplexSparseMatrix(DataType type, bool isComplex, Complex[] data, BinaryReader reader, int dataSize)
+ {
+ for (var i = 0; i < data.Length; i++)
+ {
+ data[i] = ReadDoubleValue(type, reader);
+ }
+
+ if (isComplex)
+ {
+ var skip = dataSize%8;
+
+ // skip pad
+ reader.ReadBytes(skip);
+
+ // skip header
+ type = (DataType)reader.ReadInt32();
+ reader.ReadInt32();
+
+ for (var i = 0; i < data.Length; i++)
+ {
+ data[i] += new Complex(0.0, ReadDoubleValue(type, reader));
+ }
+ }
+ }
+
+ ///
+ /// Populates the complex32 sparse matrix.
+ ///
+ /// The MATLAB data type.
+ /// if set to true if the MATLAB complex flag is set.
+ /// The matrix values array.
+ /// The reader to read from.
+ /// The length of the stored data.
+ static void PopulateComplex32SparseMatrix(DataType type, bool isComplex, Complex32[] data, BinaryReader reader, int dataSize)
+ {
+ for (var i = 0; i < data.Length; i++)
+ {
+ data[i] = (float)ReadDoubleValue(type, reader);
+ }
+
+ if (isComplex)
+ {
+ var skip = dataSize%8;
+
+ // skip pad
+ reader.ReadBytes(skip);
+
+ // skip header
+ type = (DataType)reader.ReadInt32();
+ reader.ReadInt32();
+
+ for (var i = 0; i < data.Length; i++)
+ {
+ data[i] += new Complex32(0.0f, (float)ReadDoubleValue(type, reader));
+ }
+ }
+ }
+
+ static double ReadDoubleValue(DataType type, BinaryReader reader)
+ {
+ switch (type)
+ {
+ case DataType.Double:
+ return reader.ReadDouble();
+ case DataType.Int8:
+ return reader.ReadSByte();
+ case DataType.UInt8:
+ return reader.ReadByte();
+ case DataType.Int16:
+ return reader.ReadInt16();
+ case DataType.UInt16:
+ return reader.ReadUInt16();
+ case DataType.Int32:
+ return reader.ReadInt32();
+ case DataType.UInt32:
+ return reader.ReadUInt32();
+ case DataType.Single:
+ return reader.ReadSingle();
+ case DataType.Int64:
+ return reader.ReadInt64();
+ case DataType.UInt64:
+ return reader.ReadUInt64();
+ default:
+ throw new NotSupportedException();
+ }
+ }
+ }
+}