empiricalCdf function
Builds the empirical CDF of values: one CdfPoint per DISTINCT value in
ascending order, with p the running fraction of samples ≤ that value.
Returns an empty list for no samples. Does not mutate values.
Example:
empiricalCdf(<num>[1, 2, 2, 3]);
// [CdfPoint(1, 0.25), CdfPoint(2, 0.75), CdfPoint(3, 1.0)]
Audited: 2026-06-12 11:26 EDT
Implementation
List<CdfPoint> empiricalCdf(List<num> values) {
if (values.isEmpty) return <CdfPoint>[];
final List<num> sorted = List<num>.of(values)..sort();
final int n = sorted.length;
final List<CdfPoint> points = <CdfPoint>[];
int i = 0;
while (i < n) {
final num value = sorted[i];
// Advance past every duplicate of this value so each distinct value yields a
// single point whose p reflects all samples ≤ it.
int j = i;
while (j < n && sorted[j] == value) {
j++;
}
points.add(CdfPoint(value, j / n));
i = j;
}
return points;
}