Skip to content

Commit f77ad96

Browse files
committed
Adds documentation to ArrayRef
1 parent 0cd4334 commit f77ad96

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
@@ -1402,6 +1402,74 @@ pub struct LayoutRef<A, D>
14021402
strides: D,
14031403
}
14041404

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

src/linalg/impl_linalg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ where D: Dimension
399399
}
400400
}
401401

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

0 commit comments

Comments
 (0)