diff --git a/Cargo.toml b/Cargo.toml index 9b3aab602..d9db68c2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,14 @@ [package] -name = "ndarray" -version = "0.0.1" +name = "rendarray" +version = "0.1.0" authors = ["bluss"] repository = "https://github.com/bluss/rust-ndarray" documentation = "http://bluss.github.io/rust-ndarray/" +[lib] +name = "ndarray" + [dependencies.num] version = "0.1" features = ["complex"] @@ -22,3 +25,7 @@ version = "0.4" version = "0.4" optional = true + +[features] + +assign_ops = [] diff --git a/Makefile b/Makefile index 27edc76cf..e3234c115 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ DOCCRATES = ndarray # deps to delete the generated docs RMDOCS = -FEATURES = +FEATURES = assign_ops VERSIONS = $(patsubst %,target/VERS/%,$(DOCCRATES)) @@ -12,7 +12,7 @@ docs: mkdocs subst $(RMDOCS) # https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html $(VERSIONS): Cargo.toml mkdir -p $(@D) - cargo pkgid $(@F) | sed -e "s/.*#\(\|.*:\)//" > "$@" + cargo pkgid rendarray | sed -e "s/.*#\(\|.*:\)//" > "$@" $(DOCCRATES): %: target/VERS/% # Put in the crate version into the docs diff --git a/custom.css b/custom.css index 9dcc3036b..8e0b7053e 100644 --- a/custom.css +++ b/custom.css @@ -18,3 +18,8 @@ pre.trait .where::before { content: '\a '; } +.docblock code { + background-color: inherit; + font-weight: bold; + padding: 0 0.1em; +} diff --git a/src/lib.rs b/src/lib.rs index 4d07da6e2..b984a60e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,14 @@ //! or linear algebra. `Array` is a good container. //! - There is no integration with linear algebra packages (at least not yet). //! +//! ## Crate feature flags +//! +//! - `assign_ops` +//! - Optional, requires nightly +//! - Enables the compound assignment operators +//! +#![cfg_attr(feature = "assign_ops", feature(augmented_assignments, + op_assign_traits))] #[cfg(feature = "serde")] extern crate serde; @@ -42,6 +50,7 @@ pub use indexes::Indexes; use iterators::Baseiter; + pub mod linalg; mod arraytraits; #[cfg(feature = "serde")] @@ -1102,18 +1111,18 @@ impl Array where } } -impl<'a, A, D, E> $trt> for Array where - A: Clone + $trt, - D: Dimension, - E: Dimension, +/// Perform an elementwise arithmetic operation between **self** and **other**, +/// and return the result. +/// +/// If their shapes disagree, **other** is broadcast to the shape of **self**. +/// +/// **Panics** if broadcasting isn't possible. +impl<'a, A, D, E> $trt> for Array + where A: Clone + $trt, + D: Dimension, + E: Dimension, { type Output = Array; - /// Perform an elementwise arithmetic operation between **self** and **other**, - /// and return the result. - /// - /// If their shapes disagree, **other** is broadcast to the shape of **self**. - /// - /// **Panics** if broadcasting isn't possible. fn $mth (mut self, other: Array) -> Array { // FIXME: Can we co-broadcast arrays here? And how? @@ -1131,18 +1140,18 @@ impl<'a, A, D, E> $trt> for Array where } } -impl<'a, A, D, E> $trt<&'a Array> for &'a Array where - A: Clone + $trt, - D: Dimension, - E: Dimension, +/// Perform an elementwise arithmetic operation between **self** and **other**, +/// and return the result. +/// +/// If their shapes disagree, **other** is broadcast to the shape of **self**. +/// +/// **Panics** if broadcasting isn't possible. +impl<'a, A, D, E> $trt<&'a Array> for &'a Array + where A: Clone + $trt, + D: Dimension, + E: Dimension, { type Output = Array; - /// Perform an elementwise arithmetic operation between **self** and **other**, - /// and return the result. - /// - /// If their shapes disagree, **other** is broadcast to the shape of **self**. - /// - /// **Panics** if broadcasting isn't possible. fn $mth (self, other: &'a Array) -> Array { // FIXME: Can we co-broadcast arrays here? And how? @@ -1176,6 +1185,64 @@ impl_binary_op!(BitXor, bitxor, ibitxor, ibitxor_scalar); impl_binary_op!(Shl, shl, ishl, ishl_scalar); impl_binary_op!(Shr, shr, ishr, ishr_scalar); +#[cfg(feature = "assign_ops")] +mod assign_ops { + use super::*; + + use std::ops::{ + AddAssign, + SubAssign, + MulAssign, + DivAssign, + RemAssign, + BitAndAssign, + BitOrAssign, + BitXorAssign, + }; + + + macro_rules! impl_assign_op { + ($trt:ident, $method:ident) => { + + /// Perform an elementwise in place arithmetic operation between **self** and **other**, + /// + /// If their shapes disagree, **other** is broadcast to the shape of **self**. + /// + /// **Panics** if broadcasting isn't possible. + /// + /// **Requires `feature = "assign_ops"`** + impl<'a, A, D, E> $trt<&'a Array> for Array + where A: Clone + $trt, + D: Dimension, + E: Dimension, + { + fn $method(&mut self, other: &Array) { + if self.shape() == other.shape() { + for (x, y) in self.iter_mut().zip(other.iter()) { + x.$method(y.clone()); + } + } else { + let other_iter = other.broadcast_iter_unwrap(self.dim()); + for (x, y) in self.iter_mut().zip(other_iter) { + x.$method(y.clone()); + } + } + } + } + + }; + } + + impl_assign_op!(AddAssign, add_assign); + impl_assign_op!(SubAssign, sub_assign); + impl_assign_op!(MulAssign, mul_assign); + impl_assign_op!(DivAssign, div_assign); + impl_assign_op!(RemAssign, rem_assign); + impl_assign_op!(BitAndAssign, bitand_assign); + impl_assign_op!(BitOrAssign, bitor_assign); + impl_assign_op!(BitXorAssign, bitxor_assign); +} + impl, D: Dimension> Array {