aboutsummaryrefslogtreecommitdiff
path: root/src/stats/tuple.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/stats/tuple.rs')
-rwxr-xr-xsrc/stats/tuple.rs253
1 files changed, 253 insertions, 0 deletions
diff --git a/src/stats/tuple.rs b/src/stats/tuple.rs
new file mode 100755
index 0000000..1c07515
--- /dev/null
+++ b/src/stats/tuple.rs
@@ -0,0 +1,253 @@
+//! Helper traits for tupling/untupling
+
+use crate::stats::Distribution;
+
+/// Any tuple: `(A, B, ..)`
+pub trait Tuple: Sized {
+ /// A tuple of distributions associated with this tuple
+ type Distributions: TupledDistributions<Item = Self>;
+
+ /// A tuple of vectors associated with this tuple
+ type Builder: TupledDistributionsBuilder<Item = Self>;
+}
+
+/// A tuple of distributions: `(Distribution<A>, Distribution<B>, ..)`
+pub trait TupledDistributions: Sized {
+ /// A tuple that can be pushed/inserted into the tupled distributions
+ type Item: Tuple<Distributions = Self>;
+}
+
+/// A tuple of vecs used to build distributions.
+pub trait TupledDistributionsBuilder: Sized {
+ /// A tuple that can be pushed/inserted into the tupled distributions
+ type Item: Tuple<Builder = Self>;
+
+ /// Creates a new tuple of vecs
+ fn new(size: usize) -> Self;
+
+ /// Push one element into each of the vecs
+ fn push(&mut self, tuple: Self::Item);
+
+ /// Append one tuple of vecs to this one, leaving the vecs in the other tuple empty
+ fn extend(&mut self, other: &mut Self);
+
+ /// Convert the tuple of vectors into a tuple of distributions
+ fn complete(self) -> <Self::Item as Tuple>::Distributions;
+}
+
+impl<A> Tuple for (A,)
+where
+ A: Copy,
+{
+ type Distributions = (Distribution<A>,);
+ type Builder = (Vec<A>,);
+}
+
+impl<A> TupledDistributions for (Distribution<A>,)
+where
+ A: Copy,
+{
+ type Item = (A,);
+}
+impl<A> TupledDistributionsBuilder for (Vec<A>,)
+where
+ A: Copy,
+{
+ type Item = (A,);
+
+ fn new(size: usize) -> (Vec<A>,) {
+ (Vec::with_capacity(size),)
+ }
+
+ fn push(&mut self, tuple: (A,)) {
+ (self.0).push(tuple.0);
+ }
+
+ fn extend(&mut self, other: &mut (Vec<A>,)) {
+ (self.0).append(&mut other.0);
+ }
+
+ fn complete(self) -> (Distribution<A>,) {
+ (Distribution(self.0.into_boxed_slice()),)
+ }
+}
+
+impl<A, B> Tuple for (A, B)
+where
+ A: Copy,
+ B: Copy,
+{
+ type Distributions = (Distribution<A>, Distribution<B>);
+ type Builder = (Vec<A>, Vec<B>);
+}
+
+impl<A, B> TupledDistributions for (Distribution<A>, Distribution<B>)
+where
+ A: Copy,
+ B: Copy,
+{
+ type Item = (A, B);
+}
+impl<A, B> TupledDistributionsBuilder for (Vec<A>, Vec<B>)
+where
+ A: Copy,
+ B: Copy,
+{
+ type Item = (A, B);
+
+ fn new(size: usize) -> (Vec<A>, Vec<B>) {
+ (Vec::with_capacity(size), Vec::with_capacity(size))
+ }
+
+ fn push(&mut self, tuple: (A, B)) {
+ (self.0).push(tuple.0);
+ (self.1).push(tuple.1);
+ }
+
+ fn extend(&mut self, other: &mut (Vec<A>, Vec<B>)) {
+ (self.0).append(&mut other.0);
+ (self.1).append(&mut other.1);
+ }
+
+ fn complete(self) -> (Distribution<A>, Distribution<B>) {
+ (
+ Distribution(self.0.into_boxed_slice()),
+ Distribution(self.1.into_boxed_slice()),
+ )
+ }
+}
+
+impl<A, B, C> Tuple for (A, B, C)
+where
+ A: Copy,
+ B: Copy,
+ C: Copy,
+{
+ type Distributions = (Distribution<A>, Distribution<B>, Distribution<C>);
+ type Builder = (Vec<A>, Vec<B>, Vec<C>);
+}
+
+impl<A, B, C> TupledDistributions for (Distribution<A>, Distribution<B>, Distribution<C>)
+where
+ A: Copy,
+ B: Copy,
+ C: Copy,
+{
+ type Item = (A, B, C);
+}
+impl<A, B, C> TupledDistributionsBuilder for (Vec<A>, Vec<B>, Vec<C>)
+where
+ A: Copy,
+ B: Copy,
+ C: Copy,
+{
+ type Item = (A, B, C);
+
+ fn new(size: usize) -> (Vec<A>, Vec<B>, Vec<C>) {
+ (
+ Vec::with_capacity(size),
+ Vec::with_capacity(size),
+ Vec::with_capacity(size),
+ )
+ }
+
+ fn push(&mut self, tuple: (A, B, C)) {
+ (self.0).push(tuple.0);
+ (self.1).push(tuple.1);
+ (self.2).push(tuple.2);
+ }
+
+ fn extend(&mut self, other: &mut (Vec<A>, Vec<B>, Vec<C>)) {
+ (self.0).append(&mut other.0);
+ (self.1).append(&mut other.1);
+ (self.2).append(&mut other.2);
+ }
+
+ fn complete(self) -> (Distribution<A>, Distribution<B>, Distribution<C>) {
+ (
+ Distribution(self.0.into_boxed_slice()),
+ Distribution(self.1.into_boxed_slice()),
+ Distribution(self.2.into_boxed_slice()),
+ )
+ }
+}
+
+impl<A, B, C, D> Tuple for (A, B, C, D)
+where
+ A: Copy,
+ B: Copy,
+ C: Copy,
+ D: Copy,
+{
+ type Distributions = (
+ Distribution<A>,
+ Distribution<B>,
+ Distribution<C>,
+ Distribution<D>,
+ );
+ type Builder = (Vec<A>, Vec<B>, Vec<C>, Vec<D>);
+}
+
+impl<A, B, C, D> TupledDistributions
+ for (
+ Distribution<A>,
+ Distribution<B>,
+ Distribution<C>,
+ Distribution<D>,
+ )
+where
+ A: Copy,
+ B: Copy,
+ C: Copy,
+ D: Copy,
+{
+ type Item = (A, B, C, D);
+}
+impl<A, B, C, D> TupledDistributionsBuilder for (Vec<A>, Vec<B>, Vec<C>, Vec<D>)
+where
+ A: Copy,
+ B: Copy,
+ C: Copy,
+ D: Copy,
+{
+ type Item = (A, B, C, D);
+
+ fn new(size: usize) -> (Vec<A>, Vec<B>, Vec<C>, Vec<D>) {
+ (
+ Vec::with_capacity(size),
+ Vec::with_capacity(size),
+ Vec::with_capacity(size),
+ Vec::with_capacity(size),
+ )
+ }
+
+ fn push(&mut self, tuple: (A, B, C, D)) {
+ (self.0).push(tuple.0);
+ (self.1).push(tuple.1);
+ (self.2).push(tuple.2);
+ (self.3).push(tuple.3);
+ }
+
+ fn extend(&mut self, other: &mut (Vec<A>, Vec<B>, Vec<C>, Vec<D>)) {
+ (self.0).append(&mut other.0);
+ (self.1).append(&mut other.1);
+ (self.2).append(&mut other.2);
+ (self.3).append(&mut other.3);
+ }
+
+ fn complete(
+ self,
+ ) -> (
+ Distribution<A>,
+ Distribution<B>,
+ Distribution<C>,
+ Distribution<D>,
+ ) {
+ (
+ Distribution(self.0.into_boxed_slice()),
+ Distribution(self.1.into_boxed_slice()),
+ Distribution(self.2.into_boxed_slice()),
+ Distribution(self.3.into_boxed_slice()),
+ )
+ }
+}