• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

apache / datasketches-java / #306

30 Apr 2024 10:01PM UTC coverage: 97.645% (-0.5%) from 98.139%
#306

push

web-flow
Merge pull request #555 from apache/fix_pom_xml_header

Fix pom xml header

26865 of 27513 relevant lines covered (97.64%)

0.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.51
/src/main/java/org/apache/datasketches/quantilescommon/QuantilesUtil.java
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one
3
 * or more contributor license agreements.  See the NOTICE file
4
 * distributed with this work for additional information
5
 * regarding copyright ownership.  The ASF licenses this file
6
 * to you under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in compliance
8
 * with the License.  You may obtain a copy of the License at
9
 *
10
 *   http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19

20
package org.apache.datasketches.quantilescommon;
21

22
import static java.lang.Math.log;
23
import static java.lang.Math.pow;
24
import static org.apache.datasketches.quantilescommon.QuantileSearchCriteria.INCLUSIVE;
25

26
import java.util.Objects;
27

28
import org.apache.datasketches.common.SketchesArgumentException;
29
import org.apache.datasketches.common.Util;
30

31
/**
32
 * Utilities for the quantiles sketches.
33
 *
34
 * @author Lee Rhodes
35
 */
36
public final class QuantilesUtil {
37

38
  private QuantilesUtil() {}
39

40
  /**
41
   * Checks that the given normalized rank: <i>0 &le; nRank &le; 1.0</i>.
42
   * @param nRank the given normalized rank.
43
   */
44
  public static final void checkNormalizedRankBounds(final double nRank) {
45
    if ((nRank < 0.0) || (nRank > 1.0)) {
1✔
46
      throw new SketchesArgumentException(
1✔
47
          "A normalized rank must be >= 0 and <= 1.0: " + nRank);
48
    }
49
  }
1✔
50

51
  /**
52
   * Checks the sequential validity of the given array of double values.
53
   * They must be unique, monotonically increasing and not NaN.
54
   * @param values the given array of double values
55
   */
56
  public static final void checkDoublesSplitPointsOrder(final double[] values) {
57
    Objects.requireNonNull(values);
1✔
58
    final int len = values.length;
1✔
59
    if (len == 1 && Double.isNaN(values[0])) {
1✔
60
      throw new SketchesArgumentException(
1✔
61
        "Values must be unique, monotonically increasing and not NaN.");
62
    }
63
    for (int j = 0; j < len - 1; j++) {
1✔
64
      if (values[j] < values[j + 1]) { continue; }
1✔
65
      throw new SketchesArgumentException(
1✔
66
          "Values must be unique, monotonically increasing and not NaN.");
67
    }
68
  }
1✔
69

70
  /**
71
   * Checks the sequential validity of the given array of float values.
72
   * They must be unique, monotonically increasing and not NaN.
73
   * @param values the given array of double values
74
   */
75
  public static final void checkFloatsSplitPointsOrder(final float[] values) {
76
    Objects.requireNonNull(values);
1✔
77
    final int len = values.length;
1✔
78
    if (len == 1 && Float.isNaN(values[0])) {
1✔
79
      throw new SketchesArgumentException(
1✔
80
        "Values must be unique, monotonically increasing and not NaN.");
81
    }
82
    for (int j = 0; j < len - 1; j++) {
1✔
83
      if (values[j] < values[j + 1]) { continue; }
1✔
84
      throw new SketchesArgumentException(
1✔
85
          "Values must be unique, monotonically increasing and not NaN.");
86
    }
87
  }
1✔
88

89
  /**
90
   * Returns an array of (<i>num</i> + 1) values that define equally sized intervals between 0.0, inclusive, and 1.0,
91
   * inclusive. The end points 0.0 and 1.0 are part of the returned array.
92
   *
93
   * <p>For example, if num == 2, three values will be returned: 0.0, .5, and 1, where the two equally sized regions
94
   * are {0.0,0.5}, and {0.5, 1.0}.</p>
95
   * @param num the total number of equally sized intervals between 0.0, inclusive and 1.0, inclusive.
96
   * Must be 1 or greater.
97
   * @return a double array of values that define (num + 1) equally sized intervals between 0.0, inclusive and 1.0,
98
   * inclusive.
99
   * @throws IllegalArgumentException if <i>num</i> is less than 1.
100
   */
101
  public static double[] equallySpacedDoubles(final int num) {
102
    if (num < 1) { throw new IllegalArgumentException("num must be >= 1"); }
1✔
103
    final double[] out = new double[num + 1];
1✔
104
    out[0] = 0.0;
1✔
105
    out[num] = 1.0;
1✔
106
    final double delta = 1.0 / num;
1✔
107
    for (int i = 1; i < num; i++) { out[i] = i * delta; }
1✔
108
    return out;
1✔
109
  }
110

111
  /**
112
   * Returns an array of (<i>num</i> + 1) longs that define, approximately, equally spaced intervals between the given
113
   * <i>max</i>, inclusive, and <i>min</i>, inclusive. The end points <i>max</i> and <i>min</i> are part of the
114
   * returned array. Because the range of the values may not exactly divide into <i>num</i> intervals,
115
   * the size of these intervals may vary by plus or minus one.
116
   * @param min the lowest positive valued (or zero) number of the range
117
   * @param max the highest positive valued number of the range.  <i>max</i> must be greater than <i>min</i>
118
   * @param num Number of requested intervals. Must be greater or equal to one, and less than or equal to
119
   * <i>max - min</i>.
120
   *
121
   * @return an array of (<i>num</i> + 1) longs that are approximately equally spaced between the given min and max.
122
   */
123
  public static long[] equallySpacedLongs(final long min, final long max, final int num) {
124
    if (num < 1 || min < 0 || max < 1 || (min >= max) || num > (max - min)) {
1✔
125
      throw new SketchesArgumentException(
×
126
          "Improper inputs: n < 1, min < 0, max < 1, min >= max, or n > (max - min)");
127
    }
128
    final long span = (max - min);
1✔
129
    final double[] splits = equallySpacedDoubles(num);
1✔
130
    final int len = num + 1;
1✔
131
    final long[] out = new long[len];
1✔
132
    long prev = -1L;
1✔
133
    for (int i = 0; i < len; i++) {
1✔
134
      long cur = Math.round(splits[i] * span);
1✔
135
      if (cur == prev) { cur++; } else { prev = cur; }
1✔
136
      out[i] = min + cur;
1✔
137
    }
138
    return out;
1✔
139
  }
140

141
  /**
142
   * Returns a float array of evenly spaced values between value1, inclusive, and value2 inclusive.
143
   * If value2 &gt; value1, the resulting sequence will be increasing.
144
   * If value2 &lt; value1, the resulting sequence will be decreasing.
145
   * @param value1 will be in index 0 of the returned array
146
   * @param value2 will be in the highest index of the returned array
147
   * @param num the total number of values including value1 and value2. Must be 2 or greater.
148
   * @return a float array of evenly spaced values between value1, inclusive, and value2 inclusive.
149
   */
150
  public static float[] evenlySpacedFloats(final float value1, final float value2, final int num) {
151
    if (num < 2) {
1✔
152
      throw new SketchesArgumentException("num must be >= 2");
1✔
153
    }
154
    final float[] out = new float[num];
1✔
155
    out[0] = value1;
1✔
156
    out[num - 1] = value2;
1✔
157
    if (num == 2) { return out; }
1✔
158

159
    final float delta = (value2 - value1) / (num - 1);
1✔
160

161
    for (int i = 1; i < num - 1; i++) { out[i] = i * delta + value1; }
1✔
162
    return out;
1✔
163
  }
164

165
  /**
166
   * Returns a double array of evenly spaced values between value1, inclusive, and value2 inclusive.
167
   * If value2 &gt; value1, the resulting sequence will be increasing.
168
   * If value2 &lt; value1, the resulting sequence will be decreasing.
169
   * @param value1 will be in index 0 of the returned array
170
   * @param value2 will be in the highest index of the returned array
171
   * @param num the total number of values including value1 and value2. Must be 2 or greater.
172
   * @return a float array of evenly spaced values between value1, inclusive, and value2 inclusive.
173
   */
174
  public static double[] evenlySpacedDoubles(final double value1, final double value2, final int num) {
175
    if (num < 2) {
1✔
176
      throw new SketchesArgumentException("num must be >= 2");
1✔
177
    }
178
    final double[] out = new double[num];
1✔
179
    out[0] = value1;
1✔
180
    out[num - 1] = value2;
1✔
181
    if (num == 2) { return out; }
1✔
182

183
    final double delta = (value2 - value1) / (num - 1);
1✔
184

185
    for (int i = 1; i < num - 1; i++) { out[i] = i * delta + value1; }
1✔
186
    return out;
1✔
187
  }
188

189
  /**
190
   * Returns a double array of values between min and max inclusive where the log of the
191
   * returned values are evenly spaced.
192
   * If value2 &gt; value1, the resulting sequence will be increasing.
193
   * If value2 &lt; value1, the resulting sequence will be decreasing.
194
   * @param value1 will be in index 0 of the returned array, and must be greater than zero.
195
   * @param value2 will be in the highest index of the returned array, and must be greater than zero.
196
   * @param num the total number of values including value1 and value2. Must be 2 or greater
197
   * @return a double array of exponentially spaced values between value1 and value2 inclusive.
198
   */
199
  public static double[] evenlyLogSpaced(final double value1, final double value2, final int num) {
200
    if (num < 2) {
1✔
201
      throw new SketchesArgumentException("num must be >= 2");
1✔
202
    }
203
    if (value1 <= 0 || value2 <= 0) {
1✔
204
      throw new SketchesArgumentException("value1 and value2 must be > 0.");
1✔
205
    }
206

207
    final double[] arr = evenlySpacedDoubles(log(value1) / Util.LOG2, log(value2) / Util.LOG2, num);
1✔
208
    for (int i = 0; i < arr.length; i++) { arr[i] = pow(2.0,arr[i]); }
1✔
209
    return arr;
1✔
210
  }
211

212
  /** used in search to improve rounding over a wide dynamic range */
213
  public static final double tailRoundingFactor = 1e7;
214

215
  /**
216
   * Computes the closest Natural Rank from a given Normalized Rank
217
   * @param normalizedRank the given normalized rank
218
   * @param totalN the total N
219
   * @param searchCrit the search criterion.
220
   * @return the closest Natural Rank from a given Normalized Rank
221
   */
222
  public static double getNaturalRank(
223
      final double normalizedRank,
224
      final long totalN,
225
      final QuantileSearchCriteria searchCrit) {
226
    double naturalRank = (normalizedRank * totalN);
1✔
227
    if (totalN <= tailRoundingFactor) {
1✔
228
      naturalRank = Math.round(naturalRank * tailRoundingFactor) / tailRoundingFactor;
1✔
229
    }
230
    return (searchCrit == INCLUSIVE) ? (long)Math.ceil(naturalRank) : (long)Math.floor(naturalRank);
1✔
231
  }
232

233
}
234

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc