Skip to main content

TDigest

Struct TDigest 

Source
#[non_exhaustive]
pub struct TDigest { /* private fields */ }
Expand description

T-Digest to be operated on.

Call TDigest::flush before centroid-based queries or serialization after using the mutable ingestion API. The pending buffer is deliberately omitted from serde output, so serializing an unflushed digest produces an incomplete digest.

With the serde feature, deserialization validates centroid ordering, positive weights, extrema, and count consistency before constructing a digest.

Queries that need data return None when the digest is empty. Summary accessors such as TDigest::count and TDigest::sum return zero.

Implementations§

Source§

impl TDigest

Source

pub fn new_with_size(max_size: usize) -> Self

Create an empty digest with the requested compression size.

Larger sizes retain more centroids and generally improve accuracy.

§Panics

Panics if max_size is zero.

use tdigest::TDigest;

let digest = TDigest::new_with_size(200);
assert_eq!(digest.max_size(), 200);
Source

pub fn new( centroids: Vec<Centroid>, sum: f64, count: f64, max: Option<f64>, min: Option<f64>, max_size: usize, ) -> Self

Construct a digest from existing centroids and summary statistics.

Centroids are sorted by mean. If there are more centroids than max_size, they are recompressed using the requested size. The supplied statistics must describe the same samples as the centroids.

§Panics

Panics if max_size is zero. Debug builds also check the extrema.

Source

pub fn mean(&self) -> Option<f64>

Return the arithmetic mean, or None when the digest is empty.

If the stored sum overflows, this uses a weighted mean of the centroids and buffered values. That fallback is approximate and takes linear time in the number of retained centroids and pending values.

Source

pub fn sum(&self) -> f64

Return the sum of all inserted values.

This ordinary f64 accumulator may overflow to infinity or NaN even when every inserted value is finite.

Source

pub fn count(&self) -> f64

Return the number of inserted values as an f64.

Integer counts are represented exactly up to 2^53.

Source

pub fn max(&self) -> Option<f64>

Return the greatest inserted value, or None when empty.

Source

pub fn min(&self) -> Option<f64>

Return the least inserted value, or None when empty.

Source

pub fn is_empty(&self) -> bool

Return whether no values have been inserted.

Source

pub fn max_size(&self) -> usize

Return the configured compression size.

Source

pub fn centroids(&self) -> &[Centroid]

Return the compressed centroids in ascending mean order.

Call TDigest::flush first after mutable ingestion.

Source§

impl TDigest

Source

pub fn push(&mut self, value: f64)

Insert one value into this digest.

Values are buffered and compressed automatically. Call TDigest::flush before estimating quantiles or reading centroids.

use tdigest::TDigest;

let mut digest = TDigest::new_with_size(100);
digest.push(1.0);
digest.push(2.0);
digest.flush();
assert_eq!(digest.estimate_quantile(0.5), Some(1.5));
Source

pub fn extend_values(&mut self, values: impl IntoIterator<Item = f64>)

Insert several values using the mutable buffered ingestion path.

Source

pub fn flush(&mut self)

Compress pending buffered values into this digest’s centroids.

This is a no-op when the buffer is empty.

Source

pub fn merge_unsorted(&self, unsorted_values: Vec<f64>) -> TDigest

Merge unsorted values into a new digest, sorting them internally.

use tdigest::TDigest;

let digest = TDigest::default().merge_unsorted(vec![3.0, 1.0, 2.0]);
assert_eq!(digest.estimate_quantile(0.5), Some(2.0));
Source

pub fn merge_sorted(&self, sorted_values: Vec<f64>) -> TDigest

Merge ascending values into a new digest.

use tdigest::TDigest;

let digest = TDigest::default().merge_sorted(vec![1.0, 2.0, 3.0]);
assert_eq!(digest.count(), 3.0);
Source

pub fn merge_digests(digests: Vec<TDigest>) -> TDigest

Merge several digests into one.

The result uses the largest max_size among the inputs. With no inputs, this returns a digest with the default size of 100.

use tdigest::TDigest;

let left = TDigest::default().merge_sorted(vec![1.0, 2.0]);
let right = TDigest::default().merge_sorted(vec![3.0, 4.0]);
let merged = TDigest::merge_digests(vec![left, right]);
assert_eq!(merged.count(), 4.0);
Source

pub fn estimate_quantile(&self, q: f64) -> Option<f64>

Estimate the value at quantile q (0.0 to 1.0). Returns None if the digest is empty. Values below zero return the minimum; values above one return the maximum.

use tdigest::TDigest;

let digest = TDigest::default().merge_sorted(vec![1.0, 2.0, 3.0]);
assert_eq!(digest.estimate_quantile(0.5), Some(2.0));
Source

pub fn quantiles(&self, qs: &[f64]) -> Vec<Option<f64>>

Estimate several quantiles with one cumulative-weight pass.

Quantiles do not need to be sorted. Each result has the same semantics as TDigest::estimate_quantile.

use tdigest::TDigest;

let digest = TDigest::default().merge_sorted(vec![1.0, 2.0, 3.0]);
assert_eq!(digest.quantiles(&[0.0, 0.5, 1.0]), vec![Some(1.0), Some(2.0), Some(3.0)]);
Source

pub fn estimate_rank(&self, value: f64) -> Option<f64>

Estimate the rank (CDF) of value by interpolating centroid midpoints.

Returns None if the digest is empty. Values at or below the minimum return zero; values at or above the maximum return one. For a constant digest, the rank is one at the constant value. This is a smooth estimate, rather than an exact count of samples at repeated values.

use tdigest::TDigest;

let digest = TDigest::default().merge_sorted((1..=100).map(f64::from).collect());
let median_rank = digest.estimate_rank(50.0).unwrap();
assert!((median_rank - 0.5).abs() < 0.05);
Source

pub fn trimmed_mean(&self, lo: f64, hi: f64) -> Option<f64>

Estimate the mean of values between quantiles lo and hi.

Quantiles are clamped to [0.0, 1.0]. Returns None if the digest is empty, either bound is NaN, or the resulting interval is empty.

use tdigest::TDigest;

let digest = TDigest::default().merge_sorted((1..=100).map(f64::from).collect());
assert!((digest.trimmed_mean(0.1, 0.9).unwrap() - 50.5).abs() < 1.0);

Trait Implementations§

Source§

impl Clone for TDigest

Source§

fn clone(&self) -> TDigest

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TDigest

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for TDigest

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Extend<f64> for TDigest

Source§

fn extend<T: IntoIterator<Item = f64>>(&mut self, iter: T)

Extends a collection with the contents of an iterator. Read more
Source§

fn extend_one(&mut self, item: T)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl FromIterator<f64> for TDigest

Source§

fn from_iter<T: IntoIterator<Item = f64>>(iter: T) -> Self

Creates a value from an iterator. Read more
Source§

impl PartialEq for TDigest

Source§

fn eq(&self, other: &TDigest) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for TDigest

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.