Skip to content

Commit ffe6118

Browse files
authored
Merge pull request #343 from bluss/into-dimensionality
Method .into_dimensionality::<Dim>()
2 parents 859d1f0 + 7d87ac0 commit ffe6118

File tree

4 files changed

+78
-9
lines changed

4 files changed

+78
-9
lines changed

src/dimension/dimension_trait.rs

+19-7
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,19 @@ pub trait Dimension : Clone + Eq + Debug + Send + Sync + Default +
376376
IxDyn(self.slice())
377377
}
378378

379+
#[doc(hidden)]
380+
fn from_dimension<D2: Dimension>(d: &D2) -> Option<Self> {
381+
let mut s = Self::default();
382+
if s.ndim() == d.ndim() {
383+
for i in 0..d.ndim() {
384+
s[i] = d[i];
385+
}
386+
Some(s)
387+
} else {
388+
None
389+
}
390+
}
391+
379392
#[doc(hidden)]
380393
fn try_remove_axis(&self, axis: Axis) -> Self::Smaller;
381394

@@ -790,14 +803,9 @@ impl Dimension for IxDyn
790803
self
791804
}
792805

806+
#[inline]
793807
fn zero_index(&self) -> Self {
794-
const ZEROS: &'static [usize] = &[0; 4];
795-
let n = self.ndim();
796-
if n <= ZEROS.len() {
797-
Dim(&ZEROS[..n])
798-
} else {
799-
Dim(vec![0; n])
800-
}
808+
IxDyn::zeros(self.ndim())
801809
}
802810

803811
#[inline]
@@ -808,6 +816,10 @@ impl Dimension for IxDyn
808816
self.clone()
809817
}
810818
}
819+
820+
fn from_dimension<D2: Dimension>(d: &D2) -> Option<Self> {
821+
Some(IxDyn(d.slice()))
822+
}
811823
private_impl!{}
812824
}
813825

src/dimension/dynindeximpl.rs

+13
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,16 @@ impl RemoveAxis for Dim<IxDynImpl> {
209209
Dim::new(self.ix().remove(axis.index()))
210210
}
211211
}
212+
213+
impl IxDyn {
214+
/// Create a new dimension value with `n` axes, all zeros
215+
#[inline]
216+
pub fn zeros(n: usize) -> IxDyn {
217+
const ZEROS: &'static [usize] = &[0; 4];
218+
if n <= ZEROS.len() {
219+
Dim(&ZEROS[..n])
220+
} else {
221+
Dim(vec![0; n])
222+
}
223+
}
224+
}

src/impl_methods.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use imp_prelude::*;
1717
use arraytraits;
1818
use dimension;
1919
use iterators;
20-
use error::{self, ShapeError};
20+
use error::{self, ShapeError, ErrorKind};
2121
use super::zipsl;
2222
use super::ZipExt;
2323
use dimension::IntoDimension;
@@ -1061,6 +1061,35 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
10611061
}
10621062
}
10631063

1064+
/// Convert an array or array view to another with the same type, but
1065+
/// different dimensionality type. Errors if the dimensions don't agree.
1066+
///
1067+
/// ```
1068+
/// use ndarray::{ArrayD, Ix2, IxDyn};
1069+
///
1070+
/// // Create a dynamic dimensionality array and convert it to an Array2
1071+
/// // (Ix2 dimension type).
1072+
///
1073+
/// let array = ArrayD::<f64>::zeros(IxDyn(&[10, 10]));
1074+
///
1075+
/// assert!(array.into_dimensionality::<Ix2>().is_ok());
1076+
/// ```
1077+
pub fn into_dimensionality<D2>(self) -> Result<ArrayBase<S, D2>, ShapeError>
1078+
where D2: Dimension
1079+
{
1080+
if let Some(dim) = D2::from_dimension(&self.dim) {
1081+
if let Some(strides) = D2::from_dimension(&self.strides) {
1082+
return Ok(ArrayBase {
1083+
data: self.data,
1084+
ptr: self.ptr,
1085+
dim: dim,
1086+
strides: strides,
1087+
});
1088+
}
1089+
}
1090+
Err(ShapeError::from_kind(ErrorKind::IncompatibleShape))
1091+
}
1092+
10641093
/// Act like a larger size and/or shape array by *broadcasting*
10651094
/// into a larger shape, if possible.
10661095
///

tests/ixdyn.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
extern crate ndarray;
33

44
use ndarray::Array;
5-
use ndarray::Ix3;
5+
use ndarray::{Ix0, Ix1, Ix2, Ix3, IxDyn};
66
use ndarray::IntoDimension;
77
use ndarray::ShapeBuilder;
88

@@ -146,3 +146,18 @@ fn test_0_add_broad() {
146146
assert_eq!(b[0], 6.);
147147
assert_eq!(b[1], 7.);
148148
}
149+
150+
#[test]
151+
fn test_into_dimension() {
152+
let a = Array::linspace(0., 41., 6 * 7).into_shape((6, 7)).unwrap();
153+
let a2 = a.clone().into_shape(IxDyn(&[6, 7])).unwrap();
154+
let b = a2.clone().into_dimensionality::<Ix2>().unwrap();
155+
assert_eq!(a, b);
156+
157+
assert!(a2.clone().into_dimensionality::<Ix0>().is_err());
158+
assert!(a2.clone().into_dimensionality::<Ix1>().is_err());
159+
assert!(a2.clone().into_dimensionality::<Ix3>().is_err());
160+
161+
let c = a2.clone().into_dimensionality::<IxDyn>().unwrap();
162+
assert_eq!(a2, c);
163+
}

0 commit comments

Comments
 (0)