Esempio n. 1
0
        public void Case8()
        {
            var shape = new Shape(100);
            var sh    = new NDCoordinatesIncrementor(ref shape);

            sh.Index.Should().ContainInOrder(0);
            sh.Next().Should().ContainInOrder(1);
            sh.Next().Should().ContainInOrder(2);
        }
Esempio n. 2
0
        public void Case4()
        {
            var shape = new Shape(1, 1, 3, 1);
            var sh    = new NDCoordinatesIncrementor(ref shape);

            sh.Index.Should().ContainInOrder(0, 0, 0, 0);
            sh.Next().Should().ContainInOrder(0, 0, 1, 0);
            sh.Next().Should().ContainInOrder(0, 0, 2, 0);

            sh.Next().Should().BeNull();
        }
Esempio n. 3
0
        /// <summary>
        ///     Compute the truth value of x1 OR x2 element-wise.
        /// </summary>
        /// <param name="lhs">Input boolean array.</param>
        /// <param name="rhs">Input boolean array.</param>
        /// <returns>Returns True if the arrays are equal.</returns>
        /// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.logical_or.html</remarks>
        public static unsafe NDArray <bool> logical_or(NDArray lhs, NDArray rhs)
        {
#if _REGEN1
            if (lhs.typecode != rhs.typecode)
            {
                throw new NotImplementedException("please make sure operands have the same data type");
            }
            else if (lhs.typecode == NPTypeCode.Boolean)
            {
                if (lhs.Shape.IsScalar && rhs.Shape.IsScalar)
                {
                    return(NDArray.Scalar(*(bool *)lhs.Address || *(bool *)rhs.Address).MakeGeneric <bool>());
                }

                var(BroadcastedLeftShape, BroadcastedRightShape) = DefaultEngine.Broadcast(lhs.Shape, rhs.Shape);
                var   lhs_address = (bool *)lhs.Address;
                var   rhs_address = (bool *)rhs.Address;
                var   ret         = new NDArray <bool>(new Shape(BroadcastedLeftShape.dimensions), true);
                Shape retShape    = ret.Shape;

                //iterate
                var   ret_address = (bool *)ret.Address;
                var   incr        = new NDCoordinatesIncrementor(BroadcastedLeftShape.dimensions); //doesn't matter which side it is.
                int[] current     = incr.Index;
                do
                {
                    *(ret_address + retShape.GetOffset(current)) = (*(lhs_address + BroadcastedLeftShape.GetOffset(current))) || *(rhs_address + BroadcastedRightShape.GetOffset(current));
                } while (incr.Next() != null);

                return(ret);
            }
Esempio n. 4
0
        public void Case11_Scalar()
        {
            var sh = new NDCoordinatesIncrementor(new int[0]);

            sh.Index.Should().ContainInOrder(0);
            sh.Next().Should().BeNull();
        }
Esempio n. 5
0
        public void Case10_Scalar_2()
        {
            var shape = Shape.Scalar;
            var sh    = new NDCoordinatesIncrementor(ref shape);

            sh.Index.Should().ContainInOrder(0);
            sh.Next().Should().BeNull();
        }
Esempio n. 6
0
        /// <summary>
        ///     Random values in a given shape.
        ///     Create an array of the given shape and populate it with random samples from a uniform distribution over [0, 1).
        /// </summary>
        public NDArray rand(Shape shape)
        {
            NDArray ret = new NDArray(typeof(double), shape, false);

            unsafe
            {
                var addr = (double *)ret.Address;
                var incr = new NDCoordinatesIncrementor(ref shape);
                do
                {
                    *(addr + shape.GetOffset(incr.Index)) = randomizer.NextDouble();
                } while (incr.Next() != null);
            }

            return(ret);
        }
Esempio n. 7
0
        /// <remarks>https://docs.scipy.org/doc/numpy/reference/generated/numpy.matmul.html</remarks>
        public override NDArray Matmul(NDArray lhs, NDArray rhs)
        {
            if (lhs.Shape.IsScalar || rhs.Shape.IsScalar)
            {
                throw new InvalidOperationException("Matmul can't handle scalar multiplication, use `*` or `np.dot(..)` instead");
            }

            //If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
            if (lhs.ndim == 1 && rhs.ndim == 2)
            {
                throw new NotSupportedException("Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?)");
            }

            if (rhs.ndim == 1)
            {
                rhs = np.expand_dims(rhs, 1);
            }

            if (lhs.ndim == 2 || rhs.ndim == 2)
            {
                return(MultiplyMatrix(lhs, rhs));
            }

            NDArray l = lhs;
            NDArray r = rhs;

            (l, r) = np.broadcast_arrays(l, r);
            var retShape = l.Shape.Clean();

            Console.WriteLine(retShape);
            Debug.Assert(l.shape[0] == r.shape[0]);
            var len       = l.size;
            var ret       = new NDArray(np._FindCommonArrayType(l.typecode, r.typecode), retShape);
            var iterShape = new Shape(retShape.dimensions.Take(retShape.dimensions.Length - 2).ToArray());
            var incr      = new NDCoordinatesIncrementor(ref iterShape);
            var index     = incr.Index;

            //TODO! we need to create IEnumeable<int> on NDCoordinatesIncrementor so we can do something like this:
            //TODO! Parallel.ForEach(incr, i => MultiplyMatrix(l[index], r[index], ret[index]));
            for (int i = 0; i < len; i++, incr.Next())
            {
                MultiplyMatrix(l[index], r[index], ret[index]);
            }

            return(ret);
        }
Esempio n. 8
0
        public Array ToMuliDimArray <T>() where T : unmanaged
        {
            var ret = Arrays.Create(typeof(T), shape);

            var iter      = this.AsIterator <T>();
            var hasNext   = iter.HasNext;
            var next      = iter.MoveNext;
            var coorditer = new NDCoordinatesIncrementor(shape);
            var indices   = coorditer.Index;

            while (hasNext())
            {
                ret.SetValue(next(), indices);
                if (coorditer.Next() == null)
                {
                    break;
                }
            }

            return(ret);
        }
Esempio n. 9
0
        /// <summary>
        /// Test whether all array elements evaluate to True.
        /// </summary>
        /// <param name="nd"></param>
        /// <returns></returns>
        public override bool All(NDArray nd)
        {
            if (nd.GetTypeCode != NPTypeCode.Boolean)
            {
                throw new NotSupportedException("DefaultEngine.All supports only boolean dtype."); //TODO!
            }
            unsafe
            {
                var addr  = (bool *)nd.Address;
                var shape = nd.Shape;
                var incr  = new NDCoordinatesIncrementor(shape.dimensions);
                do
                {
                    if (!(*(addr + shape.GetOffset(incr.Index))))
                    {
                        return(false);
                    }
                } while (incr.Next() != null);

                return(true);
            }
        }
        protected void autoresetDefault_Single()
        {
            if (typeof(TOut) == typeof(Single))
            {
                autoresetDefault_NoCast();
                return;
            }

            var   localBlock = Block;
            Shape shape      = Shape;
            var   convert    = Converts.FindConverter <Single, TOut>();

            if (!Shape.IsContiguous || Shape.ModifiedStrides)
            {
                //Shape is sliced, auto-resetting
                switch (Type)
                {
                case IteratorType.Scalar:
                {
                    var offset = shape.TransformOffset(0);
                    if (offset != 0)
                    {
                        MoveNext          = () => convert(*((Single *)localBlock.Address + offset));
                        MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");
                    }
                    else
                    {
                        MoveNext          = () => convert(*((Single *)localBlock.Address));
                        MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");
                    }

                    Reset   = () => { };
                    HasNext = () => true;
                    break;
                }

                case IteratorType.Vector:
                {
                    var size = Shape.size;
                    MoveNext = () =>
                    {
                        var ret = convert(*((Single *)localBlock.Address + shape.GetOffset(index++)));
                        if (index >= size)
                        {
                            index = 0;
                        }
                        return(ret);
                    };
                    MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");

                    Reset   = () => index = 0;
                    HasNext = () => true;
                    break;
                }

                case IteratorType.Matrix:
                case IteratorType.Tensor:
                {
                    var iterator = new NDCoordinatesIncrementor(ref shape, incr => incr.Reset());
                    var index    = iterator.Index;
                    Func <int[], int> getOffset = shape.GetOffset;
                    MoveNext = () =>
                    {
                        var ret = convert(*((Single *)localBlock.Address + getOffset(index)));
                        iterator.Next();
                        return(ret);
                    };
                    MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");
                    Reset             = () => iterator.Reset();
                    HasNext           = () => true;
                    break;
                }

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            else
            {
                //Shape is not sliced, auto-resetting
                switch (Type)
                {
                case IteratorType.Scalar:
                    MoveNext          = () => convert(*(Single *)localBlock.Address);
                    MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");
                    Reset             = () => { };
                    HasNext           = () => true;
                    break;

                case IteratorType.Vector:
                    var size = Shape.size;
                    MoveNext = () =>
                    {
                        var ret = convert(*((Single *)localBlock.Address + index++));
                        if (index >= size)
                        {
                            index = 0;
                        }
                        return(ret);
                    };
                    MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");
                    Reset             = () => index = 0;
                    HasNext           = () => true;
                    break;

                case IteratorType.Matrix:
                case IteratorType.Tensor:
                    var iterator = new NDOffsetIncrementorAutoresetting(Shape);     //we do not copy the dimensions because there is not risk for the iterator's shape to change.
                    MoveNext          = () => convert(*((Single *)localBlock.Address + iterator.Next()));
                    MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");
                    HasNext           = () => true;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
Esempio n. 11
0
        protected void setDefaults_UInt32() //UInt32 is the input type
        {
            if (AutoReset)
            {
                autoresetDefault_UInt32();
                return;
            }

            if (typeof(TOut) == typeof(UInt32))
            {
                setDefaults_NoCast();
                return;
            }

            var convert = Converts.FindConverter <UInt32, TOut>();

            //non auto-resetting.
            var   localBlock = Block;
            Shape shape      = Shape;

            if (Shape.IsSliced || Shape.IsBroadcasted)
            {
                //Shape is sliced, not auto-resetting
                switch (Type)
                {
                case IteratorType.Scalar:
                {
                    var hasNext = new Reference <bool>(true);
                    var offset  = shape.TransformOffset(0);

                    if (offset != 0)
                    {
                        MoveNext = () =>
                        {
                            hasNext.Value = false;
                            return(convert(*((UInt32 *)localBlock.Address + offset)));
                        };
                        MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");
                    }
                    else
                    {
                        MoveNext = () =>
                        {
                            hasNext.Value = false;
                            return(convert(*((UInt32 *)localBlock.Address)));
                        };
                        MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");
                    }

                    Reset   = () => hasNext.Value = true;
                    HasNext = () => hasNext.Value;
                    break;
                }

                case IteratorType.Vector:
                {
                    MoveNext          = () => convert(*((UInt32 *)localBlock.Address + shape.GetOffset(index++)));
                    MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");
                    Reset             = () => index = 0;
                    HasNext           = () => index < Shape.size;
                    break;
                }

                case IteratorType.Matrix:
                case IteratorType.Tensor:
                {
                    var hasNext  = new Reference <bool>(true);
                    var iterator = new NDCoordinatesIncrementor(ref shape, _ => hasNext.Value = false);
                    Func <int[], int> getOffset = shape.GetOffset;
                    var index = iterator.Index;

                    MoveNext = () =>
                    {
                        var ret = convert(*((UInt32 *)localBlock.Address + getOffset(index)));
                        iterator.Next();
                        return(ret);
                    };
                    MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");

                    Reset = () =>
                    {
                        iterator.Reset();
                        hasNext.Value = true;
                    };

                    HasNext = () => hasNext.Value;
                    break;
                }

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            else
            {
                //Shape is not sliced, not auto-resetting
                switch (Type)
                {
                case IteratorType.Scalar:
                    var hasNext = new Reference <bool>(true);
                    MoveNext = () =>
                    {
                        hasNext.Value = false;
                        return(convert(*((UInt32 *)localBlock.Address)));
                    };
                    MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");
                    Reset             = () => hasNext.Value = true;
                    HasNext           = () => hasNext.Value;
                    break;

                case IteratorType.Vector:
                    MoveNext          = () => convert(*((UInt32 *)localBlock.Address + index++));
                    MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");
                    Reset             = () => index = 0;
                    HasNext           = () => index < Shape.size;
                    break;

                case IteratorType.Matrix:
                case IteratorType.Tensor:
                    var iterator = new NDOffsetIncrementor(Shape);     //we do not copy the dimensions because there is not risk for the iterator's shape to change.
                    MoveNext          = () => convert(*((UInt32 *)localBlock.Address + iterator.Next()));
                    MoveNextReference = () => throw new NotSupportedException("Unable to return references during iteration when casting is involved.");
                    Reset             = () => iterator.Reset();
                    HasNext           = () => iterator.HasNext;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
        public override NDArray ReduceProduct(NDArray arr, int? axis_, bool keepdims = false, NPTypeCode? typeCode = null)
        {
            //in order to iterate an axis:
            //consider arange shaped (1,2,3,4) when we want to summarize axis 1 (2nd dimension which its value is 2)
            //the size of the array is [1, 2, n, m] all shapes after 2nd multiplied gives size
            //the size of what we need to reduce is the size of the shape of the given axis (shape[axis])
            var shape = arr.Shape;
            if (shape.IsEmpty || shape.size==0)
                return NDArray.Scalar(1, (typeCode ?? arr.typecode));

            if (shape.IsScalar || (shape.size == 1 && shape.NDim == 1))
            {
                var r = NDArray.Scalar(typeCode.HasValue ? Converts.ChangeType(arr.GetAtIndex(0), typeCode.Value) : arr.GetAtIndex(0));
                if (keepdims)
                    r.Storage.ExpandDimension(0);
                
                return r;
            }

            if (axis_ == null)
            {
                var r = NDArray.Scalar(product_elementwise(arr, typeCode));
                if (keepdims)
                    r.Storage.ExpandDimension(0);
                else if (!r.Shape.IsScalar && r.Shape.size == 1 && r.ndim == 1)
                    r.Storage.Reshape(Shape.Scalar);
                return r;
            }

            var axis = axis_.Value;
            while (axis < 0)
                axis = arr.ndim + axis; //handle negative axis

            if (axis >= arr.ndim)
                throw new ArgumentOutOfRangeException(nameof(axis));

            if (shape[axis] == 1)
            {
                //if the given div axis is 1 and can be squeezed out.
                if (keepdims)
                    return new NDArray(arr.Storage.Alias());
                return np.squeeze_fast(arr, axis);
            }

            //handle keepdims
            Shape axisedShape = Shape.GetAxis(shape, axis);
            var retType = typeCode ?? (arr.GetTypeCode.GetAccumulatingType());

            //prepare ret
            var ret = new NDArray(retType, axisedShape, false);
            var iterAxis = new NDCoordinatesAxisIncrementor(ref shape, axis);
            var iterRet = new NDCoordinatesIncrementor(ref axisedShape);
            var iterIndex = iterRet.Index;
            var slices = iterAxis.Slices;

            //resolve the accumulator type

#if _REGEN1
            #region Compute
            switch (arr.GetTypeCode)
		    {
			    %foreach supported_numericals,supported_numericals_lowercase%
			    case NPTypeCode.#1: 
                {
                    switch (retType)
		            {
			            %foreach supported_numericals,supported_numericals_lowercase,supported_numericals_onevales%
			            case NPTypeCode.#101: 
                        {
                            do
                            {
                                var slice = arr[slices];
                                var iter = slice.AsIterator<#2>();
                                var moveNext = iter.MoveNext;
                                var hasNext = iter.HasNext;
                                |#102 sum = #103;
                                while (hasNext())
                                    sum *= (#102) moveNext();

                                ret.Set#101(Converts.To#101(sum), iterIndex);
                            } while (iterAxis.Next() != null && iterRet.Next() != null);
                            break;
                        }