Skip to content

Commit 43fe8dc

Browse files
author
Nil Goyette
authored
Merge branch 'rust-ndarray:master' into zip_any
2 parents 5e8ebc2 + 9447328 commit 43fe8dc

File tree

21 files changed

+269
-117
lines changed

21 files changed

+269
-117
lines changed

.github/workflows/ci.yml

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,11 @@ jobs:
2424
- 1.51.0 # MSRV
2525

2626
steps:
27-
- uses: actions/checkout@v2
28-
- uses: actions-rs/toolchain@v1
27+
- uses: actions/checkout@v3
28+
- uses: dtolnay/rust-toolchain@master
2929
with:
30-
profile: minimal
3130
toolchain: ${{ matrix.rust }}
32-
override: true
31+
- uses: Swatinem/rust-cache@v2
3332
- name: Install openblas
3433
run: sudo apt-get install libopenblas-dev gfortran
3534
- run: ./scripts/all-tests.sh "$FEATURES" ${{ matrix.rust }}
@@ -45,20 +44,14 @@ jobs:
4544
target: i686-unknown-linux-gnu
4645

4746
steps:
48-
- uses: actions/checkout@v2
49-
- uses: actions-rs/toolchain@v1
47+
- uses: actions/checkout@v3
48+
- uses: dtolnay/rust-toolchain@master
5049
with:
51-
profile: minimal
5250
toolchain: ${{ matrix.rust }}
53-
target: ${{ matrix.target }}
54-
override: true
55-
- name: Cache cargo plugins
56-
uses: actions/cache@v1
57-
with:
58-
path: ~/.cargo/bin/
59-
key: ${{ runner.os }}-cargo-plugins
51+
targets: ${{ matrix.target }}
52+
- uses: Swatinem/rust-cache@v2
6053
- name: Install cross
61-
run: cargo install cross || true
54+
run: cargo install cross
6255
- run: ./scripts/cross-tests.sh "docs" ${{ matrix.rust }} ${{ matrix.target }}
6356

6457
clippy:
@@ -68,12 +61,10 @@ jobs:
6861
rust:
6962
- beta
7063
steps:
71-
- uses: actions/checkout@v2
72-
- uses: actions-rs/toolchain@v1
64+
- uses: actions/checkout@v3
65+
- uses: dtolnay/rust-toolchain@master
7366
with:
74-
profile: minimal
7567
toolchain: ${{ matrix.rust }}
76-
override: true
7768
components: clippy
69+
- uses: Swatinem/rust-cache@v2
7870
- run: cargo clippy --features docs
79-

Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,15 @@ rayon = ["rayon_", "std"]
7373

7474
matrixmultiply-threading = ["matrixmultiply/threading"]
7575

76-
[profile.release]
7776
[profile.bench]
7877
debug = true
78+
[profile.dev.package.numeric-tests]
79+
opt-level = 2
80+
[profile.test.package.numeric-tests]
81+
opt-level = 2
7982

8083
[workspace]
81-
members = ["ndarray-rand", "xtest-serialization", "xtest-blas"]
82-
exclude = ["xtest-numeric"]
84+
members = ["ndarray-rand", "xtest-serialization", "xtest-blas", "xtest-numeric"]
8385

8486
[package.metadata.release]
8587
no-dev-version = true

README-quick-start.md

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ You can use [play.integer32.com](https://play.integer32.com/) to immediately try
77

88
## The Basics
99

10-
Just create your first 2x3 floating-point ndarray
10+
You can create your first 2x3 floating-point ndarray as such:
1111
```rust
1212
use ndarray::prelude::*;
1313

@@ -24,7 +24,7 @@ fn main() {
2424
println!("{:?}", a);
2525
}
2626
```
27-
This code will create a simple array and output to stdout:
27+
This code will create a simple array, then print it to stdout as such:
2828
```
2929
[[1.0, 2.0, 3.0],
3030
[4.0, 5.0, 6.0]], shape=[2, 3], strides=[3, 1], layout=C (0x1), const ndim=2
@@ -34,8 +34,7 @@ This code will create a simple array and output to stdout:
3434

3535
### Element type and dimensionality
3636

37-
Now let's create more arrays. How about try make a zero array with dimension of (3, 2, 4)?
38-
37+
Now let's create more arrays. A common operation on matrices is to create a matrix full of 0's of certain dimensions. Let's try to do that with dimensions (3, 2, 4) using the `Array::zeros` function:
3938
```rust
4039
use ndarray::prelude::*;
4140
use ndarray::Array;
@@ -44,13 +43,13 @@ fn main() {
4443
println!("{:?}", a);
4544
}
4645
```
47-
gives
46+
Unfortunately, this code does not compile.
4847
```
4948
| let a = Array::zeros((3, 2, 4).f());
5049
| - ^^^^^^^^^^^^ cannot infer type for type parameter `A`
5150
```
52-
Note that the compiler needs to infer the element type and dimensionality from context. In this
53-
case the compiler failed to do that. Now we give it the type and let it infer dimensionality
51+
Indeed, note that the compiler needs to infer the element type and dimensionality from context only. In this
52+
case the compiler does not have enough information. To fix the code, we can explicitly give the element type through turbofish syntax, and let it infer the dimensionality type:
5453

5554
```rust
5655
use ndarray::prelude::*;
@@ -60,7 +59,7 @@ fn main() {
6059
println!("{:?}", a);
6160
}
6261
```
63-
and now it works:
62+
This code now compiles to what we wanted:
6463
```
6564
[[[0.0, 0.0, 0.0, 0.0],
6665
[0.0, 0.0, 0.0, 0.0]],
@@ -72,24 +71,11 @@ and now it works:
7271
[0.0, 0.0, 0.0, 0.0]]], shape=[3, 2, 4], strides=[1, 3, 6], layout=F (0x2), const ndim=3
7372
```
7473

75-
We can also specify its dimensionality
74+
We could also specify its dimensionality explicitly `Array::<f64, Ix3>::zeros(...)`, with`Ix3` standing for 3D array type. Phew! We achieved type safety. If you tried changing the code above to `Array::<f64, Ix3>::zeros((3, 2, 4, 5).f());`, which is not of dimension 3 anymore, Rust's type system would gracefully prevent you from compiling the code.
7675

77-
```rust
78-
use ndarray::prelude::*;
79-
use ndarray::{Array, Ix3};
80-
fn main() {
81-
let a = Array::<f64, Ix3>::zeros((3, 2, 4).f());
82-
println!("{:?}", a);
83-
}
84-
```
85-
`Ix3` stands for 3D array.
86-
87-
And now we are type checked. Try change the code above to `Array::<f64, Ix3>::zeros((3, 2, 4, 5).f());`
88-
and compile, see what happens.
89-
90-
### How about create array of different type and having different initial values?
76+
### Creating arrays with different initial values and/or different types
9177

92-
The [`from_elem`](http://docs.rs/ndarray/latest/ndarray/struct.ArrayBase.html#method.from_elem) method can be handy here:
78+
The [`from_elem`](http://docs.rs/ndarray/latest/ndarray/struct.ArrayBase.html#method.from_elem) method allows initializing an array of given dimension to a specific value of any type:
9379

9480
```rust
9581
use ndarray::{Array, Ix3};
@@ -99,7 +85,7 @@ fn main() {
9985
}
10086
```
10187

102-
### Some common create helper functions
88+
### Some common array initializing helper functions
10389
`linspace` - Create a 1-D array with 11 elements with values 0., …, 5.
10490
```rust
10591
use ndarray::prelude::*;
@@ -114,10 +100,11 @@ The output is:
114100
[0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0], shape=[11], strides=[1], layout=C | F (0x3), const ndim=1
115101
```
116102

117-
And there are also `range`, `logspace`, `ones`, `eye` and so on you can choose to use.
103+
Common array initializing methods include [`range`](https://docs.rs/ndarray/0.13.0/ndarray/struct.ArrayBase.html#method.range), [`logspace`](https://docs.rs/ndarray/0.13.0/ndarray/struct.ArrayBase.html#method.logspace), [`eye`](https://docs.rs/ndarray/0.13.0/ndarray/struct.ArrayBase.html#method.eye), [`ones`](https://docs.rs/ndarray/0.13.0/ndarray/struct.ArrayBase.html#method.ones)...
118104

119105
## Basic operations
120106

107+
Basic operations on arrays are all element-wise; you need to use specific methods for operations such as matrix multiplication (see later section).
121108
```rust
122109
use ndarray::prelude::*;
123110
use ndarray::Array;
@@ -136,16 +123,19 @@ fn main() {
136123
}
137124
```
138125

139-
Try remove all the `&` sign in front of `a` and `b`, does it still compile? Why?
140126

141-
Note that
127+
Note that (for any binary operator `@`):
142128
* `&A @ &A` produces a new `Array`
143129
* `B @ A` consumes `B`, updates it with the result, and returns it
144130
* `B @ &A` consumes `B`, updates it with the result, and returns it
145131
* `C @= &A` performs an arithmetic operation in place
146132

133+
Try removing all the `&` sign in front of `a` and `b` in the last example: it will not compile anymore because of those rules.
134+
147135
For more info checkout https://docs.rs/ndarray/latest/ndarray/struct.ArrayBase.html#arithmetic-operations
148136

137+
138+
149139
Some operations have `_axis` appended to the function name: they generally take in a parameter of type `Axis` as one of their inputs,
150140
such as `sum_axis`:
151141

@@ -237,7 +227,7 @@ The output is:
237227

238228
For more info about iteration see [Loops, Producers, and Iterators](https://docs.rs/ndarray/0.13.0/ndarray/struct.ArrayBase.html#loops-producers-and-iterators)
239229

240-
Let's try a 3D array with elements of type `isize`. This is how you index it:
230+
Let's try a iterating over a 3D array with elements of type `isize`. This is how you index it:
241231
```rust
242232
use ndarray::prelude::*;
243233

@@ -250,8 +240,8 @@ fn main() {
250240
[110,112,113]]
251241
];
252242

253-
let a = a.mapv(|a: isize| a.pow(1)); // numpy equivlant of `a ** 1`;
254-
// This line does nothing but illustrate mapv with isize type
243+
let a = a.mapv(|a: isize| a.pow(1)); // numpy equivalent of `a ** 1`;
244+
// This line does nothing except illustrating mapv with isize type
255245
println!("a -> \n{}\n", a);
256246

257247
println!("`a.slice(s![1, .., ..])` -> \n{}\n", a.slice(s![1, .., ..]));
@@ -461,11 +451,8 @@ s2 =
461451

462452
## Copies and Views
463453
### View, Ref or Shallow Copy
464-
As in Rust we have owner ship, so we cannot simply
465-
update an element of an array while we have a
466-
shared view of it. This will help us write more
467-
robust code.
468454

455+
Rust has ownership, so we cannot simply update an element of an array while we have a shared view of it. This brings guarantees & helps having more robust code.
469456
```rust
470457
use ndarray::prelude::*;
471458
use ndarray::{Array, Axis};
@@ -566,9 +553,9 @@ b clone of a =
566553
[2, 3]]
567554
```
568555

569-
Noticing that using `clone()` (or cloning) an `Array` type also copies the array's elements. It creates an independently owned array of the same type.
556+
Notice that using `clone()` (or cloning) an `Array` type also copies the array's elements. It creates an independently owned array of the same type.
570557

571-
Cloning an `ArrayView` does not clone or copy the underlying elements - it just clones the view reference (as it happens in Rust when cloning a `&` reference).
558+
Cloning an `ArrayView` does not clone or copy the underlying elements - it only clones the view reference (as it happens in Rust when cloning a `&` reference).
572559

573560
## Broadcasting
574561

@@ -600,7 +587,7 @@ fn main() {
600587

601588
See [.broadcast()](https://docs.rs/ndarray/latest/ndarray/struct.ArrayBase.html#method.broadcast) for a more detailed description.
602589

603-
And there is a short example of it:
590+
And here is a short example of it:
604591
```rust
605592
use ndarray::prelude::*;
606593

README.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ your `Cargo.toml`.
8383
- Enables parallel iterators, parallelized methods and ``par_azip!``.
8484
- Implies std
8585

86+
- ``approx``
87+
88+
- Implementations of traits from version 0.4 of the [`approx`] crate.
89+
90+
- ``approx-0_5``
91+
92+
- Implementations of traits from version 0.5 of the [`approx`] crate.
93+
8694
- ``blas``
8795

8896
- Enable transparent BLAS support for matrix multiplication.

scripts/all-tests.sh

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ set -e
66
FEATURES=$1
77
CHANNEL=$2
88

9+
if [ "$CHANNEL" = "1.51.0" ]; then
10+
cargo update --package rayon --precise 1.5.3
11+
cargo update --package rayon-core --precise 1.9.3
12+
cargo update --package serde --precise 1.0.156
13+
cargo update --package thiserror --precise 1.0.39
14+
cargo update --package once_cell --precise 1.14.0
15+
cargo update --package openblas-src --precise 0.10.5
16+
cargo update --package openblas-build --precise 0.10.5
17+
fi
18+
919
cargo build --verbose --no-default-features
1020
# Testing both dev and release profiles helps find bugs, especially in low level code
1121
cargo test --verbose --no-default-features
@@ -17,6 +27,6 @@ cargo test --manifest-path=ndarray-rand/Cargo.toml --features quickcheck --verbo
1727
cargo test --manifest-path=xtest-serialization/Cargo.toml --verbose
1828
cargo test --manifest-path=xtest-blas/Cargo.toml --verbose --features openblas-system
1929
cargo test --examples
20-
CARGO_TARGET_DIR=target/ cargo test --manifest-path=xtest-numeric/Cargo.toml --verbose
21-
CARGO_TARGET_DIR=target/ cargo test --manifest-path=xtest-numeric/Cargo.toml --verbose --features test_blas
30+
cargo test --manifest-path=xtest-numeric/Cargo.toml --verbose
31+
cargo test --manifest-path=xtest-numeric/Cargo.toml --verbose --features test_blas
2232
([ "$CHANNEL" != "nightly" ] || cargo bench --no-run --verbose --features "$FEATURES")

scripts/cross-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ cross build -v --features="$FEATURES" --target=$TARGET
1111
cross test -v --no-fail-fast --features="$FEATURES" --target=$TARGET
1212
cross test -v --no-fail-fast --target=$TARGET --manifest-path=ndarray-rand/Cargo.toml --features quickcheck
1313
cross test -v --no-fail-fast --target=$TARGET --manifest-path=xtest-serialization/Cargo.toml --verbose
14-
CARGO_TARGET_DIR=target/ cross test -v --no-fail-fast --target=$TARGET --manifest-path=xtest-numeric/Cargo.toml
14+
cross test -v --no-fail-fast --target=$TARGET --manifest-path=xtest-numeric/Cargo.toml

src/arraytraits.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ where
298298
{
299299
}
300300

301-
#[cfg(any(feature = "serde"))]
301+
#[cfg(feature = "serde")]
302302
// Use version number so we can add a packed format later.
303303
pub const ARRAY_FORMAT_VERSION: u8 = 1u8;
304304

src/dimension/dimension_trait.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ pub trait Dimension:
8383

8484
/// Compute the size of the dimension (number of elements)
8585
fn size(&self) -> usize {
86-
self.slice().iter().fold(1, |s, &a| s * a as usize)
86+
self.slice().iter().product()
8787
}
8888

8989
/// Compute the size while checking for overflow.
@@ -603,7 +603,7 @@ impl Dimension for Dim<[Ix; 2]> {
603603
fn size_checked(&self) -> Option<usize> {
604604
let m = get!(self, 0);
605605
let n = get!(self, 1);
606-
(m as usize).checked_mul(n as usize)
606+
m.checked_mul(n)
607607
}
608608

609609
#[inline]
@@ -728,7 +728,7 @@ impl Dimension for Dim<[Ix; 3]> {
728728
let m = get!(self, 0);
729729
let n = get!(self, 1);
730730
let o = get!(self, 2);
731-
m as usize * n as usize * o as usize
731+
m * n * o
732732
}
733733

734734
#[inline]

src/dimension/dynindeximpl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl<T: PartialEq> PartialEq for IxDynRepr<T> {
9696
match (self, rhs) {
9797
(&IxDynRepr::Inline(slen, ref sarr), &IxDynRepr::Inline(rlen, ref rarr)) => {
9898
slen == rlen
99-
&& (0..CAP as usize)
99+
&& (0..CAP)
100100
.filter(|&i| i < slen as usize)
101101
.all(|i| sarr[i] == rarr[i])
102102
}

src/dimension/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ mod sequence;
4747
/// Calculate offset from `Ix` stride converting sign properly
4848
#[inline(always)]
4949
pub fn stride_offset(n: Ix, stride: Ix) -> isize {
50-
(n as isize) * ((stride as Ixs) as isize)
50+
(n as isize) * (stride as Ixs)
5151
}
5252

5353
/// Check whether the given `dim` and `stride` lead to overlapping indices

src/doc/ndarray_for_numpy_users/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@
258258
//! `a[-5:]` or `a[-5:, :]` | [`a.slice(s![-5.., ..])`][.slice()] or [`a.slice_axis(Axis(0), Slice::from(-5..))`][.slice_axis()] | get the last 5 rows of a 2-D array
259259
//! `a[:3, 4:9]` | [`a.slice(s![..3, 4..9])`][.slice()] | columns 4, 5, 6, 7, and 8 of the first 3 rows
260260
//! `a[1:4:2, ::-1]` | [`a.slice(s![1..4;2, ..;-1])`][.slice()] | rows 1 and 3 with the columns in reverse order
261+
//! `a.take([4, 2])` | `a.select(Axis(0), &[4, 2])` | rows 4 and 2 of the array
261262
//!
262263
//! ## Shape and strides
263264
//!
@@ -531,6 +532,8 @@
531532
//! ------|-----------|------
532533
//! `a[:] = 3.` | [`a.fill(3.)`][.fill()] | set all array elements to the same scalar value
533534
//! `a[:] = b` | [`a.assign(&b)`][.assign()] | copy the data from array `b` into array `a`
535+
//! `a[:5, 2] = 3.` | [`a.slice_mut(s![..5, 2]).fill(3.)`][.fill()] | set a portion of the array to the same scalar value
536+
//! `a[:5, 2] = b` | [`a.slice_mut(s![..5, 2]).assign(&b)`][.assign()] | copy the data from array `b` into part of array `a`
534537
//! `np.concatenate((a,b), axis=1)` | [`concatenate![Axis(1), a, b]`][concatenate!] or [`concatenate(Axis(1), &[a.view(), b.view()])`][concatenate()] | concatenate arrays `a` and `b` along axis 1
535538
//! `np.stack((a,b), axis=1)` | [`stack![Axis(1), a, b]`][stack!] or [`stack(Axis(1), vec![a.view(), b.view()])`][stack()] | stack arrays `a` and `b` along axis 1
536539
//! `a[:,np.newaxis]` or `np.expand_dims(a, axis=1)` | [`a.slice(s![.., NewAxis])`][.slice()] or [`a.insert_axis(Axis(1))`][.insert_axis()] | create an view of 1-D array `a`, inserting a new axis 1

0 commit comments

Comments
 (0)