Skip to content

Commit 6eed17d

Browse files
committed
Adds documentation to ArrayRef
1 parent 775f06b commit 6eed17d

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

src/lib.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,74 @@ pub struct LayoutRef<A, D>
14071407
strides: D,
14081408
}
14091409

1410+
/// A reference to an *n*-dimensional array whose data is safe to read and write.
1411+
///
1412+
/// This type's relationship to [`ArrayBase`] can be thought of a bit like the
1413+
/// relationship between [`Vec`] and [`std::slice`]: it represents a look into the
1414+
/// array, and is the [`Deref`](std::ops::Deref) target for owned, shared, and viewed
1415+
/// arrays. Most functionality is implemented on `ArrayRef`, and most functions
1416+
/// should take `&ArrayRef` instead of `&ArrayBase`.
1417+
///
1418+
/// ## Relationship to Views
1419+
/// `ArrayRef` and [`ArrayView`] are very similar types: they both represent a
1420+
/// "look" into an array. There is one key difference: views have their own
1421+
/// shape and strides, while `ArrayRef` just points to the shape and strides of
1422+
/// whatever array it came from.
1423+
///
1424+
/// As an example, let's write a function that takes an array, trims it
1425+
/// down to a square in-place, and then returns the sum:
1426+
/// ```rust
1427+
/// use std::cmp;
1428+
/// use std::ops::Add;
1429+
///
1430+
/// use ndarray::{ArrayRef2, array, s};
1431+
/// use num_traits::Zero;
1432+
///
1433+
/// fn square_and_sum<A>(arr: &mut ArrayRef2<A>) -> A
1434+
/// where A: Clone + Add<Output = A> + Zero
1435+
/// {
1436+
/// let side_len = cmp::min(arr.nrows(), arr.ncols());
1437+
/// arr.slice_collapse(s![..side_len, ..side_len]);
1438+
/// arr.sum()
1439+
/// }
1440+
///
1441+
/// let mut arr = array![
1442+
/// [ 1, 2, 3],
1443+
/// [ 4, 5, 6],
1444+
/// [ 7, 8, 9],
1445+
/// [10, 11, 12]
1446+
/// ];
1447+
/// // Take a view of the array, excluding the first column
1448+
/// let mut view = arr.slice_mut(s![.., 1..]);
1449+
/// let sum_view = square_and_sum(&mut view);
1450+
/// assert_eq!(sum_view, 16);
1451+
/// assert_eq!(view.ncols(), 2usize); // The view has changed shape...
1452+
/// assert_eq!(view.nrows(), 2usize);
1453+
/// assert_eq!(arr.ncols(), 3usize); // ... but the original array has not
1454+
/// assert_eq!(arr.nrows(), 4usize);
1455+
///
1456+
/// let sum_all = square_and_sum(&mut arr);
1457+
/// assert_eq!(sum_all, 45);
1458+
/// assert_eq!(arr.ncols(), 3usize); // Now the original array has changed shape
1459+
/// assert_eq!(arr.nrows(), 3usize); // because we passed it directly to the function
1460+
/// ```
1461+
/// Critically, we can call the same function on both the view and the array itself.
1462+
/// We can see that, because the view has its own shape and strides, "squaring" it does
1463+
/// not affect the shape of the original array. Those only change when we pass the array
1464+
/// itself into the function.
1465+
///
1466+
/// Also notice that the output of `slice_mut` is a *view*, not an `ArrayRef`.
1467+
/// This is where the analogy to `Vec`/`slice` breaks down a bit: due to limitations of
1468+
/// the Rust language, `ArrayRef` *cannot* have a different shape / stride from the
1469+
/// array from which it is dereferenced. So slicing still produces an `ArrayView`,
1470+
/// not an `ArrayRef`.
1471+
///
1472+
/// ## Uniqueness
1473+
/// `ndarray` has copy-on-write shared data; see [`ArcArray`], for example.
1474+
/// When a copy-on-write array is passed to a function that takes `ArrayRef` as mutable
1475+
/// (i.e., `&mut ArrayRef`, like above), that array will be un-shared when it is dereferenced
1476+
/// into `ArrayRef`. In other words, having a `&mut ArrayRef` guarantees that the underlying
1477+
/// data is un-shared and safe to write to.
14101478
#[repr(transparent)]
14111479
pub struct ArrayRef<A, D>(LayoutRef<A, D>);
14121480

src/linalg/impl_linalg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ where D: Dimension
402402
}
403403
}
404404

405-
// mat_mul_impl uses ArrayView arguments to send all array kinds into
405+
// mat_mul_impl uses ArrayRef arguments to send all array kinds into
406406
// the same instantiated implementation.
407407
#[cfg(not(feature = "blas"))]
408408
use self::mat_mul_general as mat_mul_impl;

0 commit comments

Comments
 (0)