1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
// Copyright 2014-2016 bluss and ndarray developers. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. use imp_prelude::*; use dimension::{self, stride_offset}; use error::ShapeError; /// # Methods for Array Views /// /// Methods for read-only array views `ArrayView<'a, A, D>` /// /// Note that array views implement traits like [`From`][f] and `IntoIterator` too. /// [f]: #method.from impl<'a, A, D> ArrayBase<ViewRepr<&'a A>, D> where D: Dimension, { /// Create a read-only array view borrowing its data from a slice. /// /// Checks whether `dim` and `strides` are compatible with the slice's /// length, returning an `Err` if not compatible. /// /// ``` /// use ndarray::ArrayView; /// use ndarray::arr3; /// /// let s = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; /// let a = ArrayView::from_slice_dim_stride((2, 3, 2), /// (1, 4, 2), /// &s).unwrap(); /// /// assert!( /// a == arr3(&[[[0, 2], /// [4, 6], /// [8, 10]], /// [[1, 3], /// [5, 7], /// [9, 11]]]) /// ); /// assert!(a.strides() == &[1, 4, 2]); /// ``` pub fn from_slice_dim_stride(dim: D, strides: D, xs: &'a [A]) -> Result<Self, ShapeError> { dimension::can_index_slice(xs, &dim, &strides).map(|_| { unsafe { Self::new_(xs.as_ptr(), dim, strides) } }) } /// Split the array along `axis` and return one view strictly before the /// split and one view after the split. /// /// **Panics** if `axis` or `index` is out of bounds. /// /// Below, an illustration of `.split_at(Axis(2), 2)` on /// an array with shape 3 × 5 × 5. /// /// <img src="split_at.svg" width="300px" height="271px"> pub fn split_at(self, axis: Axis, index: Ix) -> (Self, Self) { // NOTE: Keep this in sync with the ArrayViewMut version assert!(index <= self.shape().axis(axis)); let left_ptr = self.ptr; let right_ptr = if index == self.shape().axis(axis) { self.ptr } else { let offset = stride_offset(index, self.strides.axis(axis)); unsafe { self.ptr.offset(offset) } }; let mut dim_left = self.dim.clone(); dim_left.set_axis(axis, index); let left = unsafe { Self::new_(left_ptr, dim_left, self.strides.clone()) }; let mut dim_right = self.dim; let right_len = dim_right.axis(axis) - index; dim_right.set_axis(axis, right_len); let right = unsafe { Self::new_(right_ptr, dim_right, self.strides) }; (left, right) } } /// Methods for read-write array views `ArrayViewMut<'a, A, D>` /// /// Note that array views implement traits like [`From`][f] and `IntoIterator` too. /// /// [f]: #method.from impl<'a, A, D> ArrayBase<ViewRepr<&'a mut A>, D> where D: Dimension, { /// Create a read-write array view borrowing its data from a slice. /// /// Checks whether `dim` and `strides` are compatible with the slice's /// length, returning an `Err` if not compatible. /// /// ``` /// use ndarray::ArrayViewMut; /// use ndarray::arr3; /// /// let mut s = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; /// let mut a = ArrayViewMut::from_slice_dim_stride((2, 3, 2), /// (1, 4, 2), /// &mut s).unwrap(); /// /// a[[0, 0, 0]] = 1; /// assert!( /// a == arr3(&[[[1, 2], /// [4, 6], /// [8, 10]], /// [[1, 3], /// [5, 7], /// [9, 11]]]) /// ); /// assert!(a.strides() == &[1, 4, 2]); /// ``` pub fn from_slice_dim_stride(dim: D, strides: D, xs: &'a mut [A]) -> Result<Self, ShapeError> { dimension::can_index_slice(xs, &dim, &strides).map(|_| { unsafe { Self::new_(xs.as_mut_ptr(), dim, strides) } }) } /// Split the array along `axis` and return one mutable view strictly /// before the split and one mutable view after the split. /// /// **Panics** if `axis` or `index` is out of bounds. pub fn split_at(self, axis: Axis, index: Ix) -> (Self, Self) { // NOTE: Keep this in sync with the ArrayView version assert!(index <= self.shape().axis(axis)); let left_ptr = self.ptr; let right_ptr = if index == self.shape().axis(axis) { self.ptr } else { let offset = stride_offset(index, self.strides.axis(axis)); unsafe { self.ptr.offset(offset) } }; let mut dim_left = self.dim.clone(); dim_left.set_axis(axis, index); let left = unsafe { Self::new_(left_ptr, dim_left, self.strides.clone()) }; let mut dim_right = self.dim; let right_len = dim_right.axis(axis) - index; dim_right.set_axis(axis, right_len); let right = unsafe { Self::new_(right_ptr, dim_right, self.strides) }; (left, right) } }