public NDArray this[string slice]
        {
            get
            {
                return(this[Slice.ParseSlices(slice)]);
            }

            set
            {
                throw new NotImplementedException("slice data set is not implemented for types less NDArray's.");
            }
        }
示例#2
0
        protected void SetIndices(object[] indicesObjects, NDArray values)
        {
            var indicesLen = indicesObjects.Length;
            if (indicesLen == 1)
            {
                switch (indicesObjects[0])
                {
                    case NDArray nd:
                        SetIndices(this, new NDArray[] {nd}, values);
                        return;
                    case int i:
                        Storage.SetData(values, i);
                        return;
                    case bool boolean:
                        if (boolean == false)
                            return; //do nothing

                        SetData(values);
                        return; // np.expand_dims(this, 0); //equivalent to [np.newaxis]

                    case int[] coords:
                        SetData(values, coords);
                        return;
                    case NDArray[] nds:
                        this[nds] = values;
                        return;
                    case object[] objs:
                        this[objs] = values;
                        return;
                    case string slicesStr:
                        new NDArray(Storage.GetView(Slice.ParseSlices(slicesStr))).SetData(values);
                        return;
                    case null:
                        throw new ArgumentNullException($"The 1th dimension in given indices is null.");
                    //no default
                }
            }

            int ints = 0;
            int bools = 0;
            for (var i = 0; i < indicesObjects.Length; i++)
            {
                switch (indicesObjects[i])
                {
                    case NDArray _:
                    case int[] _:
                        goto _NDArrayFound;
                    case int _:
                        ints++;
                        continue;
                    case bool @bool:
                        bools++;
                        continue;
                    case string _:
                    case Slice _:
                        continue;
                    case null: throw new ArgumentNullException($"The {i}th dimension in given indices is null.");
                    default: throw new ArgumentException($"Unsupported indexing type: '{(indicesObjects[i]?.GetType()?.Name ?? "null")}'");
                }
            }

            //handle all ints
            if (ints == indicesLen)
            {
                Storage.SetData(values, indicesObjects.Cast<int>().ToArray());
                return;
            }

            //handle all booleans
            if (bools == indicesLen)
            {
                this[np.array(indicesObjects.Cast<bool>().ToArray(), false).MakeGeneric<bool>()] = values;
                return;
            }

            Slice[] slices;
            //handle regular slices
            try
            {
                slices = indicesObjects.Select(x =>
                {
                    switch (x)
                    {
                        case Slice o: return o;
                        case int o: return Slice.Index(o);
                        case string o: return new Slice(o);
                        case bool o: return o ? Slice.NewAxis : throw new NumSharpException("false bool detected"); //TODO: verify this
                        case IConvertible o: return Slice.Index((int)o.ToInt32(CultureInfo.InvariantCulture));
                        default: throw new ArgumentException($"Unsupported slice type: '{(x?.GetType()?.Name ?? "null")}'");
                    }
                }).ToArray();
            }
            catch (NumSharpException e) when (e.Message.Contains("false bool detected"))
            {
                //handle rare case of false bool
                return;
            }

            new NDArray(Storage.GetView(slices)).SetData(values);

//handle complex ndarrays indexing
            _NDArrayFound:
            var @this = this;
            var indices = new List<NDArray>();
            bool foundNewAxis = false;
            int countNewAxes = 0;
            //handle ndarray indexing
            bool hasCustomExpandedSlice = false; //use for premature slicing detection
            for (int i = 0; i < indicesLen; i++)
            {
                var idx = indicesObjects[i];
                _recuse:
                switch (idx)
                {
                    case Slice o:

                        if (o.IsEllipsis)
                        {
                            indicesObjects = ExpandEllipsis(indicesObjects, @this.ndim).ToArray();
                            //TODO: i think we need to set here indicesLen = indicesObjects.Length
                            continue;
                        }

                        if (o.IsNewAxis)
                        {
                            //TODO: whats the approach to handling a newaxis in setter, findout.
                            countNewAxes++;
                            foundNewAxis = true;
                            continue;
                        }

                        hasCustomExpandedSlice = true;
                        indices.Add(GetIndicesFromSlice(@this.Shape.dimensions, o, i - countNewAxes));
                        continue;
                    case int o:
                        indices.Add(NDArray.Scalar<int>(o));
                        continue;
                    case string o:
                        indicesObjects[i] = idx = new Slice(o);

                        goto _recuse;
                    case bool o:
                        if (o)
                        {
                            indicesObjects[i] = idx = Slice.NewAxis;
                            goto _recuse;
                        }
                        else
                            return; //false bool causes nullification of return.
                    case IConvertible o:
                        indices.Add(NDArray.Scalar<int>(o.ToInt32(CultureInfo.InvariantCulture)));
                        continue;
                    case int[] o:
                        indices.Add(np.array(o, copy: false)); //we dont copy, pinning will be freed automatically after we done indexing.
                        continue;
                    case NDArray nd:
                        if (nd.typecode == NPTypeCode.Boolean)
                        {
                            //TODO: mask only specific axis??? find a unit test to check it against.
                            throw new Exception("if (nd.typecode == NPTypeCode.Boolean)");
                        }

                        indices.Add(nd);
                        continue;
                    default: throw new ArgumentException($"Unsupported slice type: '{(idx?.GetType()?.Name ?? "null")}'");
                }
            }

            NDArray[] indicesArray = indices.ToArray();

            //handle premature slicing when the shapes cant be broadcasted together
            if (hasCustomExpandedSlice && !np.are_broadcastable(indicesArray))
            {
                var ndim = indicesObjects.Length;
                var prematureSlices = new Slice[ndim];
                var dims = @this.shape;
                for (int i = 0; i < ndim; i++)
                {
                    if (indicesObjects[i] is Slice slice)
                    {
                        prematureSlices[i] = slice;
                        //todo: we might need this in the future indicesObjects[i] = Slice.All;
                    }
                    else
                    {
                        prematureSlices[i] = Slice.All;
                    }
                }

                @this = @this[prematureSlices];

                //updated premature axes
                dims = @this.shape;
                for (int i = 0; i < ndim; i++)
                {
                    if (prematureSlices[i] != Slice.All)
                    {
                        indicesArray[i] = GetIndicesFromSlice(dims, Slice.All, i);
                    }
                }
            }

            //TODO: we can use a slice as null indice instead of expanding it, then we use PrepareIndexGetters to actually simulate that.
            SetIndices(@this, indicesArray, values);

            //TODO: this is valid code for getter, we need to impl a similar technique before passing @this.
            //if (foundNewAxis)
            //{
            //    //TODO: This is not the behavior when setting with new axis, is it even possible?
            //    var targettedAxis = indices.Count - 1;
            //    var axisOffset = this.ndim - targettedAxis;
            //    var retShape = ret.Shape;
            //    for (int i = 0; i < indicesLen; i++)
            //    {
            //        if (!(indicesObjects[i] is Slice slc) || !slc.IsNewAxis)
            //            continue;
            //
            //        var axis = Math.Max(0, Math.Min(i - axisOffset, ret.ndim));
            //        retShape = retShape.ExpandDimension(axis);
            //    }
            //
            //    ret = ret.reshape(retShape);
            //}
            //
            //return ret;
        }
示例#3
0
 public ViewStorage(IStorage dataStorage, string slice_notation) : this(dataStorage, Slice.ParseSlices(slice_notation))
 {
 }