use libnum::{Zero, One, Float};
use std::isize;
use std::mem;
use imp_prelude::*;
use StrideShape;
use dimension;
use linspace;
use error::{self, ShapeError};
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 {
if mem::size_of::<A>() == 0 {
assert!(
v.len() <= isize::MAX as usize,
"Length must fit in `isize`.",
);
}
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
}
}
#[cfg(not(debug_assertions))]
macro_rules! size_of_shape_checked_unwrap {
($dim:expr) => {
match dimension::size_of_shape_checked($dim) {
Ok(sz) => sz,
Err(_) => panic!("ndarray: Shape too large, product of non-zero axis lengths overflows isize"),
}
}
}
#[cfg(debug_assertions)]
macro_rules! size_of_shape_checked_unwrap {
($dim:expr) => {
match dimension::size_of_shape_checked($dim) {
Ok(sz) => sz,
Err(_) => panic!(
"ndarray: Shape too large, product of non-zero axis lengths \
overflows isize in shape {:?}",
$dim
),
}
}
}
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_of_shape_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 ones<Sh>(shape: Sh) -> Self
where A: Clone + One,
Sh: ShapeBuilder<Dim=D>,
{
Self::from_elem(shape, A::one())
}
pub fn default<Sh>(shape: Sh) -> Self
where A: Default,
Sh: ShapeBuilder<Dim=D>,
{
let shape = shape.into_shape();
let size = size_of_shape_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_of_shape_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>
{
let dim = shape.dim;
let strides = shape.strides;
if shape.custom {
dimension::can_index_slice(&v, &dim, &strides)?;
} else {
dimension::can_index_slice_not_custom::<A, _>(&v, &dim)?;
if dim.size() != 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)
}
unsafe fn from_vec_dim_stride_unchecked(dim: D, strides: D, mut v: Vec<A>)
-> Self
{
debug_assert!(dimension::can_index_slice(&v, &dim, &strides).is_ok());
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_of_shape_checked_unwrap!(&shape.dim);
let mut v = Vec::with_capacity(size);
v.set_len(size);
Self::from_shape_vec_unchecked(shape, v)
}
}