use libnum::{Zero, One, Float};
use imp_prelude::*;
use StrideShape;
use dimension;
use linspace;
use error::{self, ShapeError, ErrorKind};
use indices;
use indexes;
use iterators::{to_vec, to_vec_mapped};
impl<S, A> ArrayBase<S, Ix1>
where S: DataOwned<Elem=A>,
{
pub fn from_vec(v: Vec<A>) -> Self {
unsafe { Self::from_shape_vec_unchecked(v.len() as Ix, v) }
}
pub fn from_iter<I>(iterable: I) -> Self
where I: IntoIterator<Item=A>
{
Self::from_vec(iterable.into_iter().collect())
}
pub fn linspace(start: A, end: A, n: usize) -> Self
where A: Float,
{
Self::from_vec(to_vec(linspace::linspace(start, end, n)))
}
pub fn range(start: A, end: A, step: A) -> Self
where A: Float,
{
Self::from_vec(to_vec(linspace::range(start, end, step)))
}
}
impl<S, A> ArrayBase<S, Ix2>
where S: DataOwned<Elem=A>,
{
pub fn eye(n: Ix) -> Self
where S: DataMut,
A: Clone + Zero + One,
{
let mut eye = Self::zeros((n, n));
for a_ii in eye.diag_mut() {
*a_ii = A::one();
}
eye
}
}
macro_rules! size_checked_unwrap {
($dim:expr) => {
match $dim.size_checked() {
Some(sz) => sz,
None => panic!("ndarray: Shape too large, number of elements overflows usize"),
}
}
}
impl<S, A, D> ArrayBase<S, D>
where S: DataOwned<Elem=A>,
D: Dimension,
{
pub fn from_elem<Sh>(shape: Sh, elem: A) -> Self
where A: Clone,
Sh: ShapeBuilder<Dim=D>,
{
let shape = shape.into_shape();
let size = size_checked_unwrap!(shape.dim);
let v = vec![elem; size];
unsafe { Self::from_shape_vec_unchecked(shape, v) }
}
pub fn zeros<Sh>(shape: Sh) -> Self
where A: Clone + Zero,
Sh: ShapeBuilder<Dim=D>,
{
Self::from_elem(shape, A::zero())
}
pub fn default<Sh>(shape: Sh) -> Self
where A: Default,
Sh: ShapeBuilder<Dim=D>,
{
let shape = shape.into_shape();
let size = size_checked_unwrap!(shape.dim);
let v = to_vec((0..size).map(|_| A::default()));
unsafe { Self::from_shape_vec_unchecked(shape, v) }
}
pub fn from_shape_fn<Sh, F>(shape: Sh, f: F) -> Self
where Sh: ShapeBuilder<Dim=D>,
F: FnMut(D::Pattern) -> A,
{
let shape = shape.into_shape();
let _ = size_checked_unwrap!(shape.dim);
if shape.is_c {
let v = to_vec_mapped(indices(shape.dim.clone()).into_iter(), f);
unsafe { Self::from_shape_vec_unchecked(shape, v) }
} else {
let dim = shape.dim.clone();
let v = to_vec_mapped(indexes::indices_iter_f(dim).into_iter(), f);
unsafe { Self::from_shape_vec_unchecked(shape, v) }
}
}
pub fn from_shape_vec<Sh>(shape: Sh, v: Vec<A>) -> Result<Self, ShapeError>
where Sh: Into<StrideShape<D>>,
{
Self::from_shape_vec_impl(shape.into(), v)
}
fn from_shape_vec_impl(shape: StrideShape<D>, v: Vec<A>) -> Result<Self, ShapeError>
{
if shape.custom {
Self::from_vec_dim_stride(shape.dim, shape.strides, v)
} else {
let dim = shape.dim;
let strides = shape.strides;
if dim.size_checked() != Some(v.len()) {
return Err(error::incompatible_shapes(&Ix1(v.len()), &dim));
}
unsafe { Ok(Self::from_vec_dim_stride_unchecked(dim, strides, v)) }
}
}
pub unsafe fn from_shape_vec_unchecked<Sh>(shape: Sh, v: Vec<A>) -> Self
where Sh: Into<StrideShape<D>>,
{
let shape = shape.into();
Self::from_vec_dim_stride_unchecked(shape.dim, shape.strides, v)
}
fn from_vec_dim_stride(dim: D, strides: D, v: Vec<A>)
-> Result<Self, ShapeError>
{
dimension::can_index_slice(&v, &dim, &strides).map(|_| {
unsafe {
Self::from_vec_dim_stride_unchecked(dim, strides, v)
}
})
}
unsafe fn from_vec_dim_stride_unchecked(dim: D, strides: D, mut v: Vec<A>)
-> Self
{
debug_assert!(match dimension::can_index_slice(&v, &dim, &strides) {
Ok(_) => true,
Err(ref e) => match e.kind() {
ErrorKind::OutOfBounds => false,
ErrorKind::RangeLimited => false,
_ => true,
}
});
ArrayBase {
ptr: v.as_mut_ptr(),
data: DataOwned::new(v),
strides: strides,
dim: dim
}
}
pub unsafe fn uninitialized<Sh>(shape: Sh) -> Self
where A: Copy,
Sh: ShapeBuilder<Dim=D>,
{
let shape = shape.into_shape();
let size = size_checked_unwrap!(shape.dim);
let mut v = Vec::with_capacity(size);
v.set_len(size);
Self::from_shape_vec_unchecked(shape, v)
}
}