Browse Source

Linear Algebra: VectorStorage and MatrixStorage DataContract for ephemeral serialization #350

pull/362/head
Christoph Ruegg 11 years ago
parent
commit
550d71bef0
  1. 3
      src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs
  2. 3
      src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs
  3. 3
      src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs
  4. 8
      src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs
  5. 5
      src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs
  6. 5
      src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs
  7. 4
      src/Numerics/LinearAlgebra/Storage/VectorStorage.cs
  8. 141
      src/UnitTests/LinearAlgebraTests/MatrixStorageSerializationTests.cs
  9. 117
      src/UnitTests/LinearAlgebraTests/VectorStorageSerializationTests.cs
  10. 2
      src/UnitTests/UnitTests.csproj

3
src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs

@ -31,17 +31,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Threading;
namespace MathNet.Numerics.LinearAlgebra.Storage
{
[Serializable]
[DataContract(Namespace = "urn:MathNet/Numerics/LinearAlgebra")]
public class DenseColumnMajorMatrixStorage<T> : MatrixStorage<T>
where T : struct, IEquatable<T>, IFormattable
{
// [ruegg] public fields are OK here
[DataMember(Order = 1)]
public readonly T[] Data;
internal DenseColumnMajorMatrixStorage(int rows, int columns)

3
src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs

@ -31,17 +31,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Threading;
namespace MathNet.Numerics.LinearAlgebra.Storage
{
[Serializable]
[DataContract(Namespace = "urn:MathNet/Numerics/LinearAlgebra")]
public class DenseVectorStorage<T> : VectorStorage<T>
where T : struct, IEquatable<T>, IFormattable
{
// [ruegg] public fields are OK here
[DataMember(Order = 1)]
public readonly T[] Data;
internal DenseVectorStorage(int length)

3
src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs

@ -31,17 +31,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Threading;
namespace MathNet.Numerics.LinearAlgebra.Storage
{
[Serializable]
[DataContract(Namespace = "urn:MathNet/Numerics/LinearAlgebra")]
public class DiagonalMatrixStorage<T> : MatrixStorage<T>
where T : struct, IEquatable<T>, IFormattable
{
// [ruegg] public fields are OK here
[DataMember(Order = 1)]
public readonly T[] Data;
internal DiagonalMatrixStorage(int rows, int columns)

8
src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2014 Math.NET
// Copyright (c) 2009-2015 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -30,18 +30,24 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Storage
{
[Serializable]
[DataContract(Namespace = "urn:MathNet/Numerics/LinearAlgebra")]
public abstract partial class MatrixStorage<T> : IEquatable<MatrixStorage<T>>
where T : struct, IEquatable<T>, IFormattable
{
// [ruegg] public fields are OK here
protected static readonly T Zero = BuilderInstance<T>.Matrix.Zero;
[DataMember(Order = 1)]
public readonly int RowCount;
[DataMember(Order = 2)]
public readonly int ColumnCount;
protected MatrixStorage(int rowCount, int columnCount)

5
src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs

@ -31,11 +31,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Storage
{
[Serializable]
[DataContract(Namespace = "urn:MathNet/Numerics/LinearAlgebra")]
public class SparseCompressedRowMatrixStorage<T> : MatrixStorage<T>
where T : struct, IEquatable<T>, IFormattable
{
@ -47,18 +49,21 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
/// The last value is equal to ValueCount, so that the number of non-zero entries in row "i" is always
/// given by RowPointers[i+i] - RowPointers[i]. This array thus has length RowCount+1.
/// </summary>
[DataMember(Order = 1)]
public readonly int[] RowPointers;
/// <summary>
/// An array containing the column indices of the non-zero values. Element "j" of the array
/// is the number of the column in matrix that contains the j-th value in the <see cref="Values"/> array.
/// </summary>
[DataMember(Order = 2)]
public int[] ColumnIndices;
/// <summary>
/// Array that contains the non-zero elements of matrix. Values of the non-zero elements of matrix are mapped into the values
/// array using the row-major storage mapping described in a compressed sparse row (CSR) format.
/// </summary>
[DataMember(Order = 3)]
public T[] Values;
/// <summary>

5
src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs

@ -32,12 +32,14 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Threading;
namespace MathNet.Numerics.LinearAlgebra.Storage
{
[Serializable]
[DataContract(Namespace = "urn:MathNet/Numerics/LinearAlgebra")]
public class SparseVectorStorage<T> : VectorStorage<T>
where T : struct, IEquatable<T>, IFormattable
{
@ -46,16 +48,19 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
/// <summary>
/// Array that contains the indices of the non-zero values.
/// </summary>
[DataMember(Order = 1)]
public int[] Indices;
/// <summary>
/// Array that contains the non-zero elements of the vector.
/// </summary>
[DataMember(Order = 2)]
public T[] Values;
/// <summary>
/// Gets the number of non-zero elements in the vector.
/// </summary>
[DataMember(Order = 3)]
public int ValueCount;
internal SparseVectorStorage(int length)

4
src/Numerics/LinearAlgebra/Storage/VectorStorage.cs

@ -30,17 +30,21 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Storage
{
[Serializable]
[DataContract(Namespace = "urn:MathNet/Numerics/LinearAlgebra")]
public abstract partial class VectorStorage<T> : IEquatable<VectorStorage<T>>
where T : struct, IEquatable<T>, IFormattable
{
// [ruegg] public fields are OK here
protected static readonly T Zero = BuilderInstance<T>.Vector.Zero;
[DataMember(Order = 1)]
public readonly int Length;
protected VectorStorage(int length)

141
src/UnitTests/LinearAlgebraTests/MatrixStorageSerializationTests.cs

@ -0,0 +1,141 @@
using System;
using System.IO;
using System.Runtime.Serialization;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Storage;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
{
#if NOSYSNUMERICS
using Complex64 = Numerics.Complex;
#else
using Complex64 = System.Numerics.Complex;
#endif
[TestFixture]
public class MatrixStorageSerializationTests
{
static readonly Type[] KnownTypes =
{
typeof(DenseColumnMajorMatrixStorage<double>), typeof(SparseCompressedRowMatrixStorage<double>), typeof(DiagonalMatrixStorage<double>),
typeof(DenseColumnMajorMatrixStorage<float>), typeof(SparseCompressedRowMatrixStorage<float>), typeof(DiagonalMatrixStorage<float>),
typeof(DenseColumnMajorMatrixStorage<Numerics.Complex32>), typeof(SparseCompressedRowMatrixStorage<Numerics.Complex32>), typeof(DiagonalMatrixStorage<Numerics.Complex32>),
typeof(DenseColumnMajorMatrixStorage<Complex64>), typeof(SparseCompressedRowMatrixStorage<Complex64>), typeof(DiagonalMatrixStorage<Complex64>)
};
[Test]
public void DenseColumnMajorMatrixStorageOfDoubleDataContractSerializationTest()
{
MatrixStorage<double> expected = Matrix<double>.Build.Dense(2, 2, new[] { 1.0d, 2.0d, 0.0d, 3.0d }).Storage;
var serializer = new DataContractSerializer(typeof(MatrixStorage<double>), KnownTypes);
var stream = new MemoryStream();
serializer.WriteObject(stream, expected);
stream.Position = 0;
var actual = (MatrixStorage<double>)serializer.ReadObject(stream);
Assert.That(actual.RowCount, Is.EqualTo(expected.RowCount));
Assert.That(actual.ColumnCount, Is.EqualTo(expected.ColumnCount));
Assert.That(actual, Is.TypeOf(typeof(DenseColumnMajorMatrixStorage<double>)));
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.SameAs(expected));
}
[Test]
public void DenseColumnMajorMatrixStorageOfSingleDataContractSerializationTest()
{
MatrixStorage<float> expected = Matrix<float>.Build.Dense(2, 2, new[] { 1.0f, 2.0f, 0.0f, 3.0f }).Storage;
var serializer = new DataContractSerializer(typeof(MatrixStorage<float>), KnownTypes);
var stream = new MemoryStream();
serializer.WriteObject(stream, expected);
stream.Position = 0;
var actual = (MatrixStorage<float>)serializer.ReadObject(stream);
Assert.That(actual.RowCount, Is.EqualTo(expected.RowCount));
Assert.That(actual.ColumnCount, Is.EqualTo(expected.ColumnCount));
Assert.That(actual, Is.TypeOf(typeof(DenseColumnMajorMatrixStorage<float>)));
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.SameAs(expected));
}
[Test]
public void DenseColumnMajorMatrixStorageOfComplex64DataContractSerializationTest()
{
MatrixStorage<Complex64> expected = Matrix<Complex64>.Build.Dense(2, 2, new[] { new Complex64(1.0, -1.0), 2.0, 0.0, 3.0 }).Storage;
var serializer = new DataContractSerializer(typeof(MatrixStorage<Complex64>), KnownTypes);
var stream = new MemoryStream();
serializer.WriteObject(stream, expected);
stream.Position = 0;
var actual = (MatrixStorage<Complex64>)serializer.ReadObject(stream);
Assert.That(actual.RowCount, Is.EqualTo(expected.RowCount));
Assert.That(actual.ColumnCount, Is.EqualTo(expected.ColumnCount));
Assert.That(actual, Is.TypeOf(typeof(DenseColumnMajorMatrixStorage<Complex64>)));
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.SameAs(expected));
}
[Test]
public void DenseColumnMajorMatrixStorageOfComplex32DataContractSerializationTest()
{
MatrixStorage<Numerics.Complex32> expected = Matrix<Numerics.Complex32>.Build.Dense(2, 2, new[] { new Numerics.Complex32(1.0f, -1.0f), 2.0f, 0.0f, 3.0f }).Storage;
var serializer = new DataContractSerializer(typeof(MatrixStorage<Numerics.Complex32>), KnownTypes);
var stream = new MemoryStream();
serializer.WriteObject(stream, expected);
stream.Position = 0;
var actual = (MatrixStorage<Numerics.Complex32>)serializer.ReadObject(stream);
Assert.That(actual.RowCount, Is.EqualTo(expected.RowCount));
Assert.That(actual.ColumnCount, Is.EqualTo(expected.ColumnCount));
Assert.That(actual, Is.TypeOf(typeof(DenseColumnMajorMatrixStorage<Numerics.Complex32>)));
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.SameAs(expected));
}
[Test]
public void SparseCompressedRowMatrixStorageOfDoubleDataContractSerializationTest()
{
MatrixStorage<double> expected = Matrix<double>.Build.SparseOfArray(new[,] { {1.0d, 2.0d}, {0.0d, 3.0d} }).Storage;
var serializer = new DataContractSerializer(typeof(MatrixStorage<double>), KnownTypes);
var stream = new MemoryStream();
serializer.WriteObject(stream, expected);
stream.Position = 0;
var actual = (MatrixStorage<double>)serializer.ReadObject(stream);
Assert.That(actual.RowCount, Is.EqualTo(expected.RowCount));
Assert.That(actual.ColumnCount, Is.EqualTo(expected.ColumnCount));
Assert.That(actual, Is.TypeOf(typeof(SparseCompressedRowMatrixStorage<double>)));
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.SameAs(expected));
}
[Test]
public void DiagonalMatrixStorageOfDoubleDataContractSerializationTest()
{
MatrixStorage<double> expected = Matrix<double>.Build.Diagonal(new[] { 1.0d, 2.0d, 0.0d, 3.0d }).Storage;
var serializer = new DataContractSerializer(typeof(MatrixStorage<double>), KnownTypes);
var stream = new MemoryStream();
serializer.WriteObject(stream, expected);
stream.Position = 0;
var actual = (MatrixStorage<double>)serializer.ReadObject(stream);
Assert.That(actual.RowCount, Is.EqualTo(expected.RowCount));
Assert.That(actual.ColumnCount, Is.EqualTo(expected.ColumnCount));
Assert.That(actual, Is.TypeOf(typeof(DiagonalMatrixStorage<double>)));
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.SameAs(expected));
}
}
}

117
src/UnitTests/LinearAlgebraTests/VectorStorageSerializationTests.cs

@ -0,0 +1,117 @@
using System;
using System.IO;
using System.Runtime.Serialization;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Storage;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
{
#if NOSYSNUMERICS
using Complex64 = Numerics.Complex;
#else
using Complex64 = System.Numerics.Complex;
#endif
[TestFixture]
public class VectorStorageSerializationTests
{
static readonly Type[] KnownTypes =
{
typeof(DenseVectorStorage<double>), typeof(SparseVectorStorage<double>),
typeof(DenseVectorStorage<float>), typeof(SparseVectorStorage<float>),
typeof(DenseVectorStorage<Numerics.Complex32>), typeof(SparseVectorStorage<Numerics.Complex32>),
typeof(DenseVectorStorage<Complex64>), typeof(SparseVectorStorage<Complex64>)
};
[Test]
public void DenseVectorStorageOfDoubleDataContractSerializationTest()
{
VectorStorage<double> expected = Vector<double>.Build.DenseOfArray(new[] { 1.0d, 2.0d, 0.0d, 3.0d }).Storage;
var serializer = new DataContractSerializer(typeof(VectorStorage<double>), KnownTypes);
var stream = new MemoryStream();
serializer.WriteObject(stream, expected);
stream.Position = 0;
var actual = (VectorStorage<double>)serializer.ReadObject(stream);
Assert.That(actual.Length, Is.EqualTo(expected.Length));
Assert.That(actual, Is.TypeOf(typeof(DenseVectorStorage<double>)));
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.SameAs(expected));
}
[Test]
public void DenseVectorStorageOfSingleDataContractSerializationTest()
{
VectorStorage<float> expected = Vector<float>.Build.DenseOfArray(new[] { 1.0f, 2.0f, 0.0f, 3.0f }).Storage;
var serializer = new DataContractSerializer(typeof(VectorStorage<float>), KnownTypes);
var stream = new MemoryStream();
serializer.WriteObject(stream, expected);
stream.Position = 0;
var actual = (VectorStorage<float>)serializer.ReadObject(stream);
Assert.That(actual.Length, Is.EqualTo(expected.Length));
Assert.That(actual, Is.TypeOf(typeof(DenseVectorStorage<float>)));
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.SameAs(expected));
}
[Test]
public void DenseVectorStorageOfComplex64DataContractSerializationTest()
{
VectorStorage<Complex64> expected = Vector<Complex64>.Build.DenseOfArray(new[] { new Complex64(1.0, -1.0), 2.0, 0.0, 3.0 }).Storage;
var serializer = new DataContractSerializer(typeof(VectorStorage<Complex64>), KnownTypes);
var stream = new MemoryStream();
serializer.WriteObject(stream, expected);
stream.Position = 0;
var actual = (VectorStorage<Complex64>)serializer.ReadObject(stream);
Assert.That(actual.Length, Is.EqualTo(expected.Length));
Assert.That(actual, Is.TypeOf(typeof(DenseVectorStorage<Complex64>)));
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.SameAs(expected));
}
[Test]
public void DenseVectorStorageOfComplex32DataContractSerializationTest()
{
VectorStorage<Numerics.Complex32> expected = Vector<Numerics.Complex32>.Build.DenseOfArray(new[] { new Numerics.Complex32(1.0f, -1.0f), 2.0f, 0.0f, 3.0f }).Storage;
var serializer = new DataContractSerializer(typeof(VectorStorage<Numerics.Complex32>), KnownTypes);
var stream = new MemoryStream();
serializer.WriteObject(stream, expected);
stream.Position = 0;
var actual = (VectorStorage<Numerics.Complex32>)serializer.ReadObject(stream);
Assert.That(actual.Length, Is.EqualTo(expected.Length));
Assert.That(actual, Is.TypeOf(typeof(DenseVectorStorage<Numerics.Complex32>)));
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.SameAs(expected));
}
[Test]
public void SparseVectorStorageOfDoubleDataContractSerializationTest()
{
VectorStorage<double> expected = Vector<double>.Build.SparseOfArray(new[] { 1.0d, 2.0d, 0.0d, 3.0d }).Storage;
var serializer = new DataContractSerializer(typeof(VectorStorage<double>), KnownTypes);
var stream = new MemoryStream();
serializer.WriteObject(stream, expected);
stream.Position = 0;
var actual = (VectorStorage<double>)serializer.ReadObject(stream);
Assert.That(actual.Length, Is.EqualTo(expected.Length));
Assert.That(actual, Is.TypeOf(typeof(SparseVectorStorage<double>)));
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.SameAs(expected));
}
}
}

2
src/UnitTests/UnitTests.csproj

@ -347,6 +347,8 @@
<Compile Include="LinearAlgebraTests\Single\VectorTests.cs" />
<Compile Include="LinearAlgebraTests\Single\VectorTests.Norm.cs" />
<Compile Include="LinearAlgebraTests\Double\VectorArithmeticTheory.cs" />
<Compile Include="LinearAlgebraTests\MatrixStorageSerializationTests.cs" />
<Compile Include="LinearAlgebraTests\VectorStorageSerializationTests.cs" />
<Compile Include="LinearAlgebraTests\TestData.cs" />
<Compile Include="LinearAlgebraTests\VectorArithmeticTheory.cs" />
<Compile Include="LinearAlgebraTests\MatrixHelpers.cs" />

Loading…
Cancel
Save