#[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
impl TDigest
Sourcepub fn new_with_size(max_size: usize) -> Self
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);Sourcepub fn new(
centroids: Vec<Centroid>,
sum: f64,
count: f64,
max: Option<f64>,
min: Option<f64>,
max_size: usize,
) -> Self
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.
Sourcepub fn mean(&self) -> Option<f64>
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.
Sourcepub fn sum(&self) -> f64
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.
Sourcepub fn count(&self) -> f64
pub fn count(&self) -> f64
Return the number of inserted values as an f64.
Integer counts are represented exactly up to 2^53.
Sourcepub fn centroids(&self) -> &[Centroid]
pub fn centroids(&self) -> &[Centroid]
Return the compressed centroids in ascending mean order.
Call TDigest::flush first after mutable ingestion.
Source§impl TDigest
impl TDigest
Sourcepub fn push(&mut self, value: f64)
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));Sourcepub fn extend_values(&mut self, values: impl IntoIterator<Item = f64>)
pub fn extend_values(&mut self, values: impl IntoIterator<Item = f64>)
Insert several values using the mutable buffered ingestion path.
Sourcepub fn flush(&mut self)
pub fn flush(&mut self)
Compress pending buffered values into this digest’s centroids.
This is a no-op when the buffer is empty.
Sourcepub fn merge_unsorted(&self, unsorted_values: Vec<f64>) -> TDigest
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));Sourcepub fn merge_sorted(&self, sorted_values: Vec<f64>) -> TDigest
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);Sourcepub fn merge_digests(digests: Vec<TDigest>) -> TDigest
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);Sourcepub fn estimate_quantile(&self, q: f64) -> Option<f64>
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));Sourcepub fn quantiles(&self, qs: &[f64]) -> Vec<Option<f64>>
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)]);Sourcepub fn estimate_rank(&self, value: f64) -> Option<f64>
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);Sourcepub fn trimmed_mean(&self, lo: f64, hi: f64) -> Option<f64>
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 Extend<f64> for TDigest
impl Extend<f64> for TDigest
Source§fn extend<T: IntoIterator<Item = f64>>(&mut self, iter: T)
fn extend<T: IntoIterator<Item = f64>>(&mut self, iter: T)
Source§fn extend_one(&mut self, item: T)
fn extend_one(&mut self, item: T)
extend_one)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)