Support complex numerical arrays
This commit is contained in:
parent
beae9e4429
commit
b0ae15abc9
@ -1,5 +1,6 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
namespace MatFileHandler.Tests
|
namespace MatFileHandler.Tests
|
||||||
{
|
{
|
||||||
@ -68,6 +69,32 @@ namespace MatFileHandler.Tests
|
|||||||
Assert.That(matrix[2, 1], Is.EqualTo(6.0));
|
Assert.That(matrix[2, 1], Is.EqualTo(6.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test reading a two-dimensional complex array.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestComplexMatrix()
|
||||||
|
{
|
||||||
|
var matFile = ReadHdfTestFile("matrix_complex");
|
||||||
|
var matrix = matFile["matrix"].Value as IArrayOf<Complex>;
|
||||||
|
Assert.That(matrix.Dimensions, Is.EqualTo(new[] { 3, 2 }));
|
||||||
|
Assert.That(matrix.ConvertToComplexArray(), Is.EqualTo(new[]
|
||||||
|
{
|
||||||
|
new Complex(1.0, 4.0),
|
||||||
|
new Complex(3.0, 1.0),
|
||||||
|
new Complex(5.0, 0.25),
|
||||||
|
new Complex(2.0, 2.0),
|
||||||
|
new Complex(4.0, 0.5),
|
||||||
|
new Complex(6.0, 0.125),
|
||||||
|
}));
|
||||||
|
Assert.That(matrix[0, 0], Is.EqualTo(new Complex(1.0, 4.0)));
|
||||||
|
Assert.That(matrix[0, 1], Is.EqualTo(new Complex(2.0, 2.0)));
|
||||||
|
Assert.That(matrix[1, 0], Is.EqualTo(new Complex(3.0, 1.0)));
|
||||||
|
Assert.That(matrix[1, 1], Is.EqualTo(new Complex(4.0, 0.5)));
|
||||||
|
Assert.That(matrix[2, 0], Is.EqualTo(new Complex(5.0, 0.25)));
|
||||||
|
Assert.That(matrix[2, 1], Is.EqualTo(new Complex(6.0, 0.125)));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Test reading lower and upper limits of integer data types.
|
/// Test reading lower and upper limits of integer data types.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -102,6 +129,51 @@ namespace MatFileHandler.Tests
|
|||||||
CheckLimits(array as IArrayOf<ulong>, CommonData.UInt64Limits);
|
CheckLimits(array as IArrayOf<ulong>, CommonData.UInt64Limits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test writing lower and upper limits of integer-based complex data types.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestComplexLimits()
|
||||||
|
{
|
||||||
|
var matFile = ReadHdfTestFile("limits_complex");
|
||||||
|
IArray array;
|
||||||
|
array = matFile["int8_complex"].Value;
|
||||||
|
CheckComplexLimits(array as IArrayOf<ComplexOf<sbyte>>, CommonData.Int8Limits);
|
||||||
|
Assert.That(
|
||||||
|
array.ConvertToComplexArray(),
|
||||||
|
Is.EqualTo(new[] { -128.0 + (127.0 * Complex.ImaginaryOne), 127.0 - (128.0 * Complex.ImaginaryOne) }));
|
||||||
|
|
||||||
|
array = matFile["uint8_complex"].Value;
|
||||||
|
CheckComplexLimits(array as IArrayOf<ComplexOf<byte>>, CommonData.UInt8Limits);
|
||||||
|
|
||||||
|
array = matFile["int16_complex"].Value;
|
||||||
|
CheckComplexLimits(array as IArrayOf<ComplexOf<short>>, CommonData.Int16Limits);
|
||||||
|
|
||||||
|
array = matFile["uint16_complex"].Value;
|
||||||
|
CheckComplexLimits(array as IArrayOf<ComplexOf<ushort>>, CommonData.UInt16Limits);
|
||||||
|
|
||||||
|
array = matFile["int32_complex"].Value;
|
||||||
|
CheckComplexLimits(array as IArrayOf<ComplexOf<int>>, CommonData.Int32Limits);
|
||||||
|
|
||||||
|
array = matFile["uint32_complex"].Value;
|
||||||
|
CheckComplexLimits(array as IArrayOf<ComplexOf<uint>>, CommonData.UInt32Limits);
|
||||||
|
|
||||||
|
array = matFile["int64_complex"].Value;
|
||||||
|
CheckComplexLimits(array as IArrayOf<ComplexOf<long>>, CommonData.Int64Limits);
|
||||||
|
|
||||||
|
array = matFile["uint64_complex"].Value;
|
||||||
|
CheckComplexLimits(array as IArrayOf<ComplexOf<ulong>>, CommonData.UInt64Limits);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CheckComplexLimits<T>(IArrayOf<ComplexOf<T>> array, T[] limits)
|
||||||
|
where T : struct
|
||||||
|
{
|
||||||
|
Assert.That(array, Is.Not.Null);
|
||||||
|
Assert.That(array.Dimensions, Is.EqualTo(new[] { 1, 2 }));
|
||||||
|
Assert.That(array[0], Is.EqualTo(new ComplexOf<T>(limits[0], limits[1])));
|
||||||
|
Assert.That(array[1], Is.EqualTo(new ComplexOf<T>(limits[1], limits[0])));
|
||||||
|
}
|
||||||
|
|
||||||
private static void CheckLimits<T>(IArrayOf<T> array, T[] limits)
|
private static void CheckLimits<T>(IArrayOf<T> array, T[] limits)
|
||||||
where T : struct
|
where T : struct
|
||||||
{
|
{
|
||||||
|
BIN
MatFileHandler.Tests/test-data/hdf/limits_complex.mat
Normal file
BIN
MatFileHandler.Tests/test-data/hdf/limits_complex.mat
Normal file
Binary file not shown.
BIN
MatFileHandler.Tests/test-data/hdf/matrix_complex.mat
Normal file
BIN
MatFileHandler.Tests/test-data/hdf/matrix_complex.mat
Normal file
Binary file not shown.
@ -393,6 +393,38 @@ namespace MatFileHandler
|
|||||||
var numberOfElements = dims.NumberOfElements();
|
var numberOfElements = dims.NumberOfElements();
|
||||||
var dataSize = numberOfElements * SizeOfArrayElement(arrayType);
|
var dataSize = numberOfElements * SizeOfArrayElement(arrayType);
|
||||||
var storageSize = (int)H5D.get_storage_size(datasetId);
|
var storageSize = (int)H5D.get_storage_size(datasetId);
|
||||||
|
var dataSetType = H5D.get_type(datasetId);
|
||||||
|
var dataSetTypeClass = H5T.get_class(dataSetType);
|
||||||
|
var isCompound = dataSetTypeClass == H5T.class_t.COMPOUND;
|
||||||
|
if (isCompound)
|
||||||
|
{
|
||||||
|
var h5Type = H5tTypeFromArrayType(arrayType);
|
||||||
|
var h5Size = H5T.get_size(h5Type);
|
||||||
|
var h5tComplexReal = H5T.create(H5T.class_t.COMPOUND, h5Size);
|
||||||
|
H5T.insert(h5tComplexReal, "real", IntPtr.Zero, h5Type);
|
||||||
|
var realData = ReadDataset(datasetId, h5tComplexReal, dataSize);
|
||||||
|
var convertedRealData = ConvertDataToProperType<T>(realData, arrayType);
|
||||||
|
var h5tComplexImaginary = H5T.create(H5T.class_t.COMPOUND, h5Size);
|
||||||
|
H5T.insert(h5tComplexImaginary, "imag", IntPtr.Zero, h5Type);
|
||||||
|
var imaginaryData = ReadDataset(datasetId, h5tComplexImaginary, dataSize);
|
||||||
|
var convertedImaginaryData = ConvertDataToProperType<T>(imaginaryData, arrayType);
|
||||||
|
if (arrayType == ArrayType.MxDouble)
|
||||||
|
{
|
||||||
|
var complexData =
|
||||||
|
(convertedRealData as double[])
|
||||||
|
.Zip(convertedImaginaryData as double[], (x, y) => new Complex(x, y))
|
||||||
|
.ToArray();
|
||||||
|
return new HdfNumericalArrayOf<Complex>(dims, complexData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var complexData =
|
||||||
|
convertedRealData
|
||||||
|
.Zip(convertedImaginaryData, (x, y) => new ComplexOf<T>(x, y))
|
||||||
|
.ToArray();
|
||||||
|
return new HdfNumericalArrayOf<ComplexOf<T>>(dims, complexData);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (dataSize != storageSize)
|
if (dataSize != storageSize)
|
||||||
{
|
{
|
||||||
throw new Exception("Data size mismatch.");
|
throw new Exception("Data size mismatch.");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user