Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iter::Sum for DMatrix #517

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/base/construction.rs
Expand Up @@ -681,14 +681,14 @@ impl_constructors!(Dynamic, Dynamic;
* Zero, One, Rand traits.
*
*/
impl<N, R: DimName, C: DimName> Zero for MatrixMN<N, R, C>
impl<N, R: Dim, C: Dim> Zero for MatrixMN<N, R, C>
where
N: Scalar + Zero + ClosedAdd,
DefaultAllocator: Allocator<N, R, C>,
{
#[inline]
fn zero() -> Self {
Self::from_element(N::zero())
Self::zeros_generic(R::default(), C::default())
}

#[inline]
Expand Down
85 changes: 52 additions & 33 deletions src/base/dimension.rs
Expand Up @@ -27,6 +27,13 @@ impl Dynamic {
}
}

impl Default for Dynamic {
/// A dynamic size equal to `0`.
fn default() -> Dynamic {
Dynamic::new(0)
}
}

#[cfg(feature = "serde-serialize")]
impl Serialize for Dynamic {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
Expand All @@ -53,7 +60,7 @@ impl IsNotStaticOne for Dynamic {}

/// Trait implemented by any type that can be used as a dimension. This includes type-level
/// integers and `Dynamic` (for dimensions not known at compile-time).
pub trait Dim: Any + Debug + Copy + PartialEq + Send + Sync {
pub trait Dim: Any + Debug + Default + Copy + PartialEq + Send + Sync {
#[inline(always)]
fn is<D: Dim>() -> bool {
TypeId::of::<Self>() == TypeId::of::<D>()
Expand Down Expand Up @@ -237,6 +244,12 @@ impl DimName for U1 {
}
}

impl Default for U1 {
fn default() -> U1 {
U1
}
}

impl NamedDim for typenum::U1 {
type Name = U1;
}
Expand Down Expand Up @@ -280,6 +293,12 @@ macro_rules! named_dimension(
}

impl IsNotStaticOne for $D { }

impl Default for $D {
fn default() -> $D {
$D
}
}
)*}
);

Expand All @@ -297,26 +316,26 @@ named_dimension!(

// For values greater than U1023, just use the typenum binary representation directly.
impl<
A: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
B: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
C: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
D: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
E: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
F: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
G: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
A: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
B: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
C: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
D: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
E: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
F: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
G: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
> NamedDim for UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, A>, B>, C>, D>, E>, F>, G>
{
type Name = Self;
}

impl<
A: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
B: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
C: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
D: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
E: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
F: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
G: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
A: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
B: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
C: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
D: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
E: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
F: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
G: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
> Dim for UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, A>, B>, C>, D>, E>, F>, G>
{
#[inline]
Expand All @@ -337,13 +356,13 @@ impl<
}

impl<
A: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
B: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
C: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
D: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
E: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
F: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
G: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
A: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
B: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
C: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
D: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
E: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
F: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
G: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
> DimName for UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, A>, B>, C>, D>, E>, F>, G>
{
type Value = Self;
Expand All @@ -355,24 +374,24 @@ impl<
}

impl<
A: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
B: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
C: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
D: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
E: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
F: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
G: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
A: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
B: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
C: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
D: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
E: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
F: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
G: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync,
> IsNotStaticOne
for UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, A>, B>, C>, D>, E>, F>, G>
{}

impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Sync> NamedDim
impl<U: Unsigned + DimName, B: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync> NamedDim
for UInt<U, B>
{
type Name = UInt<U, B>;
}

impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Sync> Dim
impl<U: Unsigned + DimName, B: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync> Dim
for UInt<U, B>
{
#[inline]
Expand All @@ -392,7 +411,7 @@ impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Syn
}
}

impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Sync> DimName
impl<U: Unsigned + DimName, B: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync> DimName
for UInt<U, B>
{
type Value = UInt<U, B>;
Expand All @@ -403,6 +422,6 @@ impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Syn
}
}

impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Sync> IsNotStaticOne
impl<U: Unsigned + DimName, B: Bit + Any + Debug + Default + Copy + PartialEq + Send + Sync> IsNotStaticOne
for UInt<U, B>
{}
58 changes: 52 additions & 6 deletions src/base/ops.rs
Expand Up @@ -374,23 +374,69 @@ componentwise_binop_impl!(Sub, sub, ClosedSub;
SubAssign, sub_assign, sub_assign_statically_unchecked, sub_assign_statically_unchecked_mut;
sub_to, sub_to_statically_unchecked);

impl<N, R: DimName, C: DimName> iter::Sum for MatrixMN<N, R, C>
/// Matrices and vectors implement the `iter::Sum` trait.
///
/// # Static matrices
///
/// ```
/// # use nalgebra::Matrix3x2;
/// let m1 = Matrix3x2::<f32>::zeros();
/// let m2 = Matrix3x2::<f32>::repeat(1.0);
/// let m3 = Matrix3x2::<f32>::identity();
/// let mats = vec![m1, m2, m3];
/// let expected = Matrix3x2::from_column_slice(&[2.0f32, 1.0, 1.0, 1.0, 2.0, 1.0]);
/// let sum : Matrix3x2::<f32> = mats.iter().sum();
/// assert_eq!(sum, expected);
/// ```
///
/// # Dynamic matrices
///
/// ```
/// # use nalgebra::DMatrix;
/// let m1 = DMatrix::<f32>::zeros(3, 2);
/// let m2 = DMatrix::<f32>::repeat(3, 2, 1.0);
/// let m3 = DMatrix::<f32>::identity(3, 2);
/// let mats = vec![m1, m2, m3];
/// let expected = DMatrix::from_column_slice(3, 2, &[2.0f32, 1.0, 1.0, 1.0, 2.0, 1.0]);
/// let sum : DMatrix::<f32> = mats.iter().sum();
/// assert_eq!(sum, expected);
/// ```
///
/// # Dynamic vectors
///
/// ```
/// # use nalgebra::DVector;
/// let v1 = DVector::<f32>::zeros(3);
/// let v2 = DVector::<f32>::repeat(3, 1.0);
/// let v3 = DVector::from_column_slice(3, &[1.0f32, 2.0, 3.0]);
/// let vecs = vec![v1, v2, v3];
/// let expected = DVector::from_column_slice(3, &[2.0f32, 3.0, 4.0]);
/// let sum : DVector::<f32> = vecs.iter().sum();
/// assert_eq!(sum, expected);
/// ```
impl<N, R: Dim, C: Dim> iter::Sum for MatrixMN<N, R, C>
where
N: Scalar + ClosedAdd + Zero,
DefaultAllocator: Allocator<N, R, C>,
{
fn sum<I: Iterator<Item = MatrixMN<N, R, C>>>(iter: I) -> MatrixMN<N, R, C> {
iter.fold(Matrix::zero(), |acc, x| acc + x)
/// If the sequence is empty, a zero matrix is produced in which any dynamic dimensions default to size 0.
fn sum<I: Iterator<Item = MatrixMN<N, R, C>>>(mut iter: I) -> MatrixMN<N, R, C> {
iter.next()
.map(|first| iter.fold(first, Add::add))
.unwrap_or(MatrixMN::zero())
}
}

impl<'a, N, R: DimName, C: DimName> iter::Sum<&'a MatrixMN<N, R, C>> for MatrixMN<N, R, C>
impl<'a, N, R: Dim, C: Dim> iter::Sum<&'a MatrixMN<N, R, C>> for MatrixMN<N, R, C>
where
N: Scalar + ClosedAdd + Zero,
DefaultAllocator: Allocator<N, R, C>,
{
fn sum<I: Iterator<Item = &'a MatrixMN<N, R, C>>>(iter: I) -> MatrixMN<N, R, C> {
iter.fold(Matrix::zero(), |acc, x| acc + x)
/// If the sequence is empty, a zero matrix is produced in which any dynamic dimensions default to size 0.
fn sum<I: Iterator<Item = &'a MatrixMN<N, R, C>>>(mut iter: I) -> MatrixMN<N, R, C> {
iter.next()
.map(|first| iter.fold(first.clone(), Add::add))
.unwrap_or(MatrixMN::zero())
}
}

Expand Down