private double interpolateTail(AVLGroupTree values, double x, int node, double mean, double extremeValue) { int count = values.count(node); assert count > 1; if (count == 2) { // other sample must be on the other side of the mean return 1.0 / size(); } else { // how much weight is available for interpolation? double weight = count / 2.0 - 1; // how much is between min and here? double partialWeight = (extremeValue - x) / (extremeValue - mean) * weight; // account for sample at min along with interpolated weight return (partialWeight + 1.0) / size(); } }
@Override public Centroid next() { final Centroid next = new Centroid(mean(nextNode), count(nextNode)); final List<Double> data = data(nextNode); if (data != null) { for (Double x : data) { next.insertData(x); } } nextNode = tree.next(nextNode); return next; }
/** * Return the last node so that the sum of counts of nodes that are before * it is less than or equal to <code>sum</code>. */ @SuppressWarnings("WeakerAccess") public int floorSum(long sum) { int floor = IntAVLTree.NIL; for (int node = tree.root(); node != IntAVLTree.NIL; ) { final int left = tree.left(node); final long leftCount = aggregatedCounts[left]; if (leftCount <= sum) { floor = node; sum -= leftCount + count(node); node = tree.right(node); } else { node = tree.left(node); } } return floor; }
double k0 = scale.max(n0 / count, compression, count); int node = summary.first(); int w0 = summary.count(node); double n1 = n0 + summary.count(node); int after = summary.next(node); while (after != IntAVLTree.NIL) { w1 = summary.count(after); k1 = scale.max((n1 + w1) / count, compression, count); if (w0 + w1 > Math.min(k0, k1)) {
assert minDistance == Math.abs(summary.mean(neighbor) - x); double q0 = (double) summary.headSum(neighbor) / count; double q1 = q0 + (double) summary.count(neighbor) / count; double k = Math.min(scale.max(q0, compression, count), scale.max(q1, compression, count)); if (summary.count(neighbor) + w <= k) { n++; if (gen.nextDouble() < 1 / n) { int count = summary.count(closest); List<Double> d = summary.data(closest); if (d != null) {
@Override public Centroid next() { final Centroid next = new Centroid(mean(nextNode), count(nextNode)); final List<Double> data = data(nextNode); if (data != null) { for (Double x : data) { next.insertData(x); } } nextNode = tree.next(nextNode); return next; }
/** * Return the last node so that the sum of counts of nodes that are before * it is less than or equal to <code>sum</code>. */ public int floorSum(long sum) { int floor = IntAVLTree.NIL; for (int node = tree.root(); node != IntAVLTree.NIL; ) { final int left = tree.left(node); final long leftCount = aggregatedCounts[left]; if (leftCount <= sum) { floor = node; sum -= leftCount + count(node); node = tree.right(node); } else { node = tree.left(node); } } return floor; }
for (int neighbor = start; neighbor != lastNeighbor; neighbor = summary.next(neighbor)) { assert minDistance == Math.abs(summary.mean(neighbor) - x); double q = count == 1 ? 0.5 : (sum + (summary.count(neighbor) - 1) / 2.0) / (count - 1); double k = 4 * count * q * (1 - q) / compression; if (summary.count(neighbor) + w <= k) { n++; if (gen.nextDouble() < 1 / n) { sum += summary.count(neighbor); int count = summary.count(closest); List<Double> d = summary.data(closest); if (d != null) {
if (prev != IntAVLTree.NIL) { previousMean = values.mean(prev); previousIndex = total - (values.count(prev) + 1.0) / 2; final double nextIndex = total + (values.count(next) - 1.0) / 2; if (nextIndex >= index) { if (Double.isNaN(previousMean)) { final double nextIndex2 = total + values.count(next) + (values.count(next2) - 1.0) / 2; previousMean = (nextIndex2 * values.mean(next) - nextIndex * values.mean(next2)) / (nextIndex2 - nextIndex); return quantile(nextIndex, index, nextIndex2, values.mean(next), nextMean2); total += values.count(next); previousMean = values.mean(next); previousIndex = nextIndex;
@Override public void compress() { if (summary.size() <= 1) { return; } AVLGroupTree centroids = summary; this.summary = new AVLGroupTree(recordAllData); final int[] nodes = new int[centroids.size()]; nodes[0] = centroids.first(); for (int i = 1; i < nodes.length; ++i) { nodes[i] = centroids.next(nodes[i-1]); assert nodes[i] != IntAVLTree.NIL; } assert centroids.next(nodes[nodes.length - 1]) == IntAVLTree.NIL; for (int i = centroids.size() - 1; i > 0; --i) { final int other = gen.nextInt(i + 1); final int tmp = nodes[other]; nodes[other] = nodes[i]; nodes[i] = tmp; } for (int node : nodes) { add(centroids.mean(node), centroids.count(node), centroids.data(node)); } }