Skip to content

Commit 1fb5938

Browse files
committed
Implement get_PMF and get_CDF
1 parent b0c18de commit 1fb5938

2 files changed

Lines changed: 43 additions & 1 deletion

File tree

ddsketch/include/ddsketch.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ namespace datasketches {
4343
template<class Store, class Mapping>
4444
class DDSketch {
4545
public:
46+
using vector_double = std::vector<double>;
47+
using T = typename Store::bins_type::value_type;
4648

4749
/**
4850
* Constructs an initially empty quantile sketch using the specified {@link IndexMapping} and
@@ -92,6 +94,10 @@ class DDSketch {
9294
*/
9395
double get_quantile(const double& rank) const;
9496

97+
vector_double get_PMF(const T* split_points, uint32_t size) const;
98+
99+
vector_double get_CDF(const T* split_pints, uint32_t size) const;
100+
95101

96102
bool is_empty() const;
97103

@@ -169,6 +175,8 @@ class DDSketch {
169175
void check_mergeability(const DDSketch<OtherStore, Mapping>& other) const;
170176

171177
double get_quantile(const double& rank, const double& count) const;
178+
179+
static inline void check_split_pints(const T* values, uint32_t size);
172180
};
173181

174182
} /* namespace datasketches */

ddsketch/include/ddsketch_impl.hpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include "ddsketch.hpp"
2828
#include "store_factory.hpp"
2929
namespace datasketches {
30-
3130
template<class Store, class Mapping>
3231
DDSketch<Store, Mapping>::DDSketch(const double& relative_accuracy): DDSketch(Mapping(relative_accuracy)) {}
3332

@@ -201,6 +200,29 @@ double DDSketch<Store, Mapping>::get_quantile(const double& rank, const double&
201200
throw std::invalid_argument("no such element");
202201
}
203202

203+
template<class Store, class Mapping>
204+
typename DDSketch<Store, Mapping>::vector_double DDSketch<Store, Mapping>::get_CDF(const T* split_points, uint32_t size) const {
205+
check_split_pints(split_points, size);
206+
vector_double ranks;
207+
ranks.reserve(size + 1);
208+
for (uint32_t i = 0; i < size; ++i) {
209+
ranks.push_back(get_rank(split_points[i]));
210+
}
211+
ranks.push_back(1.0);
212+
return ranks;
213+
}
214+
215+
template<class Store, class Mapping>
216+
typename DDSketch<Store, Mapping>::vector_double DDSketch<Store, Mapping>::get_PMF(const typename DDSketch<Store, Mapping>::T* split_points, uint32_t size) const {
217+
vector_double buckets = get_CDF(split_points, size);
218+
for (uint32_t i = size; i > 0; --i) {
219+
buckets[i] -= buckets[i - 1];
220+
}
221+
222+
return buckets;
223+
}
224+
225+
204226
template<class Store, class Mapping>
205227
void DDSketch<Store, Mapping>::serialize(std::ostream& os) const {
206228
index_mapping.serialize(os);
@@ -279,6 +301,18 @@ bool DDSketch<Store, Mapping>::operator==(const DDSketch<Store, Mapping>& other)
279301
max_indexed_value == other.max_indexed_value;
280302
}
281303

304+
template<class Store, class Mapping>
305+
void DDSketch<Store, Mapping>::check_split_pints(const T *items, uint32_t size) {
306+
for (uint32_t i = 0; i < size ; i++) {
307+
if (std::isnan(items[i])) {
308+
throw std::invalid_argument("Values must not be NaN");
309+
}
310+
if ((i < (size - 1)) && !(items[i] < items[i + 1])) {
311+
throw std::invalid_argument("Values must be unique and monotonically increasing");
312+
}
313+
}
314+
}
315+
282316
}
283317

284318
#endif

0 commit comments

Comments
 (0)