From 1dc4bfd8f094a47236e1a30a2e20dba8e7d217e5 Mon Sep 17 00:00:00 2001 From: bluss Date: Sun, 28 Feb 2016 18:14:43 +0100 Subject: [PATCH 1/4] Arithmetic operations B @ A are now only implemented for owned storage `B` Previously, operators like +, - etc, denoted by @ in general, were implemented so that they allowed ArrayViewMut as the left hand side operand. It would update the data in the view, and return the same view. This can be confusing, and was suggested by @SuperFluffy to be removed. We tentatively remove those implementations here. To work around B @ A not being allowed for a mutable view `B`, you can use B @= A instead, or the corresponding stable methods iadd, imul, etc. Please see the Arithmetic Operations overview in the `ArrayBase` docs for an easy to read overview. Fixes #83 --- examples/life.rs | 17 ++++++++--------- src/lib.rs | 18 ++++++++++++------ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/examples/life.rs b/examples/life.rs index 027dfd42b..66913b178 100644 --- a/examples/life.rs +++ b/examples/life.rs @@ -40,17 +40,16 @@ fn iterate(z: &mut Board, scratch: &mut Board) { // compute number of neighbors let mut neigh = scratch.view_mut(); neigh.assign_scalar(&0); - let neigh = neigh - + z.slice(s![0..-2, 0..-2]) - + z.slice(s![0..-2, 1..-1]) - + z.slice(s![0..-2, 2.. ]) + neigh.iadd(&z.slice(s![0..-2, 0..-2])); + neigh.iadd(&z.slice(s![0..-2, 1..-1])); + neigh.iadd(&z.slice(s![0..-2, 2.. ])); - + z.slice(s![1..-1, 0..-2]) - + z.slice(s![1..-1, 2.. ]) + neigh.iadd(&z.slice(s![1..-1, 0..-2])); + neigh.iadd(&z.slice(s![1..-1, 2.. ])); - + z.slice(s![2.. , 0..-2]) - + z.slice(s![2.. , 1..-1]) - + z.slice(s![2.. , 2.. ]); + neigh.iadd(&z.slice(s![2.. , 0..-2])); + neigh.iadd(&z.slice(s![2.. , 1..-1])); + neigh.iadd(&z.slice(s![2.. , 2.. ])); // birth where n = 3 and z[i] = 0, // survive where n = 2 || n = 3 and z[i] = 1 diff --git a/src/lib.rs b/src/lib.rs index bde34026b..253c61ae3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -296,15 +296,17 @@ pub type Ixs = isize; /// /// Since the trait implementations are hard to overview, here is a summary. /// -/// Let `A` be an array or view of any kind. Let `B` be a mutable -/// array (that is, either `OwnedArray`, `RcArray`, or `ArrayViewMut`) +/// Let `A` be an array or view of any kind. Let `B` be an array +/// with owned storage (either `OwnedArray` or `RcArray`). +/// Let `C` be an array with mutable data (either `OwnedArray`, `RcArray` +/// or `ArrayViewMut`). /// The following combinations of operands /// are supported for an arbitrary binary operator denoted by `@`. /// /// - `&A @ &A` which produces a new `OwnedArray` /// - `B @ A` which consumes `B`, updates it with the result, and returns it /// - `B @ &A` which consumes `B`, updates it with the result, and returns it -/// - `B @= &A` which performs an arithmetic operation in place +/// - `C @= &A` which performs an arithmetic operation in place /// (requires `features = "assign_ops"`) /// /// The trait [`Scalar`](trait.Scalar.html) marks types that can be used in arithmetic @@ -313,7 +315,7 @@ pub type Ixs = isize; /// /// - `&A @ K` or `K @ &A` which produces a new `OwnedArray` /// - `B @ K` or `K @ B` which consumes `B`, updates it with the result and returns it -/// - `B @= K` which performs an arithmetic operation in place +/// - `C @= K` which performs an arithmetic operation in place /// (requires `features = "assign_ops"`) /// /// ## Broadcasting @@ -2549,12 +2551,14 @@ macro_rules! impl_binary_op( /// between `self` and `rhs`, /// and return the result (based on `self`). /// +/// `self` must be an `OwnedArray` or `RcArray`. +/// /// If their shapes disagree, `rhs` is broadcast to the shape of `self`. /// /// **Panics** if broadcasting isn’t possible. impl $trt> for ArrayBase where A: Clone + $trt, - S: DataMut, + S: DataOwned + DataMut, S2: Data, D: Dimension, E: Dimension, @@ -2616,9 +2620,11 @@ impl<'a, A, S, S2, D, E> $trt<&'a ArrayBase> for &'a ArrayBase #[doc=$doc] /// between `self` and the scalar `x`, /// and return the result (based on `self`). +/// +/// `self` must be an `OwnedArray` or `RcArray`. impl $trt for ArrayBase where A: Clone + $trt, - S: DataMut, + S: DataOwned + DataMut, D: Dimension, B: Clone + Scalar, { From ef8d104c3242eed022acf72b3d0c02afb0a6bf0d Mon Sep 17 00:00:00 2001 From: bluss Date: Sun, 28 Feb 2016 18:23:17 +0100 Subject: [PATCH 2/4] Add small table of contents to ArrayBase's documentation. --- src/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 253c61ae3..14c416f82 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -141,6 +141,16 @@ pub type Ixs = isize; /// [`ArrayView`]: type.ArrayView.html /// [`ArrayViewMut`]: type.ArrayViewMut.html /// +/// ## Contents +/// +/// + [OwnedArray and RcArray](#ownedarray-and-rcarray) +/// + [Indexing and Dimension](#indexing-and-dimension) +/// + [Slicing](#slicing) +/// + [Subviews](#subviews) +/// + [Arithmetic Operations](#arithmetic-operations) +/// + [Broadcasting](#broadcasting) +/// + [Methods](#methods) +/// /// ## `OwnedArray` and `RcArray` /// /// `OwnedArray` owns the underlying array elements directly (just like From 773f437966e2c4ee3ba850c6e11564bc9b268e3f Mon Sep 17 00:00:00 2001 From: bluss Date: Sun, 28 Feb 2016 18:35:53 +0100 Subject: [PATCH 3/4] Be more clear about *crate* feature flags --- src/arraytraits.rs | 4 ++-- src/blas.rs | 10 +++++----- src/lib.rs | 11 +++++++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/arraytraits.rs b/src/arraytraits.rs index 0f2d98e34..8494763be 100644 --- a/src/arraytraits.rs +++ b/src/arraytraits.rs @@ -185,7 +185,7 @@ unsafe impl Send for ArrayBase // Use version number so we can add a packed format later. static ARRAY_FORMAT_VERSION: u8 = 1u8; -/// **Requires `feature = "rustc-serialize"`** +/// **Requires crate feature `"rustc-serialize"`** #[cfg(feature = "rustc-serialize")] impl Encodable for ArrayBase where A: Encodable, @@ -212,7 +212,7 @@ impl Encodable for ArrayBase } } -/// **Requires `feature = "rustc-serialize"`** +/// **Requires crate feature `"rustc-serialize"`** #[cfg(feature = "rustc-serialize")] impl Decodable for ArrayBase where A: Decodable, diff --git a/src/blas.rs b/src/blas.rs index 4fe20d2c2..cd8aab6ec 100644 --- a/src/blas.rs +++ b/src/blas.rs @@ -1,6 +1,6 @@ //! Experimental BLAS (Basic Linear Algebra Subprograms) integration //! -//! ***Requires `features = "rblas"`*** +//! ***Requires crate feature `"rblas"`*** //! //! Depends on crate [`rblas`], ([docs]). //! @@ -70,7 +70,7 @@ use super::{ }; -/// ***Requires `features = "rblas"`*** +/// ***Requires crate feature `"rblas"`*** pub struct BlasArrayView<'a, A: 'a, D>(ArrayView<'a, A, D>); impl<'a, A, D: Copy> Copy for BlasArrayView<'a, A, D> { } impl<'a, A, D: Clone> Clone for BlasArrayView<'a, A, D> { @@ -79,7 +79,7 @@ impl<'a, A, D: Clone> Clone for BlasArrayView<'a, A, D> { } } -/// ***Requires `features = "rblas"`*** +/// ***Requires crate feature `"rblas"`*** pub struct BlasArrayViewMut<'a, A: 'a, D>(ArrayViewMut<'a, A, D>); impl ArrayBase @@ -137,7 +137,7 @@ impl<'a, A, D> ArrayViewMut<'a, A, D> /// Note that `blas` suppors four different element types: `f32`, `f64`, /// `Complex`, and `Complex`. /// -/// ***Requires `features = "rblas"`*** +/// ***Requires crate feature `"rblas"`*** pub trait AsBlas { /// Return an array view implementing Vector (1D) or Matrix (2D) /// traits. @@ -222,7 +222,7 @@ pub trait AsBlas { */ } -/// ***Requires `features = "rblas"`*** +/// ***Requires crate feature `"rblas"`*** impl AsBlas for ArrayBase where S: Data, D: Dimension, diff --git a/src/lib.rs b/src/lib.rs index 14c416f82..c6d85f5a9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,6 +38,9 @@ //! //! ## Crate Feature Flags //! +//! The following crate feature flags are available. The are specified in +//! `Cargo.toml`. +//! //! - `assign_ops` //! - Optional, requires nightly //! - Enables the compound assignment operators @@ -317,7 +320,7 @@ pub type Ixs = isize; /// - `B @ A` which consumes `B`, updates it with the result, and returns it /// - `B @ &A` which consumes `B`, updates it with the result, and returns it /// - `C @= &A` which performs an arithmetic operation in place -/// (requires `features = "assign_ops"`) +/// (requires crate feature `"assign_ops"`) /// /// The trait [`Scalar`](trait.Scalar.html) marks types that can be used in arithmetic /// with arrays directly. For a scalar `K` the following combinations of operands @@ -326,7 +329,7 @@ pub type Ixs = isize; /// - `&A @ K` or `K @ &A` which produces a new `OwnedArray` /// - `B @ K` or `K @ B` which consumes `B`, updates it with the result and returns it /// - `C @= K` which performs an arithmetic operation in place -/// (requires `features = "assign_ops"`) +/// (requires crate feature `"assign_ops"`) /// /// ## Broadcasting /// @@ -2809,7 +2812,7 @@ mod assign_ops { /// /// **Panics** if broadcasting isn’t possible. /// - /// **Requires `feature = "assign_ops"`** + /// **Requires crate feature `"assign_ops"`** impl<'a, A, S, S2, D, E> $trt<&'a ArrayBase> for ArrayBase where A: Clone + $trt, S: DataMut, @@ -2825,7 +2828,7 @@ mod assign_ops { } #[doc=$doc] - /// **Requires `feature = "assign_ops"`** + /// **Requires crate feature `"assign_ops"`** impl $trt for ArrayBase where A: $trt, S: DataMut, From 7c337ca4200a078d3e24d1049b132bfb642b2116 Mon Sep 17 00:00:00 2001 From: bluss Date: Sun, 28 Feb 2016 18:39:58 +0100 Subject: [PATCH 4/4] Update benchmarks for arithmetic ops with mut views --- benches/bench1.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/benches/bench1.rs b/benches/bench1.rs index 3b1e7d7cb..327febfb4 100644 --- a/benches/bench1.rs +++ b/benches/bench1.rs @@ -266,7 +266,7 @@ fn add_2d_regular(bench: &mut test::Bencher) let b = OwnedArray::::zeros((64, 64)); let bv = b.view(); bench.iter(|| { - let _x = black_box(a.view_mut() + bv); + a.iadd(&bv); }); } @@ -292,7 +292,7 @@ fn add_2d_cutout(bench: &mut test::Bencher) let b = OwnedArray::::zeros((64, 64)); let bv = b.view(); bench.iter(|| { - let _x = black_box(acut.view_mut() + bv); + acut.iadd(&bv); }); } @@ -303,7 +303,7 @@ fn add_2d_broadcast_1_to_2(bench: &mut test::Bencher) let b = OwnedArray::::zeros(64); let bv = b.view(); bench.iter(|| { - let _x = black_box(a.view_mut() + bv); + a.iadd(&bv); }); } @@ -314,7 +314,7 @@ fn add_2d_broadcast_0_to_2(bench: &mut test::Bencher) let b = OwnedArray::::zeros(()); let bv = b.view(); bench.iter(|| { - let _x = black_box(a.view_mut() + bv); + a.iadd(&bv); }); } @@ -337,7 +337,7 @@ fn add_2d_transposed(bench: &mut test::Bencher) let b = OwnedArray::::zeros((64, 64)); let bv = b.view(); bench.iter(|| { - let _x = black_box(a.view_mut() + bv); + a.iadd(&bv); }); } @@ -348,7 +348,7 @@ fn add_2d_f32_regular(bench: &mut test::Bencher) let b = OwnedArray::::zeros((64, 64)); let bv = b.view(); bench.iter(|| { - let _x = black_box(a.view_mut() + bv); + a.iadd(&bv); }); }