Skip to content

Commit e1fef22

Browse files
committed
add some simple constructors for fortran ordered arrays
1 parent 1176bde commit e1fef22

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

src/dimension.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,26 @@ pub unsafe trait Dimension : Clone + Eq {
152152
strides
153153
}
154154

155+
fn fortran_strides(&self) -> Self {
156+
// Compute fortran array strides
157+
// Shape (a, b, c) => Give strides (1, a, a * b)
158+
let mut strides = self.clone();
159+
{
160+
let mut it = strides.slice_mut().iter_mut();
161+
// Set first element to 1
162+
for rs in it.by_ref() {
163+
*rs = 1;
164+
break;
165+
}
166+
let mut cum_prod = 1;
167+
for (rs, dim) in it.zip(self.slice().iter()) {
168+
cum_prod *= *dim;
169+
*rs = cum_prod;
170+
}
171+
}
172+
strides
173+
}
174+
155175
#[inline]
156176
fn first_index(&self) -> Option<Self>
157177
{

src/lib.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,12 +612,43 @@ impl<S, A, D> ArrayBase<S, D>
612612
}
613613
}
614614

615+
/// Create an array with copies of `elem`, dimension `dim` and fortran
616+
/// ordering.
617+
///
618+
/// ```
619+
/// use ndarray::Array;
620+
/// use ndarray::arr3;
621+
///
622+
/// let a = Array::from_elem_f((2, 2, 2), 1.);
623+
///
624+
/// assert!(
625+
/// a == arr3(&[[[1., 1.],
626+
/// [1., 1.]],
627+
/// [[1., 1.],
628+
/// [1., 1.]]])
629+
/// );
630+
/// assert!(a.strides() == &[1, 2, 4]);
631+
/// ```
632+
pub fn from_elem_f(dim: D, elem: A) -> ArrayBase<S, D> where A: Clone
633+
{
634+
let v = vec![elem; dim.size()];
635+
unsafe {
636+
Self::from_vec_dim_f(dim, v)
637+
}
638+
}
639+
615640
/// Create an array with zeros, dimension `dim`.
616641
pub fn zeros(dim: D) -> ArrayBase<S, D> where A: Clone + libnum::Zero
617642
{
618643
Self::from_elem(dim, libnum::zero())
619644
}
620645

646+
/// Create an array with zeros, dimension `dim` and fortran ordering.
647+
pub fn zeros_f(dim: D) -> ArrayBase<S, D> where A: Clone + libnum::Zero
648+
{
649+
Self::from_elem_f(dim, libnum::zero())
650+
}
651+
621652
/// Create an array with default values, dimension `dim`.
622653
pub fn default(dim: D) -> ArrayBase<S, D>
623654
where A: Default
@@ -642,6 +673,22 @@ impl<S, A, D> ArrayBase<S, D>
642673
}
643674
}
644675

676+
/// Create an array from a vector (with no allocation needed),
677+
/// using fortran ordering to interpret the data.
678+
///
679+
/// Unsafe because dimension is unchecked, and must be correct.
680+
pub unsafe fn from_vec_dim_f(dim: D, mut v: Vec<A>) -> ArrayBase<S, D>
681+
{
682+
debug_assert!(dim.size() == v.len());
683+
ArrayBase {
684+
ptr: v.as_mut_ptr(),
685+
data: DataOwned::new(v),
686+
strides: dim.fortran_strides(),
687+
dim: dim
688+
}
689+
}
690+
691+
645692
/// Create an array from a vector and interpret it according to the
646693
/// provided dimensions and strides. No allocation needed.
647694
///

0 commit comments

Comments
 (0)