Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions NumFlat/Mat/Mat.Complex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,5 +199,147 @@ public static void Imaginary(in Mat<Complex> x, in Mat<double> destination)
od += destination.Stride;
}
}

/// <summary>
/// Computes the magnitude of each element in the complex matrix.
/// </summary>
/// <param name="x">
/// The complex matrix.
/// </param>
/// <param name="destination">
/// The destination of the magnitudes.
/// </param>
/// <remarks>
/// This method does not allocate managed heap memory.
/// </remarks>
public static void Magnitude(in Mat<Complex> x, in Mat<double> destination)
{
ThrowHelper.ThrowIfEmpty(x, nameof(x));
ThrowHelper.ThrowIfEmpty(destination, nameof(destination));

if (destination.RowCount != x.RowCount)
{
throw new ArgumentException("'destination.RowCount' must match 'x.RowCount'.");
}

if (destination.ColCount != x.ColCount)
{
throw new ArgumentException("'destination.ColCount' must match 'x.ColCount'.");
}

var sx = x.Memory.Span;
var sd = destination.Memory.Span;
var ox = 0;
var od = 0;
while (od < sd.Length)
{
var px = ox;
var pd = od;
var end = od + destination.RowCount;
while (pd < end)
{
sd[pd] = sx[px].Magnitude;
px++;
pd++;
}
ox += x.Stride;
od += destination.Stride;
}
}

/// <summary>
/// Computes the squared magnitude of each element in the complex matrix.
/// </summary>
/// <param name="x">
/// The complex matrix.
/// </param>
/// <param name="destination">
/// The destination of the squared magnitudes.
/// </param>
/// <remarks>
/// This method does not allocate managed heap memory.
/// </remarks>
public static void MagnitudeSquared(in Mat<Complex> x, in Mat<double> destination)
{
ThrowHelper.ThrowIfEmpty(x, nameof(x));
ThrowHelper.ThrowIfEmpty(destination, nameof(destination));

if (destination.RowCount != x.RowCount)
{
throw new ArgumentException("'destination.RowCount' must match 'x.RowCount'.");
}

if (destination.ColCount != x.ColCount)
{
throw new ArgumentException("'destination.ColCount' must match 'x.ColCount'.");
}

var sx = x.Memory.Span;
var sd = destination.Memory.Span;
var ox = 0;
var od = 0;
while (od < sd.Length)
{
var px = ox;
var pd = od;
var end = od + destination.RowCount;
while (pd < end)
{
var value = sx[px];
sd[pd] = value.Real * value.Real + value.Imaginary * value.Imaginary;
px++;
pd++;
}
ox += x.Stride;
od += destination.Stride;
}
}

/// <summary>
/// Computes the phase of each element in the complex matrix.
/// </summary>
/// <param name="x">
/// The complex matrix.
/// </param>
/// <param name="destination">
/// The destination of the phases.
/// </param>
/// <remarks>
/// This method does not allocate managed heap memory.
/// </remarks>
public static void Phase(in Mat<Complex> x, in Mat<double> destination)
{
ThrowHelper.ThrowIfEmpty(x, nameof(x));
ThrowHelper.ThrowIfEmpty(destination, nameof(destination));

if (destination.RowCount != x.RowCount)
{
throw new ArgumentException("'destination.RowCount' must match 'x.RowCount'.");
}

if (destination.ColCount != x.ColCount)
{
throw new ArgumentException("'destination.ColCount' must match 'x.ColCount'.");
}

var sx = x.Memory.Span;
var sd = destination.Memory.Span;
var ox = 0;
var od = 0;
while (od < sd.Length)
{
var px = ox;
var pd = od;
var end = od + destination.RowCount;
while (pd < end)
{
sd[pd] = sx[px].Phase;
px++;
pd++;
}
ox += x.Stride;
od += destination.Stride;
}
}
}
}
66 changes: 66 additions & 0 deletions NumFlat/Mat/MatrixExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,72 @@ public static Mat<double> Imaginary(in this Mat<Complex> x)
return result;
}

/// <summary>
/// Computes the magnitude of each element in the complex matrix.
/// </summary>
/// <param name="x">
/// The complex matrix.
/// </param>
/// <returns>
/// The magnitudes of the complex matrix.
/// </returns>
/// <remarks>
/// This method allocates a new matrix which is independent from the original matrix.
/// To avoid the allocation, use <see cref="Mat.Magnitude(in Mat{Complex}, in Mat{double})"/> instead.
/// </remarks>
public static Mat<double> Magnitude(in this Mat<Complex> x)
{
ThrowHelper.ThrowIfEmpty(x, nameof(x));

var result = new Mat<double>(x.RowCount, x.ColCount);
Mat.Magnitude(x, result);
return result;
}

/// <summary>
/// Computes the squared magnitude of each element in the complex matrix.
/// </summary>
/// <param name="x">
/// The complex matrix.
/// </param>
/// <returns>
/// The squared magnitudes of the complex matrix.
/// </returns>
/// <remarks>
/// This method allocates a new matrix which is independent from the original matrix.
/// To avoid the allocation, use <see cref="Mat.MagnitudeSquared(in Mat{Complex}, in Mat{double})"/> instead.
/// </remarks>
public static Mat<double> MagnitudeSquared(in this Mat<Complex> x)
{
ThrowHelper.ThrowIfEmpty(x, nameof(x));

var result = new Mat<double>(x.RowCount, x.ColCount);
Mat.MagnitudeSquared(x, result);
return result;
}

/// <summary>
/// Computes the phase of each element in the complex matrix.
/// </summary>
/// <param name="x">
/// The complex matrix.
/// </param>
/// <returns>
/// The phases of the complex matrix.
/// </returns>
/// <remarks>
/// This method allocates a new matrix which is independent from the original matrix.
/// To avoid the allocation, use <see cref="Mat.Phase(in Mat{Complex}, in Mat{double})"/> instead.
/// </remarks>
public static Mat<double> Phase(in this Mat<Complex> x)
{
ThrowHelper.ThrowIfEmpty(x, nameof(x));

var result = new Mat<double>(x.RowCount, x.ColCount);
Mat.Phase(x, result);
return result;
}

/// <summary>
/// Computes a matrix inversion, <c>X^-1</c>.
/// </summary>
Expand Down
103 changes: 103 additions & 0 deletions NumFlat/Vec/Vec.Complex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,108 @@ public static void Imaginary(in Vec<Complex> x, in Vec<double> destination)
pd += destination.Stride;
}
}

/// <summary>
/// Computes the magnitude of each element in the complex vector.
/// </summary>
/// <param name="x">
/// The complex vector.
/// </param>
/// <param name="destination">
/// The destination of the magnitudes.
/// </param>
/// <remarks>
/// This method does not allocate managed heap memory.
/// </remarks>
public static void Magnitude(in Vec<Complex> x, in Vec<double> destination)
{
ThrowHelper.ThrowIfEmpty(x, nameof(x));
ThrowHelper.ThrowIfEmpty(destination, nameof(destination));

if (destination.Count != x.Count)
{
throw new ArgumentException("'destination.Count' must match 'x.Count'.");
}

var sx = x.Memory.Span;
var sd = destination.Memory.Span;
var px = 0;
var pd = 0;
while (pd < sd.Length)
{
sd[pd] = sx[px].Magnitude;
px += x.Stride;
pd += destination.Stride;
}
}

/// <summary>
/// Computes the squared magnitude of each element in the complex vector.
/// </summary>
/// <param name="x">
/// The complex vector.
/// </param>
/// <param name="destination">
/// The destination of the squared magnitudes.
/// </param>
/// <remarks>
/// This method does not allocate managed heap memory.
/// </remarks>
public static void MagnitudeSquared(in Vec<Complex> x, in Vec<double> destination)
{
ThrowHelper.ThrowIfEmpty(x, nameof(x));
ThrowHelper.ThrowIfEmpty(destination, nameof(destination));

if (destination.Count != x.Count)
{
throw new ArgumentException("'destination.Count' must match 'x.Count'.");
}

var sx = x.Memory.Span;
var sd = destination.Memory.Span;
var px = 0;
var pd = 0;
while (pd < sd.Length)
{
var value = sx[px];
sd[pd] = value.Real * value.Real + value.Imaginary * value.Imaginary;
px += x.Stride;
pd += destination.Stride;
}
}

/// <summary>
/// Computes the phase of each element in the complex vector.
/// </summary>
/// <param name="x">
/// The complex vector.
/// </param>
/// <param name="destination">
/// The destination of the phases.
/// </param>
/// <remarks>
/// This method does not allocate managed heap memory.
/// </remarks>
public static void Phase(in Vec<Complex> x, in Vec<double> destination)
{
ThrowHelper.ThrowIfEmpty(x, nameof(x));
ThrowHelper.ThrowIfEmpty(destination, nameof(destination));

if (destination.Count != x.Count)
{
throw new ArgumentException("'destination.Count' must match 'x.Count'.");
}

var sx = x.Memory.Span;
var sd = destination.Memory.Span;
var px = 0;
var pd = 0;
while (pd < sd.Length)
{
sd[pd] = sx[px].Phase;
px += x.Stride;
pd += destination.Stride;
}
}
}
}
Loading