27 changed files with 2385 additions and 1824 deletions
@ -0,0 +1,70 @@ |
|||
// <copyright file="DelimitedWriter.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
//
|
|||
// Copyright (c) 2009-2010 Math.NET
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person
|
|||
// obtaining a copy of this software and associated documentation
|
|||
// files (the "Software"), to deal in the Software without
|
|||
// restriction, including without limitation the rights to use,
|
|||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the
|
|||
// Software is furnished to do so, subject to the following
|
|||
// conditions:
|
|||
// The above copyright notice and this permission notice shall be
|
|||
// included in all copies or substantial portions of the Software.
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
// OTHER DEALINGS IN THE SOFTWARE.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Complex.IO |
|||
{ |
|||
using Generic; |
|||
using LinearAlgebra.IO; |
|||
|
|||
/// <summary>
|
|||
/// Writes an <see cref="Matrix{TDataType}"/> to delimited text file. If the user does not
|
|||
/// specify a delimiter, a tab separator is used.
|
|||
/// </summary>
|
|||
public class DelimitedWriter : DelimitedWriter<System.Numerics.Complex> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
|
|||
/// a comma as the delimiter.
|
|||
/// </summary>
|
|||
public DelimitedWriter() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
|
|||
/// using the given delimiter.
|
|||
/// </summary>
|
|||
/// <param name="delimiter">
|
|||
/// the delimiter to use.
|
|||
/// </param>
|
|||
public DelimitedWriter(char delimiter) : base(delimiter) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
|
|||
/// using the given delimiter.
|
|||
/// </summary>
|
|||
/// <param name="delimiter">
|
|||
/// the delimiter to use.
|
|||
/// </param>
|
|||
public DelimitedWriter(string delimiter) : base(delimiter) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
// <copyright file="MatlabReader.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
// Copyright (c) 2009-2010 Math.NET
|
|||
// Permission is hereby granted, free of charge, to any person
|
|||
// obtaining a copy of this software and associated documentation
|
|||
// files (the "Software"), to deal in the Software without
|
|||
// restriction, including without limitation the rights to use,
|
|||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the
|
|||
// Software is furnished to do so, subject to the following
|
|||
// conditions:
|
|||
// The above copyright notice and this permission notice shall be
|
|||
// included in all copies or substantial portions of the Software.
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
// OTHER DEALINGS IN THE SOFTWARE.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Complex.IO |
|||
{ |
|||
using System.IO; |
|||
using LinearAlgebra.IO; |
|||
|
|||
/// <summary>
|
|||
/// Creates matrices from Matlab files.
|
|||
/// </summary>
|
|||
public class MatlabMatrixReader : MatlabMatrixReader<System.Numerics.Complex> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabMatrixReader"/> class.
|
|||
/// </summary>
|
|||
/// <param name="filename">Name of the file to read matrices from.</param>
|
|||
public MatlabMatrixReader(string filename) : base(filename) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabMatrixReader"/> class.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream to reader matrices from.</param>
|
|||
public MatlabMatrixReader(Stream stream) : base(stream) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
// <copyright file="DelimitedWriter.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
//
|
|||
// Copyright (c) 2009-2010 Math.NET
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person
|
|||
// obtaining a copy of this software and associated documentation
|
|||
// files (the "Software"), to deal in the Software without
|
|||
// restriction, including without limitation the rights to use,
|
|||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the
|
|||
// Software is furnished to do so, subject to the following
|
|||
// conditions:
|
|||
// The above copyright notice and this permission notice shall be
|
|||
// included in all copies or substantial portions of the Software.
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
// OTHER DEALINGS IN THE SOFTWARE.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Complex32.IO |
|||
{ |
|||
using Generic; |
|||
using LinearAlgebra.IO; |
|||
|
|||
/// <summary>
|
|||
/// Writes an <see cref="Matrix{TDataType}"/> to delimited text file. If the user does not
|
|||
/// specify a delimiter, a tab separator is used.
|
|||
/// </summary>
|
|||
public class DelimitedWriter : DelimitedWriter<Numerics.Complex32> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
|
|||
/// a comma as the delimiter.
|
|||
/// </summary>
|
|||
public DelimitedWriter() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
|
|||
/// using the given delimiter.
|
|||
/// </summary>
|
|||
/// <param name="delimiter">
|
|||
/// the delimiter to use.
|
|||
/// </param>
|
|||
public DelimitedWriter(char delimiter) : base(delimiter) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
|
|||
/// using the given delimiter.
|
|||
/// </summary>
|
|||
/// <param name="delimiter">
|
|||
/// the delimiter to use.
|
|||
/// </param>
|
|||
public DelimitedWriter(string delimiter) : base(delimiter) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
// <copyright file="MatlabReader.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
// Copyright (c) 2009-2010 Math.NET
|
|||
// Permission is hereby granted, free of charge, to any person
|
|||
// obtaining a copy of this software and associated documentation
|
|||
// files (the "Software"), to deal in the Software without
|
|||
// restriction, including without limitation the rights to use,
|
|||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the
|
|||
// Software is furnished to do so, subject to the following
|
|||
// conditions:
|
|||
// The above copyright notice and this permission notice shall be
|
|||
// included in all copies or substantial portions of the Software.
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
// OTHER DEALINGS IN THE SOFTWARE.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Complex32.IO |
|||
{ |
|||
using System.IO; |
|||
using LinearAlgebra.IO; |
|||
|
|||
/// <summary>
|
|||
/// Creates matrices from Matlab files.
|
|||
/// </summary>
|
|||
public class MatlabMatrixReader : MatlabMatrixReader<Numerics.Complex32> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabMatrixReader"/> class.
|
|||
/// </summary>
|
|||
/// <param name="filename">Name of the file to read matrices from.</param>
|
|||
public MatlabMatrixReader(string filename) : base(filename) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabMatrixReader"/> class.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream to reader matrices from.</param>
|
|||
public MatlabMatrixReader(Stream stream) : base(stream) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
// <copyright file="DelimitedWriter.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
//
|
|||
// Copyright (c) 2009-2010 Math.NET
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person
|
|||
// obtaining a copy of this software and associated documentation
|
|||
// files (the "Software"), to deal in the Software without
|
|||
// restriction, including without limitation the rights to use,
|
|||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the
|
|||
// Software is furnished to do so, subject to the following
|
|||
// conditions:
|
|||
// The above copyright notice and this permission notice shall be
|
|||
// included in all copies or substantial portions of the Software.
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
// OTHER DEALINGS IN THE SOFTWARE.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Double.IO |
|||
{ |
|||
using Generic; |
|||
using LinearAlgebra.IO; |
|||
|
|||
/// <summary>
|
|||
/// Writes an <see cref="Matrix{TDataType}"/> to delimited text file. If the user does not
|
|||
/// specify a delimiter, a tab separator is used.
|
|||
/// </summary>
|
|||
public class DelimitedWriter : DelimitedWriter<double> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
|
|||
/// a comma as the delimiter.
|
|||
/// </summary>
|
|||
public DelimitedWriter() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
|
|||
/// using the given delimiter.
|
|||
/// </summary>
|
|||
/// <param name="delimiter">
|
|||
/// the delimiter to use.
|
|||
/// </param>
|
|||
public DelimitedWriter(char delimiter) : base(delimiter) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
|
|||
/// using the given delimiter.
|
|||
/// </summary>
|
|||
/// <param name="delimiter">
|
|||
/// the delimiter to use.
|
|||
/// </param>
|
|||
public DelimitedWriter(string delimiter) : base(delimiter) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,219 +0,0 @@ |
|||
// <copyright file="MatlabFile.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
//
|
|||
// Copyright (c) 2009-2010 Math.NET
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person
|
|||
// obtaining a copy of this software and associated documentation
|
|||
// files (the "Software"), to deal in the Software without
|
|||
// restriction, including without limitation the rights to use,
|
|||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the
|
|||
// Software is furnished to do so, subject to the following
|
|||
// conditions:
|
|||
// The above copyright notice and this permission notice shall be
|
|||
// included in all copies or substantial portions of the Software.
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
// OTHER DEALINGS IN THE SOFTWARE.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab |
|||
{ |
|||
using System.Collections.Generic; |
|||
using Generic; |
|||
|
|||
/// <summary>
|
|||
/// Represents a Matlab file
|
|||
/// </summary>
|
|||
internal class MatlabFile |
|||
{ |
|||
/// <summary>
|
|||
/// Matrices in a matlab file stored as 1-D arrays
|
|||
/// </summary>
|
|||
private readonly IDictionary<string, Matrix<double>> _matrices = new SortedList<string, Matrix<double>>(); |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the header text.
|
|||
/// </summary>
|
|||
/// <value>The header text.</value>
|
|||
public string HeaderText { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the first name of the matrix.
|
|||
/// </summary>
|
|||
/// <value>The first name of the matrix.</value>
|
|||
public string FirstMatrixName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the first matrix.
|
|||
/// </summary>
|
|||
/// <value>The first matrix.</value>
|
|||
public Matrix<double> FirstMatrix |
|||
{ |
|||
get |
|||
{ |
|||
if (string.IsNullOrEmpty(FirstMatrixName) || !_matrices.ContainsKey(FirstMatrixName)) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return _matrices[FirstMatrixName]; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the matrices.
|
|||
/// </summary>
|
|||
/// <value>The matrices.</value>
|
|||
public IDictionary<string, Matrix<double>> Matrices |
|||
{ |
|||
get { return _matrices; } |
|||
} |
|||
} |
|||
|
|||
/* |
|||
/// <summary>
|
|||
/// An
|
|||
/// </summary>
|
|||
/// <typeparam name="T"></typeparam>
|
|||
/// <typeparam name="K"></typeparam>
|
|||
internal class ListDictionary<T, K> : IDictionary<T, K> |
|||
{ |
|||
private readonly IList<T> _keys = new List<T>(); |
|||
private readonly IList<K> _values = new List<K>(); |
|||
|
|||
public void Add(T key, K value) |
|||
{ |
|||
_keys.Add(key); |
|||
_values.Add(value); |
|||
} |
|||
|
|||
public bool ContainsKey(T key) |
|||
{ |
|||
return _keys.Contains(key); |
|||
} |
|||
|
|||
public ICollection<T> Keys |
|||
{ |
|||
get { return _keys; } |
|||
} |
|||
|
|||
public bool Remove(T key) |
|||
{ |
|||
if (_keys.Contains(key)) |
|||
{ |
|||
int pos = _keys.IndexOf(key); |
|||
_values.RemoveAt(pos); |
|||
_values.RemoveAt(pos); |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public bool TryGetValue(T key, out K value) |
|||
{ |
|||
if (_keys.Contains(key)) |
|||
{ |
|||
value = _values[_keys.IndexOf(key)]; |
|||
return true; |
|||
} |
|||
value = default(K); |
|||
return false; |
|||
} |
|||
|
|||
public ICollection<K> Values |
|||
{ |
|||
get { return _values; } |
|||
} |
|||
|
|||
public K this[T key] |
|||
{ |
|||
get |
|||
{ |
|||
if (_keys.Contains(key)) |
|||
{ |
|||
return _values[_keys.IndexOf(key)]; |
|||
} |
|||
throw new KeyNotFoundException(); |
|||
} |
|||
set |
|||
{ |
|||
if (_keys.Contains(key)) |
|||
{ |
|||
_values[_keys.IndexOf(key)] = value; |
|||
} |
|||
else |
|||
{ |
|||
Add(key, value); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public void Add(KeyValuePair<T, K> item) |
|||
{ |
|||
Add(item.Key, item.Value); |
|||
} |
|||
|
|||
public void Clear() |
|||
{ |
|||
_keys.Clear(); |
|||
_values.Clear(); |
|||
} |
|||
|
|||
public bool Contains(KeyValuePair<T, K> item) |
|||
{ |
|||
return _keys.Contains(item.Key) && _values[_keys.IndexOf(item.Key)].Equals(item.Value); |
|||
} |
|||
|
|||
public void CopyTo(KeyValuePair<T, K>[] array, int arrayIndex) |
|||
{ |
|||
for (int i = 0; i < _keys.Count; i++) |
|||
{ |
|||
array[arrayIndex + i] = new KeyValuePair<T, K>(_keys[i], _values[i]); |
|||
} |
|||
} |
|||
|
|||
public int Count |
|||
{ |
|||
get { return _keys.Count; } |
|||
} |
|||
|
|||
public bool IsReadOnly |
|||
{ |
|||
get { return false; } |
|||
} |
|||
|
|||
public bool Remove(KeyValuePair<T, K> item) |
|||
{ |
|||
if (Contains(item)) |
|||
{ |
|||
Remove(item.Key); |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public IEnumerator<KeyValuePair<T, K>> GetEnumerator() |
|||
{ |
|||
for (int i = 0; i < _keys.Count; i++) |
|||
{ |
|||
yield return new KeyValuePair<T, K>(_keys[i], _values[i]); |
|||
} |
|||
} |
|||
|
|||
IEnumerator IEnumerable.GetEnumerator() |
|||
{ |
|||
return GetEnumerator(); |
|||
} |
|||
|
|||
}*/ |
|||
} |
|||
@ -1,536 +0,0 @@ |
|||
// <copyright file="MatlabParser.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
// Copyright (c) 2009-2010 Math.NET
|
|||
// Permission is hereby granted, free of charge, to any person
|
|||
// obtaining a copy of this software and associated documentation
|
|||
// files (the "Software"), to deal in the Software without
|
|||
// restriction, including without limitation the rights to use,
|
|||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the
|
|||
// Software is furnished to do so, subject to the following
|
|||
// conditions:
|
|||
// The above copyright notice and this permission notice shall be
|
|||
// included in all copies or substantial portions of the Software.
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
// OTHER DEALINGS IN THE SOFTWARE.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Double.IO.Matlab |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Text; |
|||
using Common.IO.Matlab; |
|||
using Generic; |
|||
using Properties; |
|||
using zlib; |
|||
|
|||
/// <summary>
|
|||
/// Parse a Matlab file
|
|||
/// </summary>
|
|||
internal class MatlabParser |
|||
{ |
|||
/// <summary>
|
|||
/// Large Block Size
|
|||
/// </summary>
|
|||
private const int LargeBlockSize = 8; |
|||
|
|||
/// <summary>
|
|||
/// Little Endian Indicator
|
|||
/// </summary>
|
|||
private const byte LittleEndianIndicator = 0x49; |
|||
|
|||
/// <summary>
|
|||
/// Small Block Size
|
|||
/// </summary>
|
|||
private const int SmallBlockSize = 4; |
|||
|
|||
/// <summary>
|
|||
/// Holds the names of the matrices in the file.
|
|||
/// </summary>
|
|||
private readonly IList<string> _names = new List<string>(); |
|||
|
|||
/// <summary>
|
|||
/// The stream to read the matlab file from.
|
|||
/// </summary>
|
|||
private readonly Stream _stream; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
|
|||
/// </summary>
|
|||
/// <param name="fileName">Name of the file.</param>
|
|||
public MatlabParser(string fileName) |
|||
: this(fileName, new string[0]) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream to read from.</param>
|
|||
public MatlabParser(Stream stream) |
|||
: this(stream, new string[0]) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream to read from.</param>
|
|||
/// <param name="objectNames">The name of the objects to retrieve.</param>
|
|||
public MatlabParser(Stream stream, IEnumerable<string> objectNames) |
|||
{ |
|||
if (stream == null) |
|||
{ |
|||
throw new ArgumentNullException("stream"); |
|||
} |
|||
|
|||
_stream = stream; |
|||
SetNames(objectNames); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
|
|||
/// </summary>
|
|||
/// <param name="fileName">Name of the file.</param>
|
|||
/// <param name="objectNames">The name of the objects to retrieve.</param>
|
|||
public MatlabParser(string fileName, IEnumerable<string> objectNames) |
|||
{ |
|||
if (string.IsNullOrEmpty(fileName)) |
|||
{ |
|||
throw new ArgumentException(Resources.StringNullOrEmpty, "filename"); |
|||
} |
|||
|
|||
_stream = File.OpenRead(fileName); |
|||
SetNames(objectNames); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Copies the names of the objects to retrieve to a local field.
|
|||
/// </summary>
|
|||
/// <param name="objectNames">The name of the objects to retrieve.</param>
|
|||
private void SetNames(IEnumerable<string> objectNames) |
|||
{ |
|||
foreach (var name in objectNames) |
|||
{ |
|||
_names.Add(name); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Parses the file.
|
|||
/// </summary>
|
|||
/// <returns>The parsed Matlab file as a <see cref="MatlabFile"/> object.</returns>
|
|||
public MatlabFile Parse() |
|||
{ |
|||
var file = new MatlabFile(); |
|||
|
|||
using (var reader = new BinaryReader(_stream)) |
|||
{ |
|||
file.HeaderText = Encoding.ASCII.GetString(reader.ReadBytes(116)); |
|||
|
|||
// skipping subsystem offsets
|
|||
reader.BaseStream.Position = 126; |
|||
|
|||
if (reader.ReadByte() != LittleEndianIndicator) |
|||
{ |
|||
throw new NotSupportedException(Resources.BigEndianNotSupported); |
|||
} |
|||
|
|||
// skip version since it is always 0x0100.
|
|||
reader.BaseStream.Position = 128; |
|||
var length = _stream.Length; |
|||
|
|||
// for each data block add a matlab object to the file.
|
|||
while (reader.BaseStream.Position < length) |
|||
{ |
|||
var type = (DataType)reader.ReadInt16(); |
|||
int size = reader.ReadInt16(); |
|||
var smallBlock = true; |
|||
if (size == 0) |
|||
{ |
|||
size = reader.ReadInt32(); |
|||
smallBlock = false; |
|||
} |
|||
|
|||
byte[] data; |
|||
if (type == DataType.Compressed) |
|||
{ |
|||
data = DecompressBlock(reader.ReadBytes(size), ref type); |
|||
} |
|||
else |
|||
{ |
|||
data = new byte[size]; |
|||
reader.Read(data, 0, size); |
|||
AlignData(reader.BaseStream, size, smallBlock); |
|||
} |
|||
|
|||
if (type == DataType.Matrix) |
|||
{ |
|||
AddMatrix(data, file); |
|||
} |
|||
else |
|||
{ |
|||
throw new NotSupportedException(string.Format(Resources.NotSupportedType, type)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return file; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Aligns the data.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream.</param>
|
|||
/// <param name="size">The size of the array.</param>
|
|||
/// <param name="smallBlock">if set to <c>true</c> if reading from a small block.</param>
|
|||
private static void AlignData(Stream stream, int size, bool smallBlock) |
|||
{ |
|||
var blockSize = smallBlock ? SmallBlockSize : LargeBlockSize; |
|||
var offset = 0; |
|||
var mod = size % blockSize; |
|||
if (mod != 0) |
|||
{ |
|||
offset = blockSize - mod; |
|||
} |
|||
|
|||
stream.Seek(offset, SeekOrigin.Current); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Decompresses the block.
|
|||
/// </summary>
|
|||
/// <param name="compressed">The compressed data.</param>
|
|||
/// <param name="type">The type data type contained in the block.</param>
|
|||
/// <returns>The decompressed block.</returns>
|
|||
private static byte[] DecompressBlock(byte[] compressed, ref DataType type) |
|||
{ |
|||
byte[] data; |
|||
using (var decompressed = new MemoryStream()) |
|||
{ |
|||
using (var decompressor = new ZOutputStream(decompressed)) |
|||
{ |
|||
decompressor.Write(compressed, 0, compressed.Length); |
|||
decompressed.Position = 0; |
|||
var buf = new byte[4]; |
|||
decompressed.Read(buf, 0, 4); |
|||
type = (DataType)BitConverter.ToInt32(buf, 0); |
|||
decompressed.Read(buf, 0, 4); |
|||
var size = BitConverter.ToInt32(buf, 0); |
|||
data = new byte[size]; |
|||
decompressed.Read(data, 0, size); |
|||
} |
|||
} |
|||
|
|||
return data; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a matrix from the actual file into our presentation of a matlab file.
|
|||
/// </summary>
|
|||
/// <param name="data">The data of the matrix.</param>
|
|||
/// <param name="file">The <see cref="MatlabFile"/> instance.</param>
|
|||
private void AddMatrix(byte[] data, MatlabFile file) |
|||
{ |
|||
using (var ms = new MemoryStream(data)) |
|||
{ |
|||
using (var reader = new BinaryReader(ms)) |
|||
{ |
|||
// skip tag - doesn't tell us anything we don't already know
|
|||
reader.BaseStream.Seek(8, SeekOrigin.Current); |
|||
|
|||
var arrayClass = (ArrayClass)reader.ReadByte(); |
|||
var flags = reader.ReadByte(); |
|||
var isComplex = (flags & (byte)ArrayFlags.Complex) == (byte)ArrayFlags.Complex; |
|||
|
|||
if (isComplex) |
|||
{ |
|||
throw new NotSupportedException(Resources.ComplexMatricesNotSupported); |
|||
} |
|||
|
|||
// skip unneeded bytes
|
|||
reader.BaseStream.Seek(10, SeekOrigin.Current); |
|||
|
|||
var numDimensions = reader.ReadInt32() / 8; |
|||
if (numDimensions > 2) |
|||
{ |
|||
throw new NotSupportedException(Resources.MoreThan2D); |
|||
} |
|||
|
|||
var rows = reader.ReadInt32(); |
|||
var columns = reader.ReadInt32(); |
|||
|
|||
// skip unneeded bytes
|
|||
reader.BaseStream.Seek(2, SeekOrigin.Current); |
|||
int size = reader.ReadInt16(); |
|||
var smallBlock = true; |
|||
if (size == 0) |
|||
{ |
|||
size = reader.ReadInt32(); |
|||
smallBlock = false; |
|||
} |
|||
|
|||
var name = Encoding.ASCII.GetString(reader.ReadBytes(size)); |
|||
AlignData(reader.BaseStream, size, smallBlock); |
|||
|
|||
// only grab wanted objects
|
|||
if (_names.Count != 0 && !_names.Contains(name)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
var type = (DataType)reader.ReadInt16(); |
|||
size = reader.ReadInt16(); |
|||
if (size == 0) |
|||
{ |
|||
size = reader.ReadInt32(); |
|||
} |
|||
|
|||
Matrix<double> matrix; |
|||
switch (arrayClass) |
|||
{ |
|||
case ArrayClass.Sparse: |
|||
matrix = PopulateSparseMatrix(reader, rows, columns, size); |
|||
break; |
|||
case ArrayClass.Function: |
|||
case ArrayClass.Character: |
|||
case ArrayClass.Object: |
|||
case ArrayClass.Structure: |
|||
case ArrayClass.Cell: |
|||
case ArrayClass.Unknown: |
|||
throw new NotImplementedException(); |
|||
default: |
|||
matrix = PopulateDenseMatrix(type, reader, rows, columns); |
|||
break; |
|||
} |
|||
|
|||
file.Matrices.Add(name, matrix); |
|||
if (file.FirstMatrixName == null) |
|||
{ |
|||
file.FirstMatrixName = name; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Populates a sparse matrix.
|
|||
/// </summary>
|
|||
/// <param name="reader">The reader.</param>
|
|||
/// <param name="rows">The number of rows.</param>
|
|||
/// <param name="columns">The number of columns.</param>
|
|||
/// <param name="size">The size of the block.</param>
|
|||
/// <returns>A populated sparse matrix.</returns>
|
|||
private static Matrix<double> PopulateSparseMatrix(BinaryReader reader, int rows, int columns, int size) |
|||
{ |
|||
// populate the row data array
|
|||
var ir = new int[size / 4]; |
|||
for (var i = 0; i < ir.Length; i++) |
|||
{ |
|||
ir[i] = reader.ReadInt32(); |
|||
} |
|||
|
|||
AlignData(reader.BaseStream, size, false); |
|||
|
|||
// skip data type since it will always be int32
|
|||
reader.BaseStream.Seek(4, SeekOrigin.Current); |
|||
|
|||
// populate the column data array
|
|||
var jcsize = reader.ReadInt32(); |
|||
var jc = new int[jcsize / 4]; |
|||
for (var j = 0; j < jc.Length; j++) |
|||
{ |
|||
jc[j] = reader.ReadInt32(); |
|||
} |
|||
|
|||
AlignData(reader.BaseStream, jcsize, false); |
|||
|
|||
var type = (DataType)reader.ReadInt32(); |
|||
|
|||
// skip length since we already no it for the number of rows
|
|||
reader.BaseStream.Seek(4, SeekOrigin.Current); |
|||
|
|||
Matrix<double> matrix = new SparseMatrix(rows, columns); |
|||
var col = 0; |
|||
for (var i = 0; i < ir.Length; i++) |
|||
{ |
|||
var row = ir[i]; |
|||
if (jc[col + 1] == i) |
|||
{ |
|||
col++; |
|||
} |
|||
|
|||
switch (type) |
|||
{ |
|||
case DataType.Int8: |
|||
matrix[row, col] = reader.ReadSByte(); |
|||
break; |
|||
case DataType.UInt8: |
|||
matrix[row, col] = reader.ReadByte(); |
|||
break; |
|||
case DataType.Int16: |
|||
matrix[row, col] = reader.ReadInt16(); |
|||
break; |
|||
|
|||
case DataType.UInt16: |
|||
matrix[row, col] = reader.ReadUInt16(); |
|||
break; |
|||
case DataType.Int32: |
|||
matrix[row, col] = reader.ReadInt32(); |
|||
break; |
|||
|
|||
case DataType.UInt32: |
|||
matrix[row, col] = reader.ReadUInt32(); |
|||
break; |
|||
case DataType.Single: |
|||
matrix[row, col] = reader.ReadSingle(); |
|||
break; |
|||
case DataType.Int64: |
|||
matrix[row, col] = reader.ReadInt64(); |
|||
break; |
|||
case DataType.UInt64: |
|||
matrix[row, col] = reader.ReadUInt64(); |
|||
break; |
|||
case DataType.Double: |
|||
matrix[row, col] = reader.ReadDouble(); |
|||
break; |
|||
default: |
|||
throw new NotSupportedException(); |
|||
} |
|||
} |
|||
|
|||
return matrix; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Populates a dense matrix.
|
|||
/// </summary>
|
|||
/// <param name="type">The type of data.</param>
|
|||
/// <param name="reader">The reader.</param>
|
|||
/// <param name="rows">The number of rows.</param>
|
|||
/// <param name="columns">The number of columns.</param>
|
|||
/// <returns>Returns a populated dense matrix.</returns>
|
|||
private static Matrix<double> PopulateDenseMatrix(DataType type, BinaryReader reader, int rows, int columns) |
|||
{ |
|||
Matrix<double> matrix = new DenseMatrix(rows, columns); |
|||
switch (type) |
|||
{ |
|||
case DataType.Int8: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadSByte(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.UInt8: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadByte(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.Int16: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadInt16(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.UInt16: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadUInt16(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.Int32: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadInt32(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.UInt32: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadUInt32(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.Single: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadSingle(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.Int64: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadInt64(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.UInt64: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadUInt64(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.Double: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadDouble(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
default: |
|||
throw new NotSupportedException(); |
|||
} |
|||
|
|||
return matrix; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,84 @@ |
|||
// <copyright file="MatlabFile.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
//
|
|||
// Copyright (c) 2009-2010 Math.NET
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person
|
|||
// obtaining a copy of this software and associated documentation
|
|||
// files (the "Software"), to deal in the Software without
|
|||
// restriction, including without limitation the rights to use,
|
|||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the
|
|||
// Software is furnished to do so, subject to the following
|
|||
// conditions:
|
|||
// The above copyright notice and this permission notice shall be
|
|||
// included in all copies or substantial portions of the Software.
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
// OTHER DEALINGS IN THE SOFTWARE.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.IO.Matlab |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Generic; |
|||
|
|||
/// <summary>
|
|||
/// Represents a Matlab file
|
|||
/// </summary>
|
|||
/// <typeparam name="TDataType">The data type of the matrix to return.</typeparam>
|
|||
internal class MatlabFile<TDataType> where TDataType : struct, IEquatable<TDataType>, IFormattable |
|||
{ |
|||
/// <summary>
|
|||
/// Matrices in a matlab file stored as 1-D arrays
|
|||
/// </summary>
|
|||
private readonly IDictionary<string, Matrix<TDataType>> _matrices = new SortedList<string, Matrix<TDataType>>(); |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the header text.
|
|||
/// </summary>
|
|||
/// <value>The header text.</value>
|
|||
public string HeaderText { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the first name of the matrix.
|
|||
/// </summary>
|
|||
/// <value>The first name of the matrix.</value>
|
|||
public string FirstMatrixName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the first matrix.
|
|||
/// </summary>
|
|||
/// <value>The first matrix.</value>
|
|||
public Matrix<TDataType> FirstMatrix |
|||
{ |
|||
get |
|||
{ |
|||
if (string.IsNullOrEmpty(FirstMatrixName) || !_matrices.ContainsKey(FirstMatrixName)) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return _matrices[FirstMatrixName]; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the matrices.
|
|||
/// </summary>
|
|||
/// <value>The matrices.</value>
|
|||
public IDictionary<string, Matrix<TDataType>> Matrices |
|||
{ |
|||
get { return _matrices; } |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,192 @@ |
|||
// <copyright file="MatlabReader.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
//
|
|||
// Copyright (c) 2009-2010 Math.NET
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person
|
|||
// obtaining a copy of this software and associated documentation
|
|||
// files (the "Software"), to deal in the Software without
|
|||
// restriction, including without limitation the rights to use,
|
|||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the
|
|||
// Software is furnished to do so, subject to the following
|
|||
// conditions:
|
|||
// The above copyright notice and this permission notice shall be
|
|||
// included in all copies or substantial portions of the Software.
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
// OTHER DEALINGS IN THE SOFTWARE.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.IO |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using Generic; |
|||
using Matlab; |
|||
using Properties; |
|||
|
|||
/// <summary>
|
|||
/// Creates matrices from Matlab files.
|
|||
/// </summary>
|
|||
/// <typeparam name="TDataType">The data type of the Matrix. It can be either: double, float, Complex, or Complex32.</typeparam>
|
|||
public class MatlabMatrixReader<TDataType> where TDataType : struct, IEquatable<TDataType>, IFormattable |
|||
{ |
|||
/// <summary>
|
|||
/// The name of the file to read from.
|
|||
/// </summary>
|
|||
private readonly string _filename; |
|||
|
|||
/// <summary>
|
|||
/// The stream to read from if we are not reading from a file directly.
|
|||
/// </summary>
|
|||
private readonly Stream _stream; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabMatrixReader{TDataType}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="filename">Name of the file to read matrices from.</param>
|
|||
public MatlabMatrixReader(string filename) |
|||
{ |
|||
if (string.IsNullOrEmpty(filename)) |
|||
{ |
|||
throw new ArgumentException(Resources.StringNullOrEmpty, "filename"); |
|||
} |
|||
|
|||
if (!File.Exists(filename)) |
|||
{ |
|||
throw new FileNotFoundException(Resources.FileDoesNotExist, "filename"); |
|||
} |
|||
|
|||
_filename = filename; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabMatrixReader{TDataType}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream to reader matrices from.</param>
|
|||
public MatlabMatrixReader(Stream stream) |
|||
{ |
|||
if (stream == null) |
|||
{ |
|||
throw new ArgumentNullException("stream"); |
|||
} |
|||
|
|||
_stream = stream; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Reads the first matrix from the file or stream.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// A sparse or dense matrix depending on how the matrix
|
|||
/// is defined in the Matlab file.
|
|||
/// </returns>
|
|||
public Matrix<TDataType> ReadMatrix() |
|||
{ |
|||
return ReadMatrix(null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Reads the named matrix from the file or stream.
|
|||
/// </summary>
|
|||
/// <param name="matrixName">The name of the matrix to read.</param>
|
|||
/// <returns>
|
|||
/// A sparse or dense matrix depending on how the matrix
|
|||
/// is defined in the Matlab file.
|
|||
/// <see langword="null"/> is returned if a matrix with the requests name doesn't exist.
|
|||
/// </returns>
|
|||
public Matrix<TDataType> ReadMatrix(string matrixName) |
|||
{ |
|||
Stream stream; |
|||
if (_filename == null) |
|||
{ |
|||
stream = _stream; |
|||
_stream.Seek(0, SeekOrigin.Begin); |
|||
} |
|||
else |
|||
{ |
|||
stream = new FileStream(_filename, FileMode.Open, FileAccess.Read); |
|||
} |
|||
|
|||
var names = string.IsNullOrEmpty(matrixName) ? new string[] { } : new[] { matrixName }; |
|||
var parser = new MatlabParser<TDataType>(stream, names); |
|||
var file = parser.Parse(); |
|||
|
|||
Matrix<TDataType> matrix = null; |
|||
if (string.IsNullOrEmpty(matrixName)) |
|||
{ |
|||
matrix = file.FirstMatrix; |
|||
} |
|||
else if (file.Matrices.ContainsKey(matrixName)) |
|||
{ |
|||
matrix = file.Matrices[matrixName]; |
|||
} |
|||
|
|||
if (_filename != null) |
|||
{ |
|||
stream.Close(); |
|||
stream.Dispose(); |
|||
} |
|||
|
|||
return matrix; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Reads all matrices from the file or stream.
|
|||
/// </summary>
|
|||
/// <returns>All matrices from the file or stream.</returns>
|
|||
public Matrix<TDataType>[] ReadMatrices() |
|||
{ |
|||
return ReadMatrices(new string[] { }); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Reads the named matrices from the file or stream.
|
|||
/// </summary>
|
|||
/// <param name="names">The names of the matrices to retrieve.</param>
|
|||
/// <returns>
|
|||
/// The named matrices from the file or stream.
|
|||
/// </returns>
|
|||
public Matrix<TDataType>[] ReadMatrices(IEnumerable<string> names) |
|||
{ |
|||
Stream stream; |
|||
if (_filename == null) |
|||
{ |
|||
stream = _stream; |
|||
_stream.Seek(0, SeekOrigin.Begin); |
|||
} |
|||
else |
|||
{ |
|||
stream = new BufferedStream(new FileStream(_filename, FileMode.Open, FileAccess.Read)); |
|||
} |
|||
|
|||
var parser = new MatlabParser<TDataType>(stream, names); |
|||
var file = parser.Parse(); |
|||
|
|||
var matrices = new Matrix<TDataType>[file.Matrices.Count]; |
|||
var i = 0; |
|||
foreach (var matrix in file.Matrices.Values) |
|||
{ |
|||
matrices[i++] = matrix; |
|||
} |
|||
|
|||
if (_filename != null) |
|||
{ |
|||
stream.Close(); |
|||
stream.Dispose(); |
|||
} |
|||
|
|||
return matrices; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
// <copyright file="DelimitedWriter.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
//
|
|||
// Copyright (c) 2009-2010 Math.NET
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person
|
|||
// obtaining a copy of this software and associated documentation
|
|||
// files (the "Software"), to deal in the Software without
|
|||
// restriction, including without limitation the rights to use,
|
|||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the
|
|||
// Software is furnished to do so, subject to the following
|
|||
// conditions:
|
|||
// The above copyright notice and this permission notice shall be
|
|||
// included in all copies or substantial portions of the Software.
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
// OTHER DEALINGS IN THE SOFTWARE.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Single.IO |
|||
{ |
|||
using Generic; |
|||
using LinearAlgebra.IO; |
|||
|
|||
/// <summary>
|
|||
/// Writes an <see cref="Matrix{TDataType}"/> to delimited text file. If the user does not
|
|||
/// specify a delimiter, a tab separator is used.
|
|||
/// </summary>
|
|||
public class DelimitedWriter : DelimitedWriter<float> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
|
|||
/// a comma as the delimiter.
|
|||
/// </summary>
|
|||
public DelimitedWriter() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
|
|||
/// using the given delimiter.
|
|||
/// </summary>
|
|||
/// <param name="delimiter">
|
|||
/// the delimiter to use.
|
|||
/// </param>
|
|||
public DelimitedWriter(char delimiter) : base(delimiter) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DelimitedWriter"/> class.
|
|||
/// using the given delimiter.
|
|||
/// </summary>
|
|||
/// <param name="delimiter">
|
|||
/// the delimiter to use.
|
|||
/// </param>
|
|||
public DelimitedWriter(string delimiter) : base(delimiter) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,219 +0,0 @@ |
|||
// <copyright file="MatlabFile.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
//
|
|||
// Copyright (c) 2009-2010 Math.NET
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person
|
|||
// obtaining a copy of this software and associated documentation
|
|||
// files (the "Software"), to deal in the Software without
|
|||
// restriction, including without limitation the rights to use,
|
|||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the
|
|||
// Software is furnished to do so, subject to the following
|
|||
// conditions:
|
|||
// The above copyright notice and this permission notice shall be
|
|||
// included in all copies or substantial portions of the Software.
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
// OTHER DEALINGS IN THE SOFTWARE.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Single.IO.Matlab |
|||
{ |
|||
using System.Collections.Generic; |
|||
using Generic; |
|||
|
|||
/// <summary>
|
|||
/// Represents a Matlab file
|
|||
/// </summary>
|
|||
internal class MatlabFile |
|||
{ |
|||
/// <summary>
|
|||
/// Matrices in a matlab file stored as 1-D arrays
|
|||
/// </summary>
|
|||
private readonly IDictionary<string, Matrix<float>> _matrices = new SortedList<string, Matrix<float>>(); |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the header text.
|
|||
/// </summary>
|
|||
/// <value>The header text.</value>
|
|||
public string HeaderText { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the first name of the matrix.
|
|||
/// </summary>
|
|||
/// <value>The first name of the matrix.</value>
|
|||
public string FirstMatrixName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the first matrix.
|
|||
/// </summary>
|
|||
/// <value>The first matrix.</value>
|
|||
public Matrix<float> FirstMatrix |
|||
{ |
|||
get |
|||
{ |
|||
if (string.IsNullOrEmpty(FirstMatrixName) || !_matrices.ContainsKey(FirstMatrixName)) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return _matrices[FirstMatrixName]; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the matrices.
|
|||
/// </summary>
|
|||
/// <value>The matrices.</value>
|
|||
public IDictionary<string, Matrix<float>> Matrices |
|||
{ |
|||
get { return _matrices; } |
|||
} |
|||
} |
|||
|
|||
/* |
|||
/// <summary>
|
|||
/// An
|
|||
/// </summary>
|
|||
/// <typeparam name="T"></typeparam>
|
|||
/// <typeparam name="K"></typeparam>
|
|||
internal class ListDictionary<T, K> : IDictionary<T, K> |
|||
{ |
|||
private readonly IList<T> _keys = new List<T>(); |
|||
private readonly IList<K> _values = new List<K>(); |
|||
|
|||
public void Add(T key, K value) |
|||
{ |
|||
_keys.Add(key); |
|||
_values.Add(value); |
|||
} |
|||
|
|||
public bool ContainsKey(T key) |
|||
{ |
|||
return _keys.Contains(key); |
|||
} |
|||
|
|||
public ICollection<T> Keys |
|||
{ |
|||
get { return _keys; } |
|||
} |
|||
|
|||
public bool Remove(T key) |
|||
{ |
|||
if (_keys.Contains(key)) |
|||
{ |
|||
int pos = _keys.IndexOf(key); |
|||
_values.RemoveAt(pos); |
|||
_values.RemoveAt(pos); |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public bool TryGetValue(T key, out K value) |
|||
{ |
|||
if (_keys.Contains(key)) |
|||
{ |
|||
value = _values[_keys.IndexOf(key)]; |
|||
return true; |
|||
} |
|||
value = default(K); |
|||
return false; |
|||
} |
|||
|
|||
public ICollection<K> Values |
|||
{ |
|||
get { return _values; } |
|||
} |
|||
|
|||
public K this[T key] |
|||
{ |
|||
get |
|||
{ |
|||
if (_keys.Contains(key)) |
|||
{ |
|||
return _values[_keys.IndexOf(key)]; |
|||
} |
|||
throw new KeyNotFoundException(); |
|||
} |
|||
set |
|||
{ |
|||
if (_keys.Contains(key)) |
|||
{ |
|||
_values[_keys.IndexOf(key)] = value; |
|||
} |
|||
else |
|||
{ |
|||
Add(key, value); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public void Add(KeyValuePair<T, K> item) |
|||
{ |
|||
Add(item.Key, item.Value); |
|||
} |
|||
|
|||
public void Clear() |
|||
{ |
|||
_keys.Clear(); |
|||
_values.Clear(); |
|||
} |
|||
|
|||
public bool Contains(KeyValuePair<T, K> item) |
|||
{ |
|||
return _keys.Contains(item.Key) && _values[_keys.IndexOf(item.Key)].Equals(item.Value); |
|||
} |
|||
|
|||
public void CopyTo(KeyValuePair<T, K>[] array, int arrayIndex) |
|||
{ |
|||
for (int i = 0; i < _keys.Count; i++) |
|||
{ |
|||
array[arrayIndex + i] = new KeyValuePair<T, K>(_keys[i], _values[i]); |
|||
} |
|||
} |
|||
|
|||
public int Count |
|||
{ |
|||
get { return _keys.Count; } |
|||
} |
|||
|
|||
public bool IsReadOnly |
|||
{ |
|||
get { return false; } |
|||
} |
|||
|
|||
public bool Remove(KeyValuePair<T, K> item) |
|||
{ |
|||
if (Contains(item)) |
|||
{ |
|||
Remove(item.Key); |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public IEnumerator<KeyValuePair<T, K>> GetEnumerator() |
|||
{ |
|||
for (int i = 0; i < _keys.Count; i++) |
|||
{ |
|||
yield return new KeyValuePair<T, K>(_keys[i], _values[i]); |
|||
} |
|||
} |
|||
|
|||
IEnumerator IEnumerable.GetEnumerator() |
|||
{ |
|||
return GetEnumerator(); |
|||
} |
|||
|
|||
}*/ |
|||
} |
|||
@ -1,536 +0,0 @@ |
|||
// <copyright file="MatlabParser.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
// Copyright (c) 2009-2010 Math.NET
|
|||
// Permission is hereby granted, free of charge, to any person
|
|||
// obtaining a copy of this software and associated documentation
|
|||
// files (the "Software"), to deal in the Software without
|
|||
// restriction, including without limitation the rights to use,
|
|||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the
|
|||
// Software is furnished to do so, subject to the following
|
|||
// conditions:
|
|||
// The above copyright notice and this permission notice shall be
|
|||
// included in all copies or substantial portions of the Software.
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||
// OTHER DEALINGS IN THE SOFTWARE.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Single.IO.Matlab |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Text; |
|||
using Common.IO.Matlab; |
|||
using Generic; |
|||
using Properties; |
|||
using zlib; |
|||
|
|||
/// <summary>
|
|||
/// Parse a Matlab file
|
|||
/// </summary>
|
|||
internal class MatlabParser |
|||
{ |
|||
/// <summary>
|
|||
/// Large Block Size
|
|||
/// </summary>
|
|||
private const int LargeBlockSize = 8; |
|||
|
|||
/// <summary>
|
|||
/// Little Endian Indicator
|
|||
/// </summary>
|
|||
private const byte LittleEndianIndicator = 0x49; |
|||
|
|||
/// <summary>
|
|||
/// Small Block Size
|
|||
/// </summary>
|
|||
private const int SmallBlockSize = 4; |
|||
|
|||
/// <summary>
|
|||
/// Holds the names of the matrices in the file.
|
|||
/// </summary>
|
|||
private readonly IList<string> _names = new List<string>(); |
|||
|
|||
/// <summary>
|
|||
/// The stream to read the matlab file from.
|
|||
/// </summary>
|
|||
private readonly Stream _stream; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
|
|||
/// </summary>
|
|||
/// <param name="fileName">Name of the file.</param>
|
|||
public MatlabParser(string fileName) |
|||
: this(fileName, new string[0]) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream to read from.</param>
|
|||
public MatlabParser(Stream stream) |
|||
: this(stream, new string[0]) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream to read from.</param>
|
|||
/// <param name="objectNames">The name of the objects to retrieve.</param>
|
|||
public MatlabParser(Stream stream, IEnumerable<string> objectNames) |
|||
{ |
|||
if (stream == null) |
|||
{ |
|||
throw new ArgumentNullException("stream"); |
|||
} |
|||
|
|||
_stream = stream; |
|||
SetNames(objectNames); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="MatlabParser"/> class.
|
|||
/// </summary>
|
|||
/// <param name="fileName">Name of the file.</param>
|
|||
/// <param name="objectNames">The name of the objects to retrieve.</param>
|
|||
public MatlabParser(string fileName, IEnumerable<string> objectNames) |
|||
{ |
|||
if (string.IsNullOrEmpty(fileName)) |
|||
{ |
|||
throw new ArgumentException(Resources.StringNullOrEmpty, "filename"); |
|||
} |
|||
|
|||
_stream = File.OpenRead(fileName); |
|||
SetNames(objectNames); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Copies the names of the objects to retrieve to a local field.
|
|||
/// </summary>
|
|||
/// <param name="objectNames">The name of the objects to retrieve.</param>
|
|||
private void SetNames(IEnumerable<string> objectNames) |
|||
{ |
|||
foreach (var name in objectNames) |
|||
{ |
|||
_names.Add(name); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Parses the file.
|
|||
/// </summary>
|
|||
/// <returns>The parsed Matlab file as a <see cref="MatlabFile"/> object.</returns>
|
|||
public MatlabFile Parse() |
|||
{ |
|||
var file = new MatlabFile(); |
|||
|
|||
using (var reader = new BinaryReader(_stream)) |
|||
{ |
|||
file.HeaderText = Encoding.ASCII.GetString(reader.ReadBytes(116)); |
|||
|
|||
// skipping subsystem offsets
|
|||
reader.BaseStream.Position = 126; |
|||
|
|||
if (reader.ReadByte() != LittleEndianIndicator) |
|||
{ |
|||
throw new NotSupportedException(Resources.BigEndianNotSupported); |
|||
} |
|||
|
|||
// skip version since it is always 0x0100.
|
|||
reader.BaseStream.Position = 128; |
|||
var length = _stream.Length; |
|||
|
|||
// for each data block add a matlab object to the file.
|
|||
while (reader.BaseStream.Position < length) |
|||
{ |
|||
var type = (DataType)reader.ReadInt16(); |
|||
int size = reader.ReadInt16(); |
|||
var smallBlock = true; |
|||
if (size == 0) |
|||
{ |
|||
size = reader.ReadInt32(); |
|||
smallBlock = false; |
|||
} |
|||
|
|||
byte[] data; |
|||
if (type == DataType.Compressed) |
|||
{ |
|||
data = DecompressBlock(reader.ReadBytes(size), ref type); |
|||
} |
|||
else |
|||
{ |
|||
data = new byte[size]; |
|||
reader.Read(data, 0, size); |
|||
AlignData(reader.BaseStream, size, smallBlock); |
|||
} |
|||
|
|||
if (type == DataType.Matrix) |
|||
{ |
|||
AddMatrix(data, file); |
|||
} |
|||
else |
|||
{ |
|||
throw new NotSupportedException(string.Format(Resources.NotSupportedType, type)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return file; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Aligns the data.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream.</param>
|
|||
/// <param name="size">The size of the array.</param>
|
|||
/// <param name="smallBlock">if set to <c>true</c> if reading from a small block.</param>
|
|||
private static void AlignData(Stream stream, int size, bool smallBlock) |
|||
{ |
|||
var blockSize = smallBlock ? SmallBlockSize : LargeBlockSize; |
|||
var offset = 0; |
|||
var mod = size % blockSize; |
|||
if (mod != 0) |
|||
{ |
|||
offset = blockSize - mod; |
|||
} |
|||
|
|||
stream.Seek(offset, SeekOrigin.Current); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Decompresses the block.
|
|||
/// </summary>
|
|||
/// <param name="compressed">The compressed data.</param>
|
|||
/// <param name="type">The type data type contained in the block.</param>
|
|||
/// <returns>The decompressed block.</returns>
|
|||
private static byte[] DecompressBlock(byte[] compressed, ref DataType type) |
|||
{ |
|||
byte[] data; |
|||
using (var decompressed = new MemoryStream()) |
|||
{ |
|||
using (var decompressor = new ZOutputStream(decompressed)) |
|||
{ |
|||
decompressor.Write(compressed, 0, compressed.Length); |
|||
decompressed.Position = 0; |
|||
var buf = new byte[4]; |
|||
decompressed.Read(buf, 0, 4); |
|||
type = (DataType)BitConverter.ToInt32(buf, 0); |
|||
decompressed.Read(buf, 0, 4); |
|||
var size = BitConverter.ToInt32(buf, 0); |
|||
data = new byte[size]; |
|||
decompressed.Read(data, 0, size); |
|||
} |
|||
} |
|||
|
|||
return data; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds a matrix from the actual file into our presentation of a matlab file.
|
|||
/// </summary>
|
|||
/// <param name="data">The data of the matrix.</param>
|
|||
/// <param name="file">The <see cref="MatlabFile"/> instance.</param>
|
|||
private void AddMatrix(byte[] data, MatlabFile file) |
|||
{ |
|||
using (var ms = new MemoryStream(data)) |
|||
{ |
|||
using (var reader = new BinaryReader(ms)) |
|||
{ |
|||
// skip tag - doesn't tell us anything we don't already know
|
|||
reader.BaseStream.Seek(8, SeekOrigin.Current); |
|||
|
|||
var arrayClass = (ArrayClass)reader.ReadByte(); |
|||
var flags = reader.ReadByte(); |
|||
var isComplex = (flags & (byte)ArrayFlags.Complex) == (byte)ArrayFlags.Complex; |
|||
|
|||
if (isComplex) |
|||
{ |
|||
throw new NotSupportedException(Resources.ComplexMatricesNotSupported); |
|||
} |
|||
|
|||
// skip unneeded bytes
|
|||
reader.BaseStream.Seek(10, SeekOrigin.Current); |
|||
|
|||
var numDimensions = reader.ReadInt32() / 8; |
|||
if (numDimensions > 2) |
|||
{ |
|||
throw new NotSupportedException(Resources.MoreThan2D); |
|||
} |
|||
|
|||
var rows = reader.ReadInt32(); |
|||
var columns = reader.ReadInt32(); |
|||
|
|||
// skip unneeded bytes
|
|||
reader.BaseStream.Seek(2, SeekOrigin.Current); |
|||
int size = reader.ReadInt16(); |
|||
var smallBlock = true; |
|||
if (size == 0) |
|||
{ |
|||
size = reader.ReadInt32(); |
|||
smallBlock = false; |
|||
} |
|||
|
|||
var name = Encoding.ASCII.GetString(reader.ReadBytes(size)); |
|||
AlignData(reader.BaseStream, size, smallBlock); |
|||
|
|||
// only grab wanted objects
|
|||
if (_names.Count != 0 && !_names.Contains(name)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
var type = (DataType)reader.ReadInt16(); |
|||
size = reader.ReadInt16(); |
|||
if (size == 0) |
|||
{ |
|||
size = reader.ReadInt32(); |
|||
} |
|||
|
|||
Matrix<float> matrix; |
|||
switch (arrayClass) |
|||
{ |
|||
case ArrayClass.Sparse: |
|||
matrix = PopulateSparseMatrix(reader, rows, columns, size); |
|||
break; |
|||
case ArrayClass.Function: |
|||
case ArrayClass.Character: |
|||
case ArrayClass.Object: |
|||
case ArrayClass.Structure: |
|||
case ArrayClass.Cell: |
|||
case ArrayClass.Unknown: |
|||
throw new NotImplementedException(); |
|||
default: |
|||
matrix = PopulateDenseMatrix(type, reader, rows, columns); |
|||
break; |
|||
} |
|||
|
|||
file.Matrices.Add(name, matrix); |
|||
if (file.FirstMatrixName == null) |
|||
{ |
|||
file.FirstMatrixName = name; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Populates a sparse matrix.
|
|||
/// </summary>
|
|||
/// <param name="reader">The reader.</param>
|
|||
/// <param name="rows">The number of rows.</param>
|
|||
/// <param name="columns">The number of columns.</param>
|
|||
/// <param name="size">The size of the block.</param>
|
|||
/// <returns>A populated sparse matrix.</returns>
|
|||
private static Matrix<float> PopulateSparseMatrix(BinaryReader reader, int rows, int columns, int size) |
|||
{ |
|||
// populate the row data array
|
|||
var ir = new int[size / 4]; |
|||
for (var i = 0; i < ir.Length; i++) |
|||
{ |
|||
ir[i] = reader.ReadInt32(); |
|||
} |
|||
|
|||
AlignData(reader.BaseStream, size, false); |
|||
|
|||
// skip data type since it will always be int32
|
|||
reader.BaseStream.Seek(4, SeekOrigin.Current); |
|||
|
|||
// populate the column data array
|
|||
var jcsize = reader.ReadInt32(); |
|||
var jc = new int[jcsize / 4]; |
|||
for (var j = 0; j < jc.Length; j++) |
|||
{ |
|||
jc[j] = reader.ReadInt32(); |
|||
} |
|||
|
|||
AlignData(reader.BaseStream, jcsize, false); |
|||
|
|||
var type = (DataType)reader.ReadInt32(); |
|||
|
|||
// skip length since we already no it for the number of rows
|
|||
reader.BaseStream.Seek(4, SeekOrigin.Current); |
|||
|
|||
Matrix<float> matrix = new SparseMatrix(rows, columns); |
|||
var col = 0; |
|||
for (var i = 0; i < ir.Length; i++) |
|||
{ |
|||
var row = ir[i]; |
|||
if (jc[col + 1] == i) |
|||
{ |
|||
col++; |
|||
} |
|||
|
|||
switch (type) |
|||
{ |
|||
case DataType.Int8: |
|||
matrix[row, col] = reader.ReadSByte(); |
|||
break; |
|||
case DataType.UInt8: |
|||
matrix[row, col] = reader.ReadByte(); |
|||
break; |
|||
case DataType.Int16: |
|||
matrix[row, col] = reader.ReadInt16(); |
|||
break; |
|||
|
|||
case DataType.UInt16: |
|||
matrix[row, col] = reader.ReadUInt16(); |
|||
break; |
|||
case DataType.Int32: |
|||
matrix[row, col] = reader.ReadInt32(); |
|||
break; |
|||
|
|||
case DataType.UInt32: |
|||
matrix[row, col] = reader.ReadUInt32(); |
|||
break; |
|||
case DataType.Single: |
|||
matrix[row, col] = reader.ReadSingle(); |
|||
break; |
|||
case DataType.Int64: |
|||
matrix[row, col] = reader.ReadInt64(); |
|||
break; |
|||
case DataType.UInt64: |
|||
matrix[row, col] = reader.ReadUInt64(); |
|||
break; |
|||
case DataType.Double: |
|||
matrix[row, col] = (float)reader.ReadDouble(); |
|||
break; |
|||
default: |
|||
throw new NotSupportedException(); |
|||
} |
|||
} |
|||
|
|||
return matrix; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Populates a dense matrix.
|
|||
/// </summary>
|
|||
/// <param name="type">The type of data.</param>
|
|||
/// <param name="reader">The reader.</param>
|
|||
/// <param name="rows">The number of rows.</param>
|
|||
/// <param name="columns">The number of columns.</param>
|
|||
/// <returns>Returns a populated dense matrix.</returns>
|
|||
private static Matrix<float> PopulateDenseMatrix(DataType type, BinaryReader reader, int rows, int columns) |
|||
{ |
|||
Matrix<float> matrix = new DenseMatrix(rows, columns); |
|||
switch (type) |
|||
{ |
|||
case DataType.Int8: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadSByte(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.UInt8: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadByte(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.Int16: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadInt16(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.UInt16: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadUInt16(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.Int32: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadInt32(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.UInt32: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadUInt32(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.Single: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadSingle(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.Int64: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadInt64(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.UInt64: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = reader.ReadUInt64(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
case DataType.Double: |
|||
for (var j = 0; j < columns; j++) |
|||
{ |
|||
for (var i = 0; i < rows; i++) |
|||
{ |
|||
matrix[i, j] = (float)reader.ReadDouble(); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
default: |
|||
throw new NotSupportedException(); |
|||
} |
|||
|
|||
return matrix; |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue