예제 #1
0
        public ViewStorage(IStorage dataStorage, params Slice[] slices)
        {
            if (dataStorage == null)
            {
                throw new ArgumentException("dataStorage must not be null");
            }
            if (slices == null)
            {
                throw new ArgumentException("slices must not be null");
            }
            if (slices.Length == 0)
            {
                // if now slices are given the view returns all of all dimensions
                slices = new Slice[dataStorage.Shape.NDim];
                for (int dim = 0; dim < dataStorage.Shape.NDim; dim++)
                {
                    slices[dim] = Slice.All();
                }
            }

            _data   = (IStorage)dataStorage; //all types must inheriet IInternalStorage
            _slices = slices;
            Engine  = dataStorage.Engine;
            EnsureValidSlicingDefinitions();
        }
예제 #2
0
        private void EnsureValidSlicingDefinitions()
        {
            // we need to be working with the original shape here because Slicing changes the own shape!
            var shape = _data.Shape;
            // we need at least one slice per dimension in order to correctly handle multi-dimensional arrays, if not given, extend by Slice.All() which returns the whole dimension
            var temp_slices = _slices;

            if (_slices == null)
            {
                temp_slices = new Slice[0];
            }
            _slices = new Slice[shape.NDim];
            for (int dim = 0; dim < shape.NDim; dim++)
            {
                if (temp_slices.Length > dim)
                {
                    _slices[dim] = temp_slices[dim] ?? Slice.All(); // <-- allow to pass null for Slice.All()
                }
                else
                {
                    _slices[dim] = Slice.All();
                }
            }
            for (int dim = 0; dim < shape.NDim; dim++)
            {
                var slice = _slices[dim];
                var size  = shape.Dimensions[dim];
                if (slice.IsIndex)
                {
                    // special case: reduce this dimension
                    if (slice.Start < 0 || slice.Start >= size)
                    {
                        throw new IndexOutOfRangeException($"Index {slice.Start} is out of bounds for axis {dim} with size {size}");
                    }
                }
                slice.Start = Math.Max(0, slice.Start ?? 0);
                slice.Stop  = Math.Min(size, slice.Stop ?? size);
            }
            // internal shape contains axis with only 1 element that will be reduced in public shape.
            internal_shape = _data.Shape.Slice(_slices, reduce: false);
            Shape          = _data.Shape.Slice(_slices, reduce: true);
        }