Skip to content

Commit

Permalink
Update to ndarray 0.13 (#560)
Browse files Browse the repository at this point in the history
  • Loading branch information
danwilhelm authored and AndyGauge committed Dec 17, 2019
1 parent 3fcb08b commit d7c2911
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 77 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ log4rs = "0.8"
memmap = "0.7"
mime = "0.3"
nalgebra = "0.16.12"
ndarray = "0.12"
ndarray = { version = "0.13", features = ["approx"] }
num = "0.2"
num_cpus = "1.8"
percent-encoding = "2.1"
Expand Down
4 changes: 2 additions & 2 deletions src/science/mathematics/linear_algebra.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Linear Algebra

{{#include linear_algebra/vector-sum.md}}
{{#include linear_algebra/vector-norm.md}}
{{#include linear_algebra/add-matrices.md}}
{{#include linear_algebra/multiply-matrices.md}}
{{#include linear_algebra/multiply-scalar-vector-matrix.md}}
{{#include linear_algebra/vector-comparison.md}}
{{#include linear_algebra/vector-norm.md}}
{{#include linear_algebra/invert-matrix.md}}

{{#include ../../links.md}}
12 changes: 10 additions & 2 deletions src/science/mathematics/linear_algebra/add-matrices.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
## Adding matrices
[![ndarray-badge]][ndarray] [![cat-science-badge]][cat-science]

Creates two matrices with [`ndarray::arr2`] and adds them together.
Creates two 2-D matrices with [`ndarray::arr2`] and sums them element-wise.

Note the sum is computed as `let sum = &a + &b`. The `&` operator is used to avoid consuming `a` and `b`, making them available later for display. A new array is created containing their sum.

```rust
extern crate ndarray;
Expand All @@ -15,7 +17,13 @@ fn main() {
let b = arr2(&[[6, 5, 4],
[3, 2, 1]]);

println!("Sum: {}", a + b);
let sum = &a + &b;

println!("{}", a);
println!("+");
println!("{}", b);
println!("=");
println!("{}", sum);
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@
[![ndarray-badge]][ndarray] [![cat-science-badge]][cat-science]

Creates a 1-D array (vector) with [`ndarray::arr1`] and a 2-D array (matrix)
with [`ndarray::arr2`]. First, a scalar is multiplied by the vector to get
with [`ndarray::arr2`].

First, a scalar is multiplied by the vector to get
another vector. Then, the matrix is multiplied by the new vector with
[`ndarray::Array2::dot`]. (`dot` performs matrix multiplication, while the `*`
operator performs element-wise multiplication.) In `ndarray`, 1-D arrays can be
interpreted as either row or column vectors depending on context. If
representing the orientation of a vector is important, a 2-D array with one row
or one column must be used instead. In this example, the vector is a 1-D array
on the right-hand side, so `dot` handles it as a column vector.
[`ndarray::Array2::dot`]. (Matrix multiplication is performed using `dot`, while
the `*` operator performs element-wise multiplication.)

In `ndarray`, 1-D arrays can be interpreted as either row or column vectors
depending on context. If representing the orientation of a vector is important,
a 2-D array with one row or one column must be used instead. In this example,
the vector is a 1-D array on the right-hand side, so `dot` handles it as a column
vector.

```rust
extern crate ndarray;
Expand All @@ -32,6 +36,6 @@ fn main() {
}
```

[`ndarray::Array2::dot`]: https://docs.rs/ndarray/*/ndarray/struct.ArrayBase.html#method.dot-1
[`ndarray::arr1`]: https://docs.rs/ndarray/*/ndarray/fn.arr1.html
[`ndarray::arr2`]: https://docs.rs/ndarray/*/ndarray/fn.arr2.html
[`ndarray::Array2::dot`]: https://docs.rs/ndarray/*/ndarray/struct.ArrayBase.html#method.dot-1
50 changes: 50 additions & 0 deletions src/science/mathematics/linear_algebra/vector-comparison.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## Vector comparison
[![ndarray-badge]][ndarray]

The [ndarray] crate supports a number of ways to create arrays -- this recipe creates
[`ndarray::Array`]s from `std::Vec` using `from`. Then, it sums the arrays element-wise.

This recipe contains an example of comparing two floating-point vectors element-wise.
Floating-point numbers are often stored inexactly, making exact comparisons difficult.
However, the [`assert_abs_diff_eq!`] macro from the [`approx`] crate allows for convenient
element-wise comparisons. To use the `approx` crate with `ndarray`, the `approx`
feature must be added to the `ndarray` dependency in `Cargo.toml`. For example,
`ndarray = { version = "0.13", features = ["approx"] }`.

This recipe also contains additional ownership examples. Here, `let z = a + b` consumes
`a` and `b`, updates `a` with the result, then moves ownership to `z`. Alternatively,
`let w = &c + &d` creates a new vector without consuming `c` or `d`, allowing
their modification later. See [Binary Operators With Two Arrays] for additional detail.

```rust
#[macro_use(assert_abs_diff_eq)]
extern crate approx;
extern crate ndarray;

use ndarray::Array;

fn main() {
let a = Array::from(vec![1., 2., 3., 4., 5.]);
let b = Array::from(vec![5., 4., 3., 2., 1.]);
let mut c = Array::from(vec![1., 2., 3., 4., 5.]);
let mut d = Array::from(vec![5., 4., 3., 2., 1.]);

let z = a + b;
let w = &c + &d;

assert_abs_diff_eq!(z, Array::from(vec![6., 6., 6., 6., 6.]));

println!("c = {}", c);
c[0] = 10.;
d[1] = 10.;

assert_abs_diff_eq!(w, Array::from(vec![6., 6., 6., 6., 6.]));

}
```

[`approx`]: https://docs.rs/approx/*/approx/index.html
[`assert_abs_diff_eq!`]: https://docs.rs/approx/*/approx/macro.assert_abs_diff_eq.html
[Binary Operators With Two Arrays]: https://docs.rs/ndarray/*/ndarray/struct.ArrayBase.html#binary-operators-with-two-arrays
[ndarray]: https://docs.rs/crate/ndarray/*
[`ndarray::Array`]: https://docs.rs/ndarray/*/ndarray/struct.ArrayBase.html
30 changes: 17 additions & 13 deletions src/science/mathematics/linear_algebra/vector-norm.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
## Vector Norm
## Vector norm
[![ndarray-badge]][ndarray]

This recipe demonstrates use of the [`Array1`] type, [`ArrayView1`] type,
[`fold`] method, and [`dot`] method in computing the [l1] and [l2] norms of a
given vector. The l2 norm calculation is the simpler of the two, as it is the
square root of the dot product of a vector with itself, shown in the function
`l2_norm`. The l1 norm, shown in the function `l1_norm`, is computed by a `fold`
given vector.
+ The `l2_norm` function is the simpler of the two, as it computes the
square root of the dot product of a vector with itself.
+ The `l1_norm` function is computed by a `fold`
operation that sums the absolute values of the elements. (This could also be
performed with `x.mapv(f64::abs).scalar_sum()`, but that would allocate a new
array for the result of the `mapv`.)

Note that both `l1_norm` and `l2_norm` take the [`ArrayView1`] type. This recipe
considers vector norms, so the norm functions only need to accept one
dimensional views (hence [`ArrayView1`]). While the functions could take a
considers vector norms, so the norm functions only need to accept one-dimensional
views (hence [`ArrayView1`]). While the functions could take a
parameter of type `&Array1<f64>` instead, that would require the caller to have
a reference to an owned array, which is more restrictive than just having access
to a view (since a view can be created from any array or view, not just an owned
array). The most convenient argument type for the caller would be
`&ArrayBase<S, Ix1> where S: Data`, because then the caller could use `&array`
or `&view` instead of `x.view()`. If the function is part of your public API,
that may be a better choice for the benefit of your users, but for internal
functions, the more concise `ArrayView1<f64>` may be preferable.
array).

`Array` and `ArrayView` are both type aliases for `ArrayBase`. So, the most
general argument type for the caller would be `&ArrayBase<S, Ix1> where S: Data`,
because then the caller could use `&array` or `&view` instead of `x.view()`.
If the function is part of a public API, that may be a better choice for the
benefit of users. For internal functions, the more concise `ArrayView1<f64>`
may be preferable.

```rust
#[macro_use(array)]
Expand Down Expand Up @@ -50,9 +54,9 @@ fn main() {
}
```

[l1]: http://mathworld.wolfram.com/L1-Norm.html
[l2]: http://mathworld.wolfram.com/L2-Norm.html
[`Array1`]: https://docs.rs/ndarray/*/ndarray/type.Array1.html
[`ArrayView1`]: https://docs.rs/ndarray/*/ndarray/type.ArrayView1.html
[`dot`]: https://docs.rs/ndarray/*/ndarray/struct.ArrayBase.html#method.dot
[`fold`]: https://docs.rs/ndarray/*/ndarray/struct.ArrayBase.html#method.fold
[l1]: http://mathworld.wolfram.com/L1-Norm.html
[l2]: http://mathworld.wolfram.com/L2-Norm.html
51 changes: 0 additions & 51 deletions src/science/mathematics/linear_algebra/vector-sum.md

This file was deleted.

0 comments on commit d7c2911

Please sign in to comment.