Skip to content

Commit

Permalink
Release 0.3.0
Browse files Browse the repository at this point in the history
* Implement VariableNoFlow.
* Implement new value types: Sum, WeightedSum, Mean, WeightedMean.
* Replace FillWeight trait with FillWith and FillWithWeighted.
* Improve docs.
  • Loading branch information
davehadley authored Jan 16, 2021
1 parent a801deb commit 8313bd3
Show file tree
Hide file tree
Showing 29 changed files with 995 additions and 67 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: ci

on:
push:
branches: [main]
branches: [main, develop]
pull_request:
branches: [main]
branches: [main, develop]


jobs:
Expand Down
8 changes: 3 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ jobs:
test:
name: Publish
runs-on: ubuntu-latest
working-directory: ./ndhistogram
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: publish
args: --locked --token ${{ secrets.CRATES_TOKEN }}
- name: cargo publish
working-directory: ./ndhistogram
run: cargo publish --locked --token ${{ secrets.CRATES_TOKEN }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
venv/
.vscode/
.idea/

# Generated by Cargo
# will have compiled files and executables
Expand Down
3 changes: 0 additions & 3 deletions .vscode/settings.json

This file was deleted.

7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# ndhistogram : N-dimensional histograms for Rust

[![Main Build status](https://img.shields.io/github/workflow/status/davehadley/ndhistogram/ci/main?label=main)](https://github.com/davehadley/ndhistogram)
[![Develop status](https://img.shields.io/github/workflow/status/davehadley/ndhistogram/ci/main?label=develop)](https://github.com/davehadley/ndhistogram)
[![Crate](https://img.shields.io/crates/v/ndhistogram.svg)](https://crates.io/crates/ndhistogram)
[![License](https://img.shields.io/crates/l/ndhistogram)](https://crates.io/crates/ndhistogram)
[![Last commit](https://img.shields.io/github/last-commit/davehadley/ndhistogram/develop)](https://github.com/davehadley/ndhistogram)
[![Last release](https://img.shields.io/github/release-date/davehadley/ndhistogram)](https://crates.io/crates/ndhistogram)

# Usage

For usage instructions see:
Expand Down
6 changes: 3 additions & 3 deletions TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
- [ ] Uniform with transform binning
- [ ] Integer binning
- [ ] Dynamic histogram (i.e. axes only know at runtime)
- [ ] "SumW2" histogram values
- [ ] "Profile" histograms
- [x] "SumW2" histogram values
- [x] "Profile" histograms
- [ ] ndarray-like slicing
- [ ] Pretty display for histogram
- [ ] Histogram +, -, /, *, ==, operations
- [x] Histogram +, -, /, *, ==, operations
- [ ] Implement grow for Uniform
- [ ] Re-binnable axis.
- [ ] Growable/Extendable axis.
Expand Down
2 changes: 1 addition & 1 deletion ndhistogram/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ndhistogram"
version = "0.2.1"
version = "0.3.0"
authors = [ "David Hadley <[email protected]>",]
edition = "2018"
license = "MIT OR Apache-2.0"
Expand Down
8 changes: 5 additions & 3 deletions ndhistogram/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# ndhistogram : multi-dimensional histogramming for Rust

[![Build status](https://img.shields.io/github/workflow/status/davehadley/ndhistogram/ci)](https://github.com/davehadley/ndhistogram)
[![Main Build status](https://img.shields.io/github/workflow/status/davehadley/ndhistogram/ci/main?label=main)](https://github.com/davehadley/ndhistogram)
[![Develop status](https://img.shields.io/github/workflow/status/davehadley/ndhistogram/ci/main?label=develop)](https://github.com/davehadley/ndhistogram)
[![Crate](https://img.shields.io/crates/v/ndhistogram.svg)](https://crates.io/crates/ndhistogram)
[![License](https://img.shields.io/crates/l/ndhistogram)](https://crates.io/crates/ndhistogram)
[![Downloads](https://img.shields.io/crates/d/ndhistogram)](https://crates.io/crates/ndhistogram)
[![Last commit](https://img.shields.io/github/last-commit/davehadley/ndhistogram/develop)](https://github.com/davehadley/ndhistogram)
[![Last release](https://img.shields.io/github/release-date/davehadley/ndhistogram)](https://crates.io/crates/ndhistogram)

A histogramming library for Rust.

Expand All @@ -15,7 +17,7 @@ Add this to your `Cargo.toml`:

```toml
[dependencies]
ndhistogram = "0.2.0"
ndhistogram = "0.3.0"
```

To get started see the [quick start guide](https://docs.rs/ndhistogram).
Expand Down
2 changes: 1 addition & 1 deletion ndhistogram/src/axis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ type Bins<'a, BinInterval> = Box<dyn Iterator<Item = BinInterval> + 'a>;
///
/// let mut hist = ndhistogram!(ParityAxis{}; i32);
/// hist.fill(&1);
/// hist.fill_weight(&2, 4);
/// hist.fill_with(&2, 4);
/// assert_eq!(hist.value(&1), Some(&1));
/// assert_eq!(hist.value(&2), Some(&4));
/// ```
Expand Down
38 changes: 25 additions & 13 deletions ndhistogram/src/histogram/fill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ use num_traits::One;

/// Fill a histogram bin value with unit weight.
///
/// Values that may be stored in a [Histogram](crate::Histogram) should implement this trait to allow that histogram to be filled.
/// A blanket implementation is provided for types that implement [One] and [AddAssign] traits.
/// See also [FillWeight].
/// Values that may be stored in a [Histogram](crate::Histogram) should
/// implement this trait to allow that histogram to be filled.
/// A blanket implementation is provided for types that implement [One]
/// and [AddAssign] traits. See also [FillWith].
pub trait Fill {
/// Fill this value with unit weight.
/// For a simple number type this means simply increment by one.
Expand All @@ -19,21 +20,32 @@ impl<T: One + AddAssign> Fill for T {
}
}

/// Fill a histogram bin value with a weight.
/// Fill a histogram bin value with some data.
///
/// Values that may be stored in a [Histogram](crate::Histogram) should implement this trait to allow that histogram to be filled with weights.
/// A blanket implementation is provided for types that implement the [AddAssign] trait.
pub trait FillWeight<W> {
/// Fill this value with some weight.
/// Fill a histogram with some value. This trait has a blanket implementation
/// for [AddAssign].
/// In the case of primitive histogram values, this is equivalent to a weighted
/// fill.
pub trait FillWith<D> {
/// Fill this value with some data.
/// For a simple number type means adding the weight.
fn fill_weight(&mut self, weight: W);
fn fill_with(&mut self, value: D);
}

impl<W> FillWeight<W> for W
impl<D> FillWith<D> for D
where
Self: AddAssign<W>,
Self: AddAssign<D>,
{
fn fill_weight(&mut self, weight: W) {
*self += weight;
fn fill_with(&mut self, data: D) {
*self += data;
}
}

/// Fill a histogram with some weighted value.
///
/// As [FillWith], but for instances where the value may also be weighted.
/// For example, see [WeightedMean](crate::value::WeightedMean).
pub trait FillWithWeighted<D, W> {
/// Fill a histogram with some weighted value.
fn fill_with_weighted(&mut self, data: D, weight: W);
}
30 changes: 21 additions & 9 deletions ndhistogram/src/histogram/histogram.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{axes::Axes, axis::Axis};
use crate::{axes::Axes, axis::Axis, FillWith};

use super::fill::{Fill, FillWeight};
use super::fill::{Fill, FillWithWeighted};

// TODO: Using generic associated types would give a cleaner interface and avoid boxing the iterators
// https://github.com/rust-lang/rfcs/blob/master/text/1598-generic_associated_types.md
Expand Down Expand Up @@ -66,21 +66,33 @@ pub trait Histogram<A: Axes, V> {
}
}

/// Fill the histogram bin value at coordinate with a weight.
/// If the [Axes] do no cover that coordinate, do nothing.
/// See [FillWeight].
fn fill_weight<W>(&mut self, coordinate: &A::Coordinate, weight: W)
/// Fill the histogram bin value at coordinate with some data.
/// If the [Axes] do not cover that coordinate, do nothing.
/// See [FillWith].
fn fill_with<D>(&mut self, coordinate: &A::Coordinate, data: D)
where
V: FillWith<D>,
{
if let Some(value) = self.value_mut(coordinate) {
value.fill_with(data)
}
}

/// Fill the histogram bin value at coordinate with some data.
/// If the [Axes] do not cover that coordinate, do nothing.
/// See [FillWith].
fn fill_with_weighted<D, W>(&mut self, coordinate: &A::Coordinate, data: D, weight: W)
where
V: FillWeight<W>,
V: FillWithWeighted<D, W>,
{
if let Some(value) = self.value_mut(coordinate) {
value.fill_weight(weight)
value.fill_with_weighted(data, weight)
}
}
}

/// Struct to be returned when iterating over [Histogram]s bins.
#[derive(Debug, PartialEq, Clone)]
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Item<T, V> {
/// Bin number
pub index: usize,
Expand Down
67 changes: 65 additions & 2 deletions ndhistogram/src/histogram/vechistogram.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::fmt::Display;
use std::{
fmt::Display,
ops::{Add, Div, Mul, Sub},
};

use crate::axes::Axes;

Expand All @@ -7,7 +10,7 @@ use super::histogram::{Histogram, Item, Iter, IterMut, ValuesMut};
/// A Histogram that stores its values in a [Vec].
///
/// See [ndhistogram] for examples of its use.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VecHistogram<A, V> {
axes: A,
values: Vec<V>,
Expand Down Expand Up @@ -93,3 +96,63 @@ impl<A: Axes, V> Display for VecHistogram<A, V> {
write!(f, "VecHistogram{}D", self.axes().num_dim())
}
}

macro_rules! impl_binary_op {
($Trait:tt, $method:tt, $mathsymbol:tt) => {
impl<A: Axes + PartialEq + Clone, V> $Trait<&VecHistogram<A, V>> for &VecHistogram<A, V>
where
for<'a> &'a V: $Trait<Output = V>,
{
type Output = Result<VecHistogram<A, V>, ()>;

fn $method(self, rhs: &VecHistogram<A, V>) -> Self::Output {
if self.axes() != rhs.axes() {
return Err(());
}
let values = self
.values
.iter()
.zip(rhs.values.iter())
.map(|(l, r)| l $mathsymbol r)
.collect();
Ok(VecHistogram {
axes: self.axes().clone(),
values,
})
}
}
};
}

impl_binary_op! {Add, add, +}
impl_binary_op! {Sub, sub, -}
impl_binary_op! {Mul, mul, *}
impl_binary_op! {Div, div, /}

macro_rules! impl_binary_op_with_scalar {
($Trait:tt, $method:tt, $mathsymbol:tt) => {
impl<A: Axes + PartialEq + Clone, V> $Trait<&V> for &VecHistogram<A, V>
where
for<'a> &'a V: $Trait<Output = V>,
{
type Output = VecHistogram<A, V>;

fn $method(self, rhs: &V) -> Self::Output {
let values = self
.values
.iter()
.map(|l| l $mathsymbol rhs)
.collect();
VecHistogram {
axes: self.axes().clone(),
values,
}
}
}
};
}

impl_binary_op_with_scalar! {Add, add, +}
impl_binary_op_with_scalar! {Sub, sub, -}
impl_binary_op_with_scalar! {Mul, mul, *}
impl_binary_op_with_scalar! {Div, div, /}
26 changes: 18 additions & 8 deletions ndhistogram/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! - Continuous (eg represented by a floating point number) and discrete axis (eg a category represented by a string value or enum) types.
//! - Flexible bin values including any primitive number type, or a user-defined struct.
//! - Unweighted and weighted filling of histograms.
//! - User definable axis types.
//! - Flexible, user-definable axis types.
//!
//! ## Quick-start
//!
Expand All @@ -17,7 +17,7 @@
//! // fill this histogram with a single value
//! hist.fill(&1.0);
//! // fill this histogram with weights
//! hist.fill_weight(&2.0, 4.0);
//! hist.fill_with(&2.0, 4.0);
//! // read the histogram values
//! let x1 = hist.value(&1.0);
//! let also_x1 = hist.value_at_index(7);
Expand Down Expand Up @@ -45,9 +45,9 @@
//!
//! // The Histogram bin value type is configurable
//! let mut hist = ndhistogram!(Uniform::new(10, -5.0, 5.0); i32);
//! hist.fill_weight(&1.0, 2);
//! hist.fill_with(&1.0, 2);
//! let value: Option<&i32> = hist.value(&1.0);
//! // and user defined value types are possible by implementing Fill and FillWeight traits
//! // and user defined value types are possible by implementing Fill and FillWith traits
//!
//! ```
//!
Expand All @@ -56,7 +56,7 @@
//! A [Histogram](crate::Histogram) is composed of two components:
//! - An [Axis](crate::axis::Axis) for 1D histograms or set of [Axes] for higher dimensional histograms.
//! The [Axes] and [Axis](crate::axis::Axis) map from coodinate space (eg \[x,y,z\]) to an integer bin number.
//! - The histogram bin value storage. Bin values may be any type that implements [Fill] or [FillWeight] (including integer and floating number types).
//! - The histogram bin value storage. Bin values may be any type that implements [Fill], [FillWith] or [FillWithWeight] (including any integer and floating number type).
//!
//! ### Histogram Implementations
//!
Expand All @@ -82,10 +82,17 @@
//! Histograms may be filled with values of the following types.
//!
//! - Primitve floating point and integer number types.
//! - All types that implement [AddAssign](std::ops::AddAssign) are [FillWeight].
//! - All types that implement [AddAssign](std::ops::AddAssign) are [FillWith].
//! - All types that implement [AddAssign](std::ops::AddAssign) and [One](num_traits::One) are [Fill].
//!
//! User defined bin value types are possible by implementing the [Fill] and [FillWeight] traits.
//! This crate defines the following bin value types:
//!
//! - [Sum](crate::value::Sum) : a simple bin count that counts the number of times it has been filled.
//! - [WeightedSum](crate::value::WeightedSum) : as Sum but with weighted fills.
//! - [Mean](crate::value::Mean) : computes the mean of the values it is filled with.
//! - [WeightedMean](crate::value::WeightedMean) : as Mean but with weighted fills.
//!
//! User defined bin value types are possible by implementing the [Fill], [FillWith] or [FillWithWeighted] traits.
#![doc(issue_tracker_base_url = "https://github.com/davehadley/rust-hist/issues")]
#![cfg_attr(
Expand All @@ -104,9 +111,12 @@ mod axes;
pub mod axis;
mod histogram;

pub mod value;

pub use axes::Axes;
pub use histogram::fill::Fill;
pub use histogram::fill::FillWeight;
pub use histogram::fill::FillWith;
pub use histogram::fill::FillWithWeighted;
pub use histogram::histogram::Histogram;
pub use histogram::histogram::Item;
pub use histogram::vechistogram::VecHistogram;
Expand Down
11 changes: 11 additions & 0 deletions ndhistogram/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@
#[macro_export]
macro_rules! ndhistogram {

// ($( $x:expr ),+ $(,)*; $type:ident<$($generics:tt),+> $(;)*) => {
// {
// let axes = (
// $(
// $x,
// )*
// );
// $crate::VecHistogram::<_, $type<$($generics),+>>::new(axes)
// }
// };

($( $x:expr ),+ $(,)*; $type:ty $(;)*) => {
{
let axes = (
Expand Down
Loading

0 comments on commit 8313bd3

Please sign in to comment.