#[cfg(feature = "abomonation-serialize")] use std::io::{Result as IOResult, Write}; #[cfg(all(feature = "alloc", not(feature = "std")))] use alloc::vec::Vec; use crate::allocator::InnerAllocator; use crate::base::constraint::{SameNumberOfRows, ShapeConstraint}; use crate::base::default_allocator::DefaultAllocator; use crate::base::dimension::{Dim, DimName, Dynamic, U1}; use crate::base::storage::{ ContiguousStorage, ContiguousStorageMut, Owned, ReshapableStorage, Storage, StorageMut, }; use crate::base::Vector; #[cfg(feature = "serde-serialize-no-std")] use serde::{ de::{Deserialize, Deserializer, Error}, ser::{Serialize, Serializer}, }; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; /* * * Storage. * */ /// A Vec-based matrix data storage. It may be dynamically-sized. #[repr(C)] #[derive(Eq, Debug, Clone, PartialEq)] pub struct VecStorage { pub(crate) data: Vec, pub(crate) nrows: R, pub(crate) ncols: C, } #[cfg(feature = "serde-serialize")] impl Serialize for VecStorage where T: Serialize, R: Serialize, C: Serialize, { fn serialize(&self, serializer: Ser) -> Result where Ser: Serializer, { (&self.data, &self.nrows, &self.ncols).serialize(serializer) } } #[cfg(feature = "serde-serialize")] impl<'a, T, R: Dim, C: Dim> Deserialize<'a> for VecStorage where T: Deserialize<'a>, R: Deserialize<'a>, C: Deserialize<'a>, { fn deserialize(deserializer: Des) -> Result where Des: Deserializer<'a>, { let (data, nrows, ncols): (Vec, R, C) = Deserialize::deserialize(deserializer)?; // SAFETY: make sure the data we deserialize have the // correct number of elements. if nrows.value() * ncols.value() != data.len() { return Err(Des::Error::custom(format!( "Expected {} components, found {}", nrows.value() * ncols.value(), data.len() ))); } Ok(Self { data, nrows, ncols }) } } #[deprecated(note = "renamed to `VecStorage`")] /// Renamed to [VecStorage]. pub type MatrixVec = VecStorage; impl VecStorage { /// Creates a new dynamic matrix data storage from the given vector and shape. #[inline] pub fn new(nrows: R, ncols: C, data: Vec) -> Self { assert!( nrows.value() * ncols.value() == data.len(), "Data storage buffer dimension mismatch." ); Self { data, nrows, ncols } } /// The underlying data storage. #[inline] #[must_use] pub fn as_vec(&self) -> &Vec { &self.data } /// The underlying mutable data storage. /// /// # Safety /// This is unsafe because this may cause UB if the size of the vector is changed /// by the user. #[inline] pub unsafe fn as_vec_mut(&mut self) -> &mut Vec { &mut self.data } /// Resizes the underlying mutable data storage and unwraps it. /// /// # Safety /// If `sz` is larger than the current size, additional elements are uninitialized. /// If `sz` is smaller than the current size, additional elements are truncated. #[inline] pub unsafe fn resize(mut self, sz: usize) -> Vec { let len = self.len(); if sz < len { self.data.set_len(sz); self.data.shrink_to_fit(); } else { self.data.reserve_exact(sz - len); self.data.set_len(sz); } self.data } /// The number of elements on the underlying vector. #[inline] #[must_use] pub fn len(&self) -> usize { self.data.len() } /// Returns true if the underlying vector contains no elements. #[inline] #[must_use] pub fn is_empty(&self) -> bool { self.len() == 0 } } impl From> for Vec { fn from(vec: VecStorage) -> Self { vec.data } } /* * * Dynamic − Static * Dynamic − Dynamic * */ unsafe impl Storage for VecStorage where DefaultAllocator: InnerAllocator, { type RStride = U1; type CStride = Dynamic; #[inline] fn ptr(&self) -> *const T { self.data.as_ptr() } #[inline] fn shape(&self) -> (Dynamic, C) { (self.nrows, self.ncols) } #[inline] fn strides(&self) -> (Self::RStride, Self::CStride) { (Self::RStride::name(), self.nrows) } #[inline] fn is_contiguous(&self) -> bool { true } #[inline] fn into_owned(self) -> Owned where DefaultAllocator: InnerAllocator, { self } #[inline] fn clone_owned(&self) -> Owned where DefaultAllocator: InnerAllocator, { self.clone() } #[inline] unsafe fn as_slice_unchecked(&self) -> &[T] { &self.data } } unsafe impl Storage for VecStorage where DefaultAllocator: InnerAllocator, { type RStride = U1; type CStride = R; #[inline] fn ptr(&self) -> *const T { self.data.as_ptr() } #[inline] fn shape(&self) -> (R, Dynamic) { (self.nrows, self.ncols) } #[inline] fn strides(&self) -> (Self::RStride, Self::CStride) { (Self::RStride::name(), self.nrows) } #[inline] fn is_contiguous(&self) -> bool { true } #[inline] fn into_owned(self) -> Owned where DefaultAllocator: InnerAllocator, { self } #[inline] fn clone_owned(&self) -> Owned where DefaultAllocator: InnerAllocator, { self.clone() } #[inline] unsafe fn as_slice_unchecked(&self) -> &[T] { &self.data } } /* * * StorageMut, ContiguousStorage. * */ unsafe impl StorageMut for VecStorage where DefaultAllocator: InnerAllocator, { #[inline] fn ptr_mut(&mut self) -> *mut T { self.data.as_mut_ptr() } #[inline] unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] { &mut self.data[..] } } unsafe impl ContiguousStorage for VecStorage where DefaultAllocator: InnerAllocator { } unsafe impl ContiguousStorageMut for VecStorage where DefaultAllocator: InnerAllocator { } impl ReshapableStorage for VecStorage { type Output = VecStorage; fn reshape_generic(self, nrows: Dynamic, ncols: C2) -> Self::Output { assert_eq!(nrows.value() * ncols.value(), self.data.len()); VecStorage { data: self.data, nrows, ncols, } } } impl ReshapableStorage for VecStorage { type Output = VecStorage; fn reshape_generic(self, nrows: R2, ncols: Dynamic) -> Self::Output { assert_eq!(nrows.value() * ncols.value(), self.data.len()); VecStorage { data: self.data, nrows, ncols, } } } unsafe impl StorageMut for VecStorage where DefaultAllocator: InnerAllocator, { #[inline] fn ptr_mut(&mut self) -> *mut T { self.data.as_mut_ptr() } #[inline] unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] { &mut self.data[..] } } impl ReshapableStorage for VecStorage { type Output = VecStorage; fn reshape_generic(self, nrows: Dynamic, ncols: C2) -> Self::Output { assert_eq!(nrows.value() * ncols.value(), self.data.len()); VecStorage { data: self.data, nrows, ncols, } } } impl ReshapableStorage for VecStorage { type Output = VecStorage; fn reshape_generic(self, nrows: R2, ncols: Dynamic) -> Self::Output { assert_eq!(nrows.value() * ncols.value(), self.data.len()); VecStorage { data: self.data, nrows, ncols, } } } #[cfg(feature = "abomonation-serialize")] impl Abomonation for VecStorage { unsafe fn entomb(&self, writer: &mut W) -> IOResult<()> { self.data.entomb(writer) } unsafe fn exhume<'a, 'b>(&'a mut self, bytes: &'b mut [u8]) -> Option<&'b mut [u8]> { self.data.exhume(bytes) } fn extent(&self) -> usize { self.data.extent() } } unsafe impl ContiguousStorage for VecStorage where DefaultAllocator: InnerAllocator { } unsafe impl ContiguousStorageMut for VecStorage where DefaultAllocator: InnerAllocator { } impl Extend for VecStorage { /// Extends the number of columns of the `VecStorage` with elements /// from the given iterator. /// /// # Panics /// This function panics if the number of elements yielded by the /// given iterator is not a multiple of the number of rows of the /// `VecStorage`. fn extend>(&mut self, iter: I) { self.data.extend(iter); self.ncols = Dynamic::new(self.data.len() / self.nrows.value()); assert!(self.data.len() % self.nrows.value() == 0, "The number of elements produced by the given iterator was not a multiple of the number of rows."); } } impl<'a, T: 'a + Copy, R: Dim> Extend<&'a T> for VecStorage { /// Extends the number of columns of the `VecStorage` with elements /// from the given iterator. /// /// # Panics /// This function panics if the number of elements yielded by the /// given iterator is not a multiple of the number of rows of the /// `VecStorage`. fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().copied()) } } impl Extend> for VecStorage where SV: Storage, ShapeConstraint: SameNumberOfRows, { /// Extends the number of columns of the `VecStorage` with vectors /// from the given iterator. /// /// # Panics /// This function panics if the number of rows of each `Vector` /// yielded by the iterator is not equal to the number of rows /// of this `VecStorage`. fn extend>>(&mut self, iter: I) { let nrows = self.nrows.value(); let iter = iter.into_iter(); let (lower, _upper) = iter.size_hint(); self.data.reserve(nrows * lower); for vector in iter { assert_eq!(nrows, vector.shape().0); self.data.extend(vector.iter().cloned()); } self.ncols = Dynamic::new(self.data.len() / nrows); } } impl Extend for VecStorage { /// Extends the number of rows of the `VecStorage` with elements /// from the given iterator. fn extend>(&mut self, iter: I) { self.data.extend(iter); self.nrows = Dynamic::new(self.data.len()); } }