Skip to content

Commit

Permalink
Added support for user defined decimal precision for np.around() and …
Browse files Browse the repository at this point in the history
…TensorEngine.Round()
  • Loading branch information
shashi4u authored and Oceania2018 committed Dec 17, 2023
1 parent 1fed94d commit a7fdcbc
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/NumSharp.Core/Backends/Default/Math/Default.Round.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ public partial class DefaultEngine
{
public override NDArray Round(in NDArray nd, Type dtype) => Round(nd, dtype?.GetTypeCode());

public override NDArray Round(in NDArray nd, int decimals, Type dtype) => Round(nd, decimals, dtype?.GetTypeCode());

public override NDArray Round(in NDArray nd, NPTypeCode? typeCode = null)
{
if (nd.size == 0)
Expand Down Expand Up @@ -59,6 +61,61 @@ public override NDArray Round(in NDArray nd, NPTypeCode? typeCode = null)
}
default:
throw new NotSupportedException();
#endif
}
}
}

public override NDArray Round(in NDArray nd, int decimals, NPTypeCode? typeCode = null)
{
if (nd.size == 0)
return nd.Clone();

var @out = Cast(nd, ResolveUnaryReturnType(nd, typeCode), copy: true);
var len = @out.size;

unsafe
{
switch (@out.GetTypeCode)
{
#if _REGEN
%foreach except(supported_numericals, "Decimal"),except(supported_numericals_lowercase, "decimal")%
case NPTypeCode.#1:
{
var out_addr = (#2*)@out.Address;
for (int i = 0; i < len; i++) out_addr[i] = Converts.To#1(Math.Round(out_addr[i], decimals));
return @out;
}
%
case NPTypeCode.Decimal:
{
var out_addr = (decimal*)@out.Address;
for (int i = 0; i < len; i++) out_addr[i] = (DecimalEx.Round(out_addr[i], decimals));
return @out;
}
default:
throw new NotSupportedException();
#else
case NPTypeCode.Double:
{
var out_addr = (double*)@out.Address;
for (int i = 0; i < len; i++) out_addr[i] = Converts.ToDouble(Math.Round(out_addr[i], decimals));
return @out;
}
case NPTypeCode.Single:
{
var out_addr = (float*)@out.Address;
for (int i = 0; i < len; i++) out_addr[i] = Converts.ToSingle(Math.Round(out_addr[i], decimals));
return @out;
}
case NPTypeCode.Decimal:
{
var out_addr = (decimal*)@out.Address;
for (int i = 0; i < len; i++) out_addr[i] = (decimal.Round(out_addr[i], decimals));
return @out;
}
default:
throw new NotSupportedException();
#endif
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/NumSharp.Core/Backends/TensorEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ public abstract class TensorEngine
public abstract NDArray Ceil(in NDArray nd, Type dtype);
public abstract NDArray Ceil(in NDArray nd, NPTypeCode? typeCode = null);
public abstract NDArray Round(in NDArray nd, Type dtype);
public abstract NDArray Round(in NDArray nd, int decimals, Type dtype);
public abstract NDArray Round(in NDArray nd, NPTypeCode? typeCode = null);
public abstract NDArray Round(in NDArray nd, int decimals, NPTypeCode? typeCode = null);
public abstract (NDArray Fractional, NDArray Intergral) ModF(in NDArray nd, Type dtype);
public abstract (NDArray Fractional, NDArray Intergral) ModF(in NDArray nd, NPTypeCode? typeCode = null);

Expand Down
48 changes: 48 additions & 0 deletions src/NumSharp.Core/Math/np.round.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ public static partial class np
public static NDArray round_(in NDArray x, NPTypeCode? outType = null)
=> x.TensorEngine.Round(x, outType);

/// <summary>
/// Evenly round to the given number of decimals.
/// </summary>
/// <param name="x">Input array</param>
/// <param name="decimals">Number of decimal places to round to</param>
/// <param name="outType">The dtype the returned ndarray should be of, only non integer values are supported.</param>
/// <returns>An array of the same type as a, containing the rounded values. Unless out was specified, a new array is created. A reference to the result is returned.
/// The real and imaginary parts of complex numbers are rounded separately.The result of rounding a float is a float.</returns>
/// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.around.html</remarks>
public static NDArray round_(in NDArray x, int decimals, NPTypeCode? outType = null)
=> x.TensorEngine.Round(x, decimals, outType);

/// <summary>
/// Evenly round to the given number of decimals.
/// </summary>
Expand All @@ -27,6 +39,18 @@ public static NDArray round_(in NDArray x, NPTypeCode? outType = null)
public static NDArray round_(in NDArray x, Type outType)
=> x.TensorEngine.Round(x, outType);

/// <summary>
/// Evenly round to the given number of decimals.
/// </summary>
/// <param name="x">Input array</param>
/// <param name="decimals">Number of decimal places to round to</param>
/// <param name="outType">The dtype the returned ndarray should be of, only non integer values are supported.</param>
/// <returns>An array of the same type as a, containing the rounded values. Unless out was specified, a new array is created. A reference to the result is returned.
/// The real and imaginary parts of complex numbers are rounded separately.The result of rounding a float is a float.</returns>
/// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.around.html</remarks>
public static NDArray round_(in NDArray x, int decimals, Type outType)
=> x.TensorEngine.Round(x, decimals, outType);

/// <summary>
/// Evenly round to the given number of decimals.
/// </summary>
Expand All @@ -38,6 +62,18 @@ public static NDArray round_(in NDArray x, Type outType)
public static NDArray around(in NDArray x, NPTypeCode? outType = null)
=> x.TensorEngine.Round(x, outType);

/// <summary>
/// Evenly round to the given number of decimals.
/// </summary>
/// <param name="x">Input array</param>
/// <param name="decimals">Number of decimal places to round to</param>
/// <param name="outType">The dtype the returned ndarray should be of, only non integer values are supported.</param>
/// <returns>An array of the same type as a, containing the rounded values. Unless out was specified, a new array is created. A reference to the result is returned.
/// The real and imaginary parts of complex numbers are rounded separately.The result of rounding a float is a float.</returns>
/// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.around.html</remarks>
public static NDArray around(in NDArray x, int decimals, NPTypeCode? outType = null)
=> x.TensorEngine.Round(x, decimals, outType);

/// <summary>
/// Evenly round to the given number of decimals.
/// </summary>
Expand All @@ -48,5 +84,17 @@ public static NDArray around(in NDArray x, NPTypeCode? outType = null)
/// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.around.html</remarks>
public static NDArray around(in NDArray x, Type outType)
=> x.TensorEngine.Round(x, outType);

/// <summary>
/// Evenly round to the given number of decimals.
/// </summary>
/// <param name="x">Input array</param>
/// <param name="decimals">Number of decimal places to round to</param>
/// <param name="outType">The dtype the returned ndarray should be of, only non integer values are supported.</param>
/// <returns>An array of the same type as a, containing the rounded values. Unless out was specified, a new array is created. A reference to the result is returned.
/// The real and imaginary parts of complex numbers are rounded separately.The result of rounding a float is a float.</returns>
/// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.around.html</remarks>
public static NDArray around(in NDArray x, int decimals, Type outType)
=> x.TensorEngine.Round(x, decimals, outType);
}
}

0 comments on commit a7fdcbc

Please sign in to comment.