diff --git a/src/impl_constructors.rs b/src/impl_constructors.rs index 2355a1249..f8589f595 100644 --- a/src/impl_constructors.rs +++ b/src/impl_constructors.rs @@ -171,6 +171,29 @@ where } eye } + + /// Create a 2D matrix from its diagonal + /// + /// **Panics** if `diag.len() * diag.len()` would overflow `isize`. + /// + /// ```rust + /// use ndarray::{Array2, arr1, arr2}; + /// + /// let diag = arr1(&[1, 2]); + /// let array = Array2::from_diag(&diag); + /// assert_eq!(array, arr2(&[[1, 0], [0, 2]])); + /// ``` + pub fn from_diag(diag: &ArrayBase) -> Self + where + A: Clone + Zero, + S: DataMut, + S2: Data, + { + let n = diag.len(); + let mut arr = Self::zeros((n, n)); + arr.diag_mut().assign(&diag); + arr + } } #[cfg(not(debug_assertions))] diff --git a/tests/array.rs b/tests/array.rs index 4a86b3cba..70802e2c5 100644 --- a/tests/array.rs +++ b/tests/array.rs @@ -1950,6 +1950,20 @@ fn test_array_clone_same_view() { assert_eq!(a, b); } +#[test] +fn test_array2_from_diag() { + let diag = arr1(&[0, 1, 2]); + let x = Array2::from_diag(&diag); + let x_exp = arr2(&[[0, 0, 0], [0, 1, 0], [0, 0, 2]]); + assert_eq!(x, x_exp); + + // check 0 length array + let diag = Array1::::zeros(0); + let x = Array2::from_diag(&diag); + assert_eq!(x.ndim(), 2); + assert_eq!(x.shape(), [0, 0]); +} + #[test] fn array_macros() { // array