public IStorage GetStorage(NPTypeCode typeCode) { return(new TypedArrayStorage(typeCode) { Engine = this }); }
public override UnmanagedStorage GetStorage(NPTypeCode typeCode) { return(new UnmanagedStorage(typeCode) { Engine = this }); }
public NDArray Cast(NDArray nd, NPTypeCode dtype, bool copy) { if (dtype == NPTypeCode.Empty) { throw new ArgumentNullException(nameof(dtype)); } NDArray clone() { var copied = new NDArray(nd.dtype, nd.TensorEngine); copied.Storage.Allocate(ArrayConvert.To(nd.Array, dtype), nd.shape); return(copied); } if (nd.GetTypeCode == dtype) { //casting not needed return(copy ? clone() : nd); } else { //casting needed if (copy) { return(clone()); } //just re-set the data, conversion is handled inside. nd.Storage.ReplaceData(nd.Storage.GetData(), dtype); return(nd); } }
public static Object ChangeType(Object value, NPTypeCode typeCode) { if (value == null && (typeCode == NPTypeCode.Empty || typeCode == NPTypeCode.String)) return null; // This line is invalid for things like Enums that return a NPTypeCode // of Int32, but the object can't actually be cast to an Int32. // if (v.GetNPTypeCode() == NPTypeCode) return value; switch (typeCode) { case NPTypeCode.Boolean: return ((IConvertible)value).ToBoolean(CultureInfo.InvariantCulture); case NPTypeCode.Byte: return ((IConvertible)value).ToByte(CultureInfo.InvariantCulture); case NPTypeCode.Int32: return ((IConvertible)value).ToInt32(CultureInfo.InvariantCulture); case NPTypeCode.Int64: return ((IConvertible)value).ToInt64(CultureInfo.InvariantCulture); case NPTypeCode.Single: return ((IConvertible)value).ToSingle(CultureInfo.InvariantCulture); case NPTypeCode.Double: return ((IConvertible)value).ToDouble(CultureInfo.InvariantCulture); case NPTypeCode.String: return ((IConvertible)value).ToString(CultureInfo.InvariantCulture); case NPTypeCode.Empty: throw new InvalidCastException("InvalidCast_Empty"); default: throw new ArgumentException("Arg_UnknownNPTypeCode"); } }
/// <summary> /// Return a new array of given shape and type, filled with ones. /// </summary> /// <param name="shape">Shape of the new array.</param> /// <param name="typeCode">The desired data-type for the array, e.g., <see cref="uint8"/>. Default is <see cref="float64"/> / <see cref="double"/>.</param> /// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.ones.html</remarks> public static NDArray ones(Shape shape, NPTypeCode typeCode) { object one = null; switch (typeCode) { case NPTypeCode.Complex: one = new Complex(1d, 0d); break; case NPTypeCode.NDArray: one = NDArray.Scalar(1, np.int32); break; case NPTypeCode.String: one = "1"; break; case NPTypeCode.Char: one = '1'; break; default: one = Converts.ChangeType((byte)1, typeCode); break; } return(new NDArray(ArraySlice.Allocate(typeCode, shape.size, one), shape)); }
public static Type AsType(this NPTypeCode typeCode) { switch (typeCode) { #if _REGEN %foreach all_dtypes,all_dtypes_lowercase% case NPTypeCode.#1: return typeof(#2); %
public static IMemoryBlock CastTo(this IMemoryBlock source, NPTypeCode to) { switch (to) { #if _REGEN1 %foreach supported_dtypes,supported_dtypes_lowercase% case NPTypeCode.#1: return CastTo<#2>(source); %
public override NDArray Cast(NDArray nd, NPTypeCode dtype, bool copy) { if (dtype == NPTypeCode.Empty) { throw new ArgumentNullException(nameof(dtype)); } NDArray clone() => new NDArray(nd.Storage.Clone()); if (nd.Shape.IsEmpty) { if (copy) { return(new NDArray(dtype)); } nd.Storage = new UnmanagedStorage(dtype); return(nd); } if (nd.Shape.IsScalar || (nd.Shape.size == 1 && nd.Shape.NDim == 1)) { var ret = NDArray.Scalar(nd.GetAtIndex(0), dtype); if (copy) { return(ret); } nd.Storage = ret.Storage; return(nd); } if (nd.GetTypeCode == dtype) { //casting not needed return(copy ? clone() : nd); } else { //casting needed if (copy) { if (nd.Shape.IsSliced) { nd = clone(); } return(new NDArray(new UnmanagedStorage(ArraySlice.FromMemoryBlock(nd.Array.CastTo(dtype), false), nd.Shape))); } else { var storage = nd.Shape.IsSliced ? nd.Storage.Clone() : nd.Storage; nd.Storage = new UnmanagedStorage(ArraySlice.FromMemoryBlock(storage.InternalArray.CastTo(dtype), false), storage.Shape); return(nd); } } }
/// <summary> /// Return a new double array of given shape, filled with zeros. /// </summary> /// <param name="shape">Shape of the new array,</param> /// <param name="typeCode">The desired data-type for the array, e.g., <see cref="uint8"/>. Default is <see cref="float64"/> / <see cref="double"/>.</param> /// <returns>Array of zeros with the given shape, dtype.</returns> /// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.zeros.html</remarks> public static NDArray zeros(Shape shape, NPTypeCode typeCode) { if (typeCode == NPTypeCode.Empty) { throw new ArgumentNullException(nameof(typeCode)); } return(new NDArray(typeCode, shape, true)); //already allocates inside. }
/// <summary> /// Creates a scalar <see cref="NDArray"/> of <see cref="value"/> and <see cref="dtype"/>. /// </summary> /// <param name="value">The value of the scalar</param> /// <param name="typeCode">The type code of the scalar.</param> /// <returns></returns> /// <remarks>In case when <see cref="value"/> is not <see cref="dtype"/>, <see cref="Convert.ChangeType(object,System.Type)"/> will be called.</remarks> public static NDArray Scalar(object value, NPTypeCode typeCode) { var type = typeCode.AsType(); var ndArray = new NDArray(type, new int[0]); ndArray.Storage.ReplaceData(Arrays.Wrap(typeCode, Convert.ChangeType(value, type))); //todo! create a NPConvert to support NPTypeCode return(ndArray); }
/// <summary> /// Return a new array of given shape and type, without initializing entries. /// </summary> /// <param name="shape">Shape of the empty array, e.g., (2, 3) or 2.</param> /// <param name="typeCode">Desired output data-type for the array, e.g, numpy.int8. Default is numpy.float64.</param> /// <returns>Array of uninitialized (arbitrary) data of the given shape, dtype, and order. Object arrays will be initialized to None.</returns> /// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.empty.html</remarks> public static NDArray empty(Shape shape, NPTypeCode typeCode) { if (typeCode == NPTypeCode.Empty) { throw new ArgumentNullException(nameof(typeCode)); } return(new NDArray(typeCode, shape, false)); }
/// <summary> /// Return a new array of given shape and type, filled with fill_value. /// </summary> /// <param name="fill_value">Fill value.</param> /// <param name="shape">Shape of the empty array, e.g., (2, 3) or 2.</param> /// <param name="typeCode">The desired data-type for the array The default, null, means np.array(fill_value).dtype.</param> /// <returns>Array of fill_value with the given shape, dtype, and order.</returns> /// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.full.html</remarks> public static NDArray full(ValueType fill_value, Shape shape, NPTypeCode typeCode) { if (typeCode == NPTypeCode.Empty) { throw new ArgumentNullException(nameof(typeCode)); } return(new NDArray(new UnmanagedStorage(ArraySlice.Allocate(typeCode, shape.size, Convert.ChangeType(fill_value, (TypeCode)typeCode)), shape))); }
/// <summary> /// Convert <see cref="NPTypeCode"/> into its <see cref="Type"/> /// </summary> /// <param name="typeCode"></param> /// <returns></returns> public static Type AsType(this NPTypeCode typeCode) { switch (typeCode) { case NPTypeCode.Empty: return(null); case NPTypeCode.Boolean: return(typeof(Boolean)); case NPTypeCode.Char: return(typeof(Char)); case NPTypeCode.Byte: return(typeof(Byte)); case NPTypeCode.Int16: return(typeof(Int16)); case NPTypeCode.UInt16: return(typeof(UInt16)); case NPTypeCode.Int32: return(typeof(Int32)); case NPTypeCode.UInt32: return(typeof(UInt32)); case NPTypeCode.Int64: return(typeof(Int64)); case NPTypeCode.UInt64: return(typeof(UInt64)); case NPTypeCode.Single: return(typeof(Single)); case NPTypeCode.Double: return(typeof(Double)); case NPTypeCode.Decimal: return(typeof(Decimal)); case NPTypeCode.String: return(typeof(String)); case NPTypeCode.NDArray: return(typeof(NDArray)); case NPTypeCode.Complex: return(typeof(Complex)); default: throw new ArgumentOutOfRangeException(nameof(typeCode), typeCode, null); } }
/// <summary> /// Creates an array of 1D of type <paramref name="typeCode"/>. /// </summary> /// <param name="typeCode">The type to create this array.</param> /// <param name="length">The length of the array</param> /// <remarks>Do not use this if you are trying to create jagged or multidimensional array.</remarks> public static Array Create(NPTypeCode typeCode, int length) { switch (typeCode) { #if _REGEN % foreach supported_dtypes, supported_dtypes_lowercase % case NPTypeCode.#1: { return(new #2[length]); }
/// <summary> /// Return a casted <see cref="UnmanagedStorage"/> to a specific dtype only if necessary /// </summary> /// <param name="typeCode">The dtype to convert to</param> /// <returns>A copy of this <see cref="UnmanagedStorage"/> casted to a specific dtype.</returns> /// <remarks>Copies only if dtypes does not match <paramref name="typeCode"/></remarks> public UnmanagedStorage CastIfNecessary(NPTypeCode typeCode) { if (_shape.IsEmpty || _typecode == typeCode) { return(this); } //this also handles slices return(new UnmanagedStorage((IArraySlice)InternalArray.CastTo(typeCode), _shape.Clone(true, true, true))); }
/// <summary> /// Translates the <see cref="NPTypeCode"/> type code in to the actual reflecton type. /// </summary> /// <param name="code">The type code to translate into the type.</param> /// <returns>The <see cref="NDArray"/> element <see cref="Type"/>translated.</returns> public static Type Translate(NPTypeCode code) { if (s_types.TryGetValue(code, out var type)) { return(type); } else { throw new ArgumentException($"The operation index does not support requested type code: {code}."); } }
/// <summary> /// Return a casted <see cref="UnmanagedStorage"/> to a specific dtype. /// </summary> /// <param name="typeCode">The dtype to convert to</param> /// <returns>A copy of this <see cref="UnmanagedStorage"/> casted to a specific dtype.</returns> /// <remarks>Always copies, If dtype==typeof(T) then a <see cref="Clone"/> is returned.</remarks> public UnmanagedStorage Cast(NPTypeCode typeCode) { if (Shape.IsEmpty) { return(new UnmanagedStorage(typeCode)); } if (_typecode == typeCode) { return(Clone()); } //this also handles slices return(new UnmanagedStorage((IArraySlice)InternalArray.CastTo(typeCode), Shape.Clone(true, true))); }
/// <summary> /// Get the min value of given <see cref="NPTypeCode"/>. /// </summary> public static object MaxValue(this NPTypeCode typeCode) { switch (typeCode) { case NPTypeCode.Complex: return(new Complex(double.MaxValue, double.MaxValue)); case NPTypeCode.Boolean: return(true); #if _REGEN % foreach except(supported_primitives, "Boolean", "String") % case NPTypeCode.#1: return(#1.MaxValue); % #else case NPTypeCode.Byte: return(Byte.MaxValue);
/// <summary> /// Return evenly spaced numbers over a specified interval.<br></br> /// Returns num evenly spaced samples, calculated over the interval[start, stop].<br></br> /// The endpoint of the interval can optionally be excluded. /// </summary> /// <param name="start">The starting value of the sequence.</param> /// <param name="stop">The end value of the sequence, unless endpoint is set to False. In that case, the sequence consists of all but the last of num + 1 evenly spaced samples, so that stop is excluded. Note that the step size changes when endpoint is False.</param> /// <param name="num">Number of samples to generate. Default is 50. Must be non-negative.</param> /// <param name="endpoint">If True, stop is the last sample. Otherwise, it is not included. Default is True.</param> /// <param name="typeCode">The type of the output array. If dtype is not given, infer the data type from the other input arguments.</param> /// <remarks>https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.linspace.html</remarks> public static NDArray linspace(double start, double stop, int num, bool endpoint = true, NPTypeCode typeCode = NPTypeCode.Double) { if (typeCode == NPTypeCode.Empty) { throw new ArgumentException("Invalid typeCode", nameof(typeCode)); } NDArray ret = new NDArray(typeCode, new Shape(num), false); double step = (stop - start) / (endpoint ? num - 1.0 : num); switch (ret.GetTypeCode) { #if _REGEN case NPTypeCode.Boolean: { unsafe { var addr = (bool *)ret.Address; for (int i = 0; i < num; i++) { *(addr + i) = (start + i * step) != 0; } } return(ret); } % foreach except(supported_dtypes, "Boolean"), except(supported_dtypes_lowercase, "bool") % case NPTypeCode.#1: { unsafe { var addr = (#2 *)ret.Address; for (int i = 0; i < num; i++) { *(addr + i) = Convert.To #1 (start + i * step); } } return(ret); }
/// <summary> /// Get storage for given <paramref name="typeCode"/>. /// </summary> public abstract UnmanagedStorage GetStorage(NPTypeCode typeCode);
public static bool IsNumerical(this NPTypeCode typeCode) { var val = (int)typeCode; return val >= 3 && val <= 15 || val == 129; }
/// <summary> /// Constructor for init data type /// internal storage is 1D with 1 element /// </summary> /// <param name="typeCode">Data type of elements</param> /// <param name="engine">The engine of this <see cref="NDArray"/></param> /// <remarks>This constructor does not call allocation/></remarks> protected internal NDArray(NPTypeCode typeCode, TensorEngine engine) { tensorEngine = engine; Storage = TensorEngine.GetStorage(typeCode); }
/// <summary> /// Constructor which initialize elements with 0 /// type and shape are given. /// </summary> /// <param name="dtype">internal data type</param> /// <param name="shape">Shape of NDArray</param> /// <param name="fillZeros">Should set the values of the new allocation to default(dtype)? otherwise - old memory noise</param> /// <remarks>This constructor calls <see cref="IStorage.Allocate(NumSharp.Shape,System.Type)"/></remarks> public NDArray(NPTypeCode dtype, Shape shape, bool fillZeros) : this(dtype) { Storage.Allocate(shape, dtype, fillZeros); }
/// <summary> /// Constructor which initialize elements with length of <paramref name="size"/> /// </summary> /// <param name="dtype">Internal data type</param> /// <param name="size">The size as a single dimension shape</param> /// <param name="fillZeros">Should set the values of the new allocation to default(dtype)? otherwise - old memory noise</param> /// <remarks>This constructor calls <see cref="IStorage.Allocate(NumSharp.Shape,System.Type)"/></remarks> public NDArray(NPTypeCode dtype, int size, bool fillZeros) : this(dtype, Shape.Vector(size), true) { }
/// <summary> /// Constructor which initialize elements with length of <paramref name="size"/> /// </summary> /// <param name="dtype">Internal data type</param> /// <param name="size">The size as a single dimension shape</param> /// <remarks>This constructor calls <see cref="IStorage.Allocate(NumSharp.Shape,System.Type)"/></remarks> public NDArray(NPTypeCode dtype, int size) : this(dtype, Shape.Vector(size), true) { }
/// <summary> /// Constructor which initialize elements with 0 /// type and shape are given. /// </summary> /// <param name="dtype">internal data type</param> /// <param name="shape">Shape of NDArray</param> /// <remarks>This constructor calls <see cref="IStorage.Allocate(NumSharp.Shape,System.Type)"/></remarks> public NDArray(NPTypeCode dtype, Shape shape) : this(dtype, shape, true) { }
/// <summary> /// Join a sequence of arrays along an existing axis. /// </summary> /// <param name="axis">The axis along which the arrays will be joined. If axis is None, arrays are flattened before use. Default is 0.</param> /// <param name="arrays">The arrays must have the same shape, except in the dimension corresponding to axis (the first, by default).</param> /// <returns>The concatenated array.</returns> /// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.concatenate.html</remarks> public static NDArray concatenate(NDArray[] arrays, int axis = 0) { //What we do is we have the axis which is the only dimension that is allowed to be different //We need to perform a check if the dimensions actually match. //After we have the axis ax=1 where shape is (3,ax,3) - ax is the only dimension that can vary. //So if we got input of (3,5,3) and (3,1,3), we create a return shape of (3,6,3). //We perform the assignment by iterating a slice: (:,n,:) on src and dst where dst while n of dst grows as we iterate all arrays. if (arrays == null) { throw new ArgumentNullException(nameof(arrays)); } if (arrays.Length == 0) { throw new ArgumentException("Value cannot be an empty collection.", nameof(arrays)); } if (arrays.Length == 1) { return(arrays[0]); } var first = arrays[0]; var firstShape = (int[])first.shape.Clone(); while (axis < 0) { axis = first.ndim + axis; //translate negative axis } int i, j; int axisSize = 0; //accumulated shape[axis] size for return shape. NPTypeCode retType = first.GetTypeCode; foreach (var src in arrays) { //accumulate the concatenated axis var shape = src.shape; axisSize += shape[axis]; if (ReferenceEquals(src, first)) { continue; } var srcType = src.GetTypeCode; //resolve what the return type should be and should we perform casting. if (first.GetTypeCode != srcType) { if (srcType.CompareTo(retType) == 1) { retType = srcType; } } if (shape.Length != first.ndim) { throw new IncorrectShapeException("all the input arrays must have same number of dimensions."); } //verify the shapes are equal for (j = 0; j < shape.Length; j++) { if (axis == j) { continue; } if (shape[j] != firstShape[j]) { throw new IncorrectShapeException("all the input array dimensions except for the concatenation axis must match exactly."); } } } //prepare return shape firstShape[axis] = axisSize; var retShape = new Shape(firstShape); var dst = new NDArray(retType, retShape); var accessorDst = new Slice[retShape.NDim]; var accessorSrc = new Slice[retShape.NDim]; for (i = 0; i < accessorDst.Length; i++) { accessorSrc[i] = accessorDst[i] = Slice.All; } accessorSrc[axis] = Slice.Index(0); accessorDst[axis] = Slice.Index(0); foreach (var src in arrays) { var len = src.shape[axis]; for (i = 0; i < len; i++) { var writeTo = dst[accessorDst]; var writeFrom = src[accessorSrc]; MultiIterator.Assign(writeTo.Storage, writeFrom.Storage); accessorSrc[axis]++; accessorDst[axis]++; //increment every step } accessorSrc[axis] = Slice.Index(0); //reset src } return(dst); }
/// <summary> /// Return a new array of given shape and type, filled with fill_value. /// </summary> /// <param name="fill_value">Fill value.</param> /// <param name="shape">Shape of the empty array, e.g., (2, 3) or 2.</param> /// <param name="typeCode">The desired data-type for the array The default, null, means np.array(fill_value).dtype.</param> /// <returns>Array of fill_value with the given shape, dtype, and order.</returns> /// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.full.html</remarks> public static NDArray full(Shape shape, ValueType fill_value, NPTypeCode typeCode) { return(full(fill_value, shape, typeCode)); }
static InfoOf() { NPTypeCode = typeof(T).GetTypeCode(); Zero = default; try { MaxValue = (T)NPTypeCode.MaxValue(); MinValue = (T)NPTypeCode.MinValue(); } catch (ArgumentOutOfRangeException) { } switch (NPTypeCode) { case NPTypeCode.NDArray: Size = IntPtr.Size; break; case NPTypeCode.Boolean: Size = 1; break; case NPTypeCode.Char: Size = 2; break; case NPTypeCode.Byte: Size = 1; break; case NPTypeCode.Int16: Size = 2; break; case NPTypeCode.UInt16: Size = 2; break; case NPTypeCode.Int32: Size = 4; break; case NPTypeCode.UInt32: Size = 4; break; case NPTypeCode.Int64: Size = 8; break; case NPTypeCode.UInt64: Size = 8; break; case NPTypeCode.Single: Size = 4; break; case NPTypeCode.Double: Size = 8; break; case NPTypeCode.Decimal: Size = 16; break; case NPTypeCode.String: break; case NPTypeCode.Complex: default: Size = Marshal.SizeOf <T>(); break; } }
/// <summary> /// Constructor for init data type /// internal storage is 1D with 1 element /// </summary> /// <param name="typeCode">Data type of elements</param> /// <remarks>This constructor does not call allocation/></remarks> public NDArray(NPTypeCode typeCode) : this(typeCode, BackendFactory.GetEngine()) { }