Repository: rust-ndarray/ndarray
Pull request #1113 (2021-11-17 18:04:41)

Release notes for 0.15.4


Patch:
diff --git a/RELEASES.md b/RELEASES.md
index cfb5e7d3..c0eab138 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,120 @@
+Version 0.15.4 (2021-11-xx)
+===========================
+
+New features
+------------
+
+- Complex matrix multiplication now uses BLAS ``cgemm``/``zgemm`` when
+  enabled (and matrix layout allows), by [@ethanhs].
+
+  https://github.com/rust-ndarray/ndarray/pull/1106
+
+- Use `matrixmultiply` as fallback for complex matrix multiplication
+  when BLAS is not available or the matrix layout requires it by [@bluss]
+
+  https://github.com/rust-ndarray/ndarray/pull/1118
+
+- Add ``into/to_slice_memory_order`` methods for views, lifetime-preserving
+  versions of existing similar methods by [@jturner314]
+
+  https://github.com/rust-ndarray/ndarray/pull/1015
+
+- ``kron`` function for Kronecker product by [@ethanhs].
+
+  https://github.com/rust-ndarray/ndarray/pull/1105
+
+- ``split_complex`` method for splitting complex arrays into separate
+  real and imag view parts by [@jturner314] and [@ethanhs].
+
+  https://github.com/rust-ndarray/ndarray/pull/1107
+
+- New method ``try_into_owned_nocopy`` by [@jturner314]
+
+  https://github.com/rust-ndarray/ndarray/pull/1022
+
+- New producer and iterable ``axis_windows`` by [@VasanthakumarV]
+  and [@jturner314].
+
+  https://github.com/rust-ndarray/ndarray/pull/1022
+
+- New method ``Zip::par_fold`` by [@adamreichold]
+
+  https://github.com/rust-ndarray/ndarray/pull/1095
+
+- New constructor ``from_diag_elem`` by [@jturner314]
+
+  https://github.com/rust-ndarray/ndarray/pull/1076
+
+- ``Parallel::with_min_len`` method for parallel iterators by [@adamreichold]
+
+  https://github.com/rust-ndarray/ndarray/pull/1081
+
+- Allocation-preserving map function ``.mapv_into_any()`` added by [@benkay86]
+
+Enhancements
+------------
+
+- Improve performance of ``.sum_axis()`` for some cases by [@jturner314]
+
+  https://github.com/rust-ndarray/ndarray/pull/1061
+
+Bug fixes
+---------
+
+- Fix error in calling dgemv (matrix-vector multiplication) with BLAS and
+  broadcasted arrays, by [@jturner314].
+
+  https://github.com/rust-ndarray/ndarray/pull/1088
+
+API changes
+-----------
+
+- Support approx 0.5 partially alongside the already existing approx 0.4 support.
+  New feature flag is `approx-0_5`, by [@jturner314]
+
+  https://github.com/rust-ndarray/ndarray/pull/1025
+
+- Slice and reference-to-array conversions to CowArray added for by [@jturner314].
+
+  https://github.com/rust-ndarray/ndarray/pull/1038
+
+- Allow trailing comma in stack and concatenate macros by [@jturner314]
+
+  https://github.com/rust-ndarray/ndarray/pull/1044
+
+- ``Zip`` now has a ``must_use`` marker to help users by [@adamreichold]
+
+  https://github.com/rust-ndarray/ndarray/pull/1082
+
+Other changes
+-------------
+
+- Fixing the crates.io badge on github by [@atouchet]
+
+  https://github.com/rust-ndarray/ndarray/pull/1104
+
+- Use intra-doc links in docs by [@LeSeulArtichaut]
+
+  https://github.com/rust-ndarray/ndarray/pull/1033
+
+- Clippy fixes by [@adamreichold]
+
+  https://github.com/rust-ndarray/ndarray/pull/1092 <br>
+  https://github.com/rust-ndarray/ndarray/pull/1091
+
+- Minor fixes in links and punctuation in docs by [@jimblandy]
+
+  https://github.com/rust-ndarray/ndarray/pull/1056
+
+- Minor fixes in docs by [@chohner]
+
+  https://github.com/rust-ndarray/ndarray/pull/1119
+
+- Update tests to quickcheck 1.0 by [@bluss]
+
+  https://github.com/rust-ndarray/ndarray/pull/1114
+
+
 Version 0.15.3 (2021-06-05)
 ===========================
 
@@ -1427,13 +1544,20 @@ Earlier releases
 [@jturner314]: https://github.com/jturner314
 [@LukeMathWalker]: https://github.com/LukeMathWalker
 [@acj]: https://github.com/acj
+[@adamreichold]: https://github.com/adamreichold
+[@atouchet]: https://github.com/atouchet
 [@andrei-papou]: https://github.com/andrei-papou
+[@benkay]: https://github.com/benkay
 [@cassiersg]: https://github.com/cassiersg
+[@chohner]: https://github.com/chohner
 [@dam5h]: https://github.com/dam5h
+[@ethanhs]: https://github.com/ethanhs
 [@d-dorazio]: https://github.com/d-dorazio
 [@Eijebong]: https://github.com/Eijebong
 [@insideoutclub]: https://github.com/insideoutclub
 [@JP-Ellis]: https://github.com/JP-Ellis
+[@jimblandy]: https://github.com/jimblandy
+[@LeSeulArtichaut]: https://github.com/LeSeulArtichaut
 [@lifuyang]: https://github.com/liufuyang
 [@kdubovikov]: https://github.com/kdubovikov
 [@max-sixty]: https://github.com/max-sixty
@@ -1448,5 +1572,6 @@ Earlier releases
 [@termoshtt]: https://github.com/termoshtt
 [@TheLortex]: https://github.com/TheLortex
 [@viniciusd]: https://github.com/viniciusd
+[@VasanthakumarV]: https://github.com/VasanthakumarV
 [@xd009642]: https://github.com/xd009642
 [@Zuse64]: https://github.com/Zuse64
diff --git a/src/doc/crate_feature_flags.rs b/src/doc/crate_feature_flags.rs
new file mode 100644
index 00000000..b396755c
--- /dev/null
+++ b/src/doc/crate_feature_flags.rs
@@ -0,0 +1,35 @@
+//! Crate Feature Flags
+//!
+//! The following crate feature flags are available. They are configured in your
+//! `Cargo.toml` where the dependency on `ndarray` is defined.
+//!
+//! ## `std`
+//!   - Rust standard library (enabled by default)
+//!   - This crate can be used without the standard library by disabling the
+//!     default `std` feature. To do so, use `default-features = false` in
+//!     your `Cargo.toml`.
+//!   - The `geomspace` `linspace` `logspace` `range` `std` `var` `var_axis`
+//!     and `std_axis` methods are only available when `std` is enabled.
+//!
+//! ## `serde`
+//!   - Enables serialization support for serde 1.x
+//!
+//! ## `rayon`
+//!   - Enables parallel iterators, parallelized methods, the [`parallel`] module and [`par_azip!`].
+//!   - Implies std
+//!
+//! ## `approx`
+//!   - Enables implementations of traits from version 0.4 of the [`approx`] crate.
+//!
+//! ## `approx-0_5`
+//!   - Enables implementations of traits from version 0.5 of the [`approx`] crate.
+//!
+//! ## `blas`
+//!   - Enable transparent BLAS support for matrix multiplication.
+//!     Uses ``blas-src`` for pluggable backend, which needs to be configured
+//!     separately (see the README).
+//!
+//! ## `matrixmultiply-threading`
+//!   - Enable the ``threading`` feature in the matrixmultiply package
+//!
+//! [`parallel`]: crate::parallel
diff --git a/src/doc/mod.rs b/src/doc/mod.rs
index b98c9cab..c0d7fab9 100644
--- a/src/doc/mod.rs
+++ b/src/doc/mod.rs
@@ -1,3 +1,4 @@
 //! Standalone documentation pages.
 
+pub mod crate_feature_flags;
 pub mod ndarray_for_numpy_users;
diff --git a/src/impl_owned_array.rs b/src/impl_owned_array.rs
index e5893274..8cfb82b5 100644
--- a/src/impl_owned_array.rs
+++ b/src/impl_owned_array.rs
@@ -120,7 +120,7 @@ impl<A> Array<A, Ix2> {
 
     /// Append a column to an array
     ///
-    /// The elements from `column` are cloned and added as a new row in the array.
+    /// The elements from `column` are cloned and added as a new column in the array.
     ///
     /// ***Errors*** with a shape error if the length of the column does not match the length of
     /// the columns in the array.
@@ -380,7 +380,7 @@ impl<A, D> Array<A, D>
     /// appending to an array along the same axis.
     ///
     /// The amortized average complexity of the append, when appending along its growing axis, is
-    /// O(*m*) where *m* is the length of the row.
+    /// O(*m*) where *m* is the number of individual elements to append.
     ///
     /// The memory layout of the argument `array` does not matter to the same extent.
     ///
@@ -438,14 +438,14 @@ impl<A, D> Array<A, D>
     /// appending to an array along the same axis.
     ///
     /// The amortized average complexity of the append, when appending along its growing axis, is
-    /// O(*m*) where *m* is the length of the row.
+    /// O(*m*) where *m* is the number of individual elements to append.
     ///
     /// The memory layout of the argument `array` does not matter to the same extent.
     ///
     /// ```rust
     /// use ndarray::{Array, ArrayView, array, Axis};
     ///
-    /// // create an empty array and append
+    /// // create an empty array and append two rows at a time
     /// let mut a = Array::zeros((0, 4));
     /// let ones  = ArrayView::from(&[1.; 8]).into_shape((2, 4)).unwrap();
     /// let zeros = ArrayView::from(&[0.; 8]).into_shape((2, 4)).unwrap();
diff --git a/src/impl_raw_views.rs b/src/impl_raw_views.rs
index 425af96c..64a5c4c8 100644
--- a/src/impl_raw_views.rs
+++ b/src/impl_raw_views.rs
@@ -156,7 +156,7 @@ where
 {
     /// Splits the view into views of the real and imaginary components of the
     /// elements.
-    pub fn split_re_im(self) -> Complex<RawArrayView<T, D>> {
+    pub fn split_complex(self) -> Complex<RawArrayView<T, D>> {
         // Check that the size and alignment of `Complex<T>` are as expected.
         // These assertions should always pass, for arbitrary `T`.
         assert_eq!(
@@ -375,8 +375,8 @@ where
 {
     /// Splits the view into views of the real and imaginary components of the
     /// elements.
-    pub fn split_re_im(self) -> Complex<RawArrayViewMut<T, D>> {
-        let Complex { re, im } = self.into_raw_view().split_re_im();
+    pub fn split_complex(self) -> Complex<RawArrayViewMut<T, D>> {
+        let Complex { re, im } = self.into_raw_view().split_complex();
         unsafe {
             Complex {
                 re: RawArrayViewMut::new(re.ptr, re.dim, re.strides),
diff --git a/src/impl_views/splitting.rs b/src/impl_views/splitting.rs
index 84d24038..028148dd 100644
--- a/src/impl_views/splitting.rs
+++ b/src/impl_views/splitting.rs
@@ -112,13 +112,13 @@ where
     ///     [Complex64::new(5., 6.), Complex64::new(7., 8.)],
     ///     [Complex64::new(9., 10.), Complex64::new(11., 12.)],
     /// ];
-    /// let Complex { re, im } = arr.view().split_re_im();
+    /// let Complex { re, im } = arr.view().split_complex();
     /// assert_eq!(re, array![[1., 3.], [5., 7.], [9., 11.]]);
     /// assert_eq!(im, array![[2., 4.], [6., 8.], [10., 12.]]);
     /// ```
-    pub fn split_re_im(self) -> Complex<ArrayView<'a, T, D>> {
+    pub fn split_complex(self) -> Complex<ArrayView<'a, T, D>> {
         unsafe {
-            let Complex { re, im } = self.into_raw_view().split_re_im();
+            let Complex { re, im } = self.into_raw_view().split_complex();
             Complex {
                 re: re.deref_into_view(),
                 im: im.deref_into_view(),
@@ -185,7 +185,7 @@ where
     ///     [Complex64::new(9., 10.), Complex64::new(11., 12.)],
     /// ];
     ///
-    /// let Complex { mut re, mut im } = arr.view_mut().split_re_im();
+    /// let Complex { mut re, mut im } = arr.view_mut().split_complex();
     /// assert_eq!(re, array![[1., 3.], [5., 7.], [9., 11.]]);
     /// assert_eq!(im, array![[2., 4.], [6., 8.], [10., 12.]]);
     ///
@@ -195,9 +195,9 @@ where
     /// assert_eq!(arr[[0, 1]], Complex64::new(13., 4.));
     /// assert_eq!(arr[[2, 0]], Complex64::new(9., 14.));
     /// ```
-    pub fn split_re_im(self) -> Complex<ArrayViewMut<'a, T, D>> {
+    pub fn split_complex(self) -> Complex<ArrayViewMut<'a, T, D>> {
         unsafe {
-            let Complex { re, im } = self.into_raw_view_mut().split_re_im();
+            let Complex { re, im } = self.into_raw_view_mut().split_complex();
             Complex {
                 re: re.deref_into_view_mut(),
                 im: im.deref_into_view_mut(),
diff --git a/src/lib.rs b/src/lib.rs
index aadef4c9..a8ee9ee6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -75,30 +75,15 @@
 //! ## Crate Feature Flags
 //!
 //! The following crate feature flags are available. They are configured in your
-//! `Cargo.toml`.
+//! `Cargo.toml`. See [`doc::crate_feature_flags`] for more information.
 //!
-//! - `std`
-//!   - Rust standard library (enabled by default)
-//!   - This crate can be used without the standard library by disabling the
-//!     default `std` feature. To do so, use `default-features = false` in
-//!     your `Cargo.toml`.
-//!   - The `geomspace` `linspace` `logspace` `range` `std` `var` `var_axis`
-//!     and `std_axis` methods are only available when `std` is enabled.
-//! - `serde`
-//!   - Enables serialization support for serde 1.x
-//! - `rayon`
-//!   - Enables parallel iterators, parallelized methods, the [`parallel`] module and [`par_azip!`].
-//!   - Implies std
-//! - `approx`
-//!   - Enables implementations of traits from version 0.4 of the [`approx`] crate.
-//! - `approx-0_5`
-//!   - Enables implementations of traits from version 0.5 of the [`approx`] crate.
-//! - `blas`
-//!   - Enable transparent BLAS support for matrix multiplication.
-//!     Uses ``blas-src`` for pluggable backend, which needs to be configured
-//!     separately (see the README).
-//! - `matrixmultiply-threading`
-//!   - Enable the ``threading`` feature in the matrixmultiply package
+//! - `std`: Rust standard library-using functionality (enabled by default)
+//! - `serde`: serialization support for serde 1.x
+//! - `rayon`: Parallel iterators, parallelized methods, the [`parallel`] module and [`par_azip!`].
+//! - `approx` Implementations of traits from version 0.4 of the [`approx`] crate.
+//! - `approx-0_5`: Implementations of traits from version 0.5 of the [`approx`] crate.
+//! - `blas`: transparent BLAS support for matrix multiplication, needs configuration.
+//! - `matrixmultiply-threading`: Use threading from `matrixmultiply`.
 //!
 //! ## Documentation
 //!
@@ -246,9 +231,13 @@ pub type Ixs = isize;
 
 /// An *n*-dimensional array.
 ///
-/// The array is a general container of elements. It cannot grow or shrink (with some exceptions),
-/// but can be sliced into subsets of its data.
-/// The array supports arithmetic operations by applying them elementwise.
+/// The array is a general container of elements.
+/// The array supports arithmetic operations by applying them elementwise, if the
+/// elements are numeric, but it supports non-numeric elements too.
+///
+/// The arrays rarely grow or shrink, since those operations can be costly. On
+/// the other hand there is a rich set of methods and operations for taking views,
+/// slices, and making traversals over one or more arrays.
 ///
 /// In *n*-dimensional we include for example 1-dimensional rows or columns,
 /// 2-dimensional matrices, and higher dimensional arrays. If the array has *n*
@@ -259,7 +248,7 @@ pub type Ixs = isize;
 ///
 /// Type aliases [`Array`], [`ArcArray`], [`CowArray`], [`ArrayView`], and
 /// [`ArrayViewMut`] refer to `ArrayBase` with different types for the data
-/// container.
+/// container: arrays with different kinds of ownership or different kinds of array views.
 ///
 /// ## Contents
 ///


Test patch:
diff --git a/tests/array.rs b/tests/array.rs
index 44565965..a16e75fd 100644
--- a/tests/array.rs
+++ b/tests/array.rs
@@ -2541,17 +2541,17 @@ fn test_remove_index_oob3() {
 }
 
 #[test]
-fn test_split_re_im_view() {
+fn test_split_complex_view() {
     let a = Array3::from_shape_fn((3, 4, 5), |(i, j, k)| {
         Complex::<f32>::new(i as f32 * j as f32, k as f32)
     });
-    let Complex { re, im } = a.view().split_re_im();
+    let Complex { re, im } = a.view().split_complex();
     assert_relative_eq!(re.sum(), 90.);
     assert_relative_eq!(im.sum(), 120.);
 }
 
 #[test]
-fn test_split_re_im_view_roundtrip() {
+fn test_split_complex_view_roundtrip() {
     let a_re = Array3::from_shape_fn((3,1,5), |(i, j, _k)| {
         i * j
     });
@@ -2561,49 +2561,49 @@ fn test_split_re_im_view_roundtrip() {
     let a = Array3::from_shape_fn((3,1,5), |(i,j,k)| {
         Complex::new(a_re[[i,j,k]], a_im[[i,j,k]])
     });
-    let Complex { re, im } = a.view().split_re_im();
+    let Complex { re, im } = a.view().split_complex();
     assert_eq!(a_re, re);
     assert_eq!(a_im, im);
 }
 
 #[test]
-fn test_split_re_im_view_mut() {
+fn test_split_complex_view_mut() {
     let eye_scalar = Array2::<u32>::eye(4);
     let eye_complex = Array2::<Complex<u32>>::eye(4);
     let mut a = Array2::<Complex<u32>>::zeros((4, 4));
-    let Complex { mut re, im } = a.view_mut().split_re_im();
+    let Complex { mut re, im } = a.view_mut().split_complex();
     re.assign(&eye_scalar);
     assert_eq!(im.sum(), 0);
     assert_eq!(a, eye_complex);
 }
 
 #[test]
-fn test_split_re_im_zerod() {
+fn test_split_complex_zerod() {
     let mut a = Array0::from_elem((), Complex::new(42, 32));
-    let Complex { re, im } = a.view().split_re_im();
+    let Complex { re, im } = a.view().split_complex();
     assert_eq!(re.get(()), Some(&42));
     assert_eq!(im.get(()), Some(&32));
-    let cmplx = a.view_mut().split_re_im();
+    let cmplx = a.view_mut().split_complex();
     cmplx.re.assign_to(cmplx.im);
     assert_eq!(a.get(()).unwrap().im, 42);
 }
 
 #[test]
-fn test_split_re_im_permuted() {
+fn test_split_complex_permuted() {
     let a = Array3::from_shape_fn((3, 4, 5), |(i, j, k)| {
         Complex::new(i * k + j, k)
     });
     let permuted = a.view().permuted_axes([1,0,2]);
-    let Complex { re, im } = permuted.split_re_im();
+    let Complex { re, im } = permuted.split_complex();
     assert_eq!(re.get((3,2,4)).unwrap(), &11);
     assert_eq!(im.get((3,2,4)).unwrap(), &4);
 }
 
 #[test]
-fn test_split_re_im_invert_axis() {
+fn test_split_complex_invert_axis() {
     let mut a = Array::from_shape_fn((2, 3, 2), |(i, j, k)| Complex::new(i as f64 + j as f64, i as f64 + k as f64));
     a.invert_axis(Axis(1));
-    let cmplx = a.view().split_re_im();
+    let cmplx = a.view().split_complex();
     assert_eq!(cmplx.re, a.mapv(|z| z.re));
     assert_eq!(cmplx.im, a.mapv(|z| z.im));
 }