001 /*
002 * Java Genetic Algorithm Library (jenetics-5.2.0).
003 * Copyright (c) 2007-2020 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019 */
020 package io.jenetics.stat;
021
022 import static java.util.Objects.requireNonNull;
023 import static io.jenetics.internal.util.Hashes.hash;
024
025 import java.io.Serializable;
026 import java.util.function.ToLongFunction;
027 import java.util.stream.Collector;
028
029 /**
030 * <i>Value</i> objects which contains statistical moments.
031 *
032 * @see io.jenetics.stat.LongMomentStatistics
033 *
034 * @implNote
035 * This class is immutable and thread-safe.
036 *
037 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
038 * @since 3.0
039 * @version 5.2
040 */
041 public final /*record*/ class LongMoments implements Serializable {
042
043 private static final long serialVersionUID = 1L;
044
045 private final long _count;
046 private final long _min;
047 private final long _max;
048 private final long _sum;
049 private final double _mean;
050 private final double _variance;
051 private final double _skewness;
052 private final double _kurtosis;
053
054
055 /**
056 * Create an immutable object which contains statistical values.
057 *
058 * @param count the count of values recorded
059 * @param min the minimum value
060 * @param max the maximum value
061 * @param sum the sum of the recorded values
062 * @param mean the arithmetic mean of values
063 * @param variance the variance of values
064 * @param skewness the skewness of values
065 * @param kurtosis the kurtosis of values
066 */
067 private LongMoments(
068 final long count,
069 final long min,
070 final long max,
071 final long sum,
072 final double mean,
073 final double variance,
074 final double skewness,
075 final double kurtosis
076 ) {
077 _count = count;
078 _min = min;
079 _max = max;
080 _sum = sum;
081 _mean = mean;
082 _variance = variance;
083 _skewness = skewness;
084 _kurtosis = kurtosis;
085 }
086
087 /**
088 * Returns the count of values recorded.
089 *
090 * @return the count of recorded values
091 */
092 public long count() {
093 return _count;
094 }
095
096 /**
097 * Returns the count of values recorded.
098 *
099 * @return the count of recorded values
100 * @deprecated Use {@link #count()} instead
101 */
102 @Deprecated
103 public long getCount() {
104 return _count;
105 }
106
107 /**
108 * Return the minimum value recorded, or {@code Long.MAX_VALUE} if no
109 * values have been recorded.
110 *
111 * @return the minimum value, or {@code Long.MAX_VALUE} if none
112 */
113 public long min() {
114 return _min;
115 }
116
117 /**
118 * Return the minimum value recorded, or {@code Long.MAX_VALUE} if no
119 * values have been recorded.
120 *
121 * @return the minimum value, or {@code Long.MAX_VALUE} if none
122 * @deprecated Use {@link #min()} instead
123 */
124 @Deprecated
125 public long getMin() {
126 return _min;
127 }
128
129 /**
130 * Return the maximum value recorded, or {@code Long.MIN_VALUE} if no
131 * values have been recorded.
132 *
133 * @return the maximum value, or {@code Long.MIN_VALUE} if none
134 */
135 public long max() {
136 return _max;
137 }
138
139 /**
140 * Return the maximum value recorded, or {@code Long.MIN_VALUE} if no
141 * values have been recorded.
142 *
143 * @return the maximum value, or {@code Long.MIN_VALUE} if none
144 * @deprecated Use {@link #max()} instead
145 */
146 @Deprecated
147 public long getMax() {
148 return _max;
149 }
150
151 /**
152 * Return the sum of values recorded, or zero if no values have been
153 * recorded.
154 *
155 * @return the sum of values, or zero if none
156 */
157 public long sum() {
158 return _sum;
159 }
160
161 /**
162 * Return the sum of values recorded, or zero if no values have been
163 * recorded.
164 *
165 * @return the sum of values, or zero if none
166 * @deprecated Use {@link #sum()} instead
167 */
168 @Deprecated
169 public long getSum() {
170 return _sum;
171 }
172
173 /**
174 * Return the arithmetic mean of values recorded, or zero if no values have
175 * been recorded.
176 *
177 * @return the arithmetic mean of values, or zero if none
178 */
179 public double mean() {
180 return _mean;
181 }
182
183 /**
184 * Return the arithmetic mean of values recorded, or zero if no values have
185 * been recorded.
186 *
187 * @return the arithmetic mean of values, or zero if none
188 * @deprecated Use {@link #mean()} instead
189 */
190 @Deprecated
191 public double getMean() {
192 return _mean;
193 }
194
195 /**
196 * Return the variance of values recorded, or {@code Double.NaN} if no
197 * values have been recorded.
198 *
199 * @return the variance of values, or {@code NaN} if none
200 */
201 public double variance() {
202 return _variance;
203 }
204
205 /**
206 * Return the variance of values recorded, or {@code Double.NaN} if no
207 * values have been recorded.
208 *
209 * @return the variance of values, or {@code NaN} if none
210 * @deprecated Use {@link #variance()} instead
211 */
212 @Deprecated
213 public double getVariance() {
214 return _variance;
215 }
216
217 /**
218 * Return the skewness of values recorded, or {@code Double.NaN} if less
219 * than two values have been recorded.
220 *
221 * @see <a href="https://en.wikipedia.org/wiki/Skewness">Skewness</a>
222 *
223 * @return the skewness of values, or {@code NaN} if less than two values
224 * have been recorded
225 */
226 public double skewness() {
227 return _skewness;
228 }
229
230 /**
231 * Return the skewness of values recorded, or {@code Double.NaN} if less
232 * than two values have been recorded.
233 *
234 * @see <a href="https://en.wikipedia.org/wiki/Skewness">Skewness</a>
235 *
236 * @return the skewness of values, or {@code NaN} if less than two values
237 * have been recorded
238 * @deprecated Use {@link #skewness()} instead
239 */
240 @Deprecated
241 public double getSkewness() {
242 return _skewness;
243 }
244
245 /**
246 * Return the kurtosis of values recorded, or {@code Double.NaN} if less
247 * than four values have been recorded.
248 *
249 * @see <a href="https://en.wikipedia.org/wiki/Kurtosis">Kurtosis</a>
250 *
251 * @return the kurtosis of values, or {@code NaN} if less than four values
252 * have been recorded
253 */
254 public double kurtosis() {
255 return _kurtosis;
256 }
257
258 /**
259 * Return the kurtosis of values recorded, or {@code Double.NaN} if less
260 * than four values have been recorded.
261 *
262 * @see <a href="https://en.wikipedia.org/wiki/Kurtosis">Kurtosis</a>
263 *
264 * @return the kurtosis of values, or {@code NaN} if less than four values
265 * have been recorded
266 * @deprecated Use {@link #kurtosis()} instead
267 */
268 @Deprecated
269 public double getKurtosis() {
270 return _kurtosis;
271 }
272
273 @Override
274 public int hashCode() {
275 return
276 hash(_count,
277 hash(_sum,
278 hash(_min,
279 hash(_max,
280 hash(_mean,
281 hash(_variance,
282 hash(_skewness,
283 hash(_kurtosis))))))));
284 }
285
286 @Override
287 public boolean equals(final Object obj) {
288 return obj == this ||
289 obj instanceof LongMoments &&
290 _count == ((LongMoments)obj)._count &&
291 _sum == ((LongMoments)obj)._sum &&
292 _min == ((LongMoments)obj)._min &&
293 _max == ((LongMoments)obj)._max &&
294 Double.compare(_mean, ((LongMoments)obj)._mean) == 0 &&
295 Double.compare(_variance, ((LongMoments)obj)._variance) == 0 &&
296 Double.compare(_skewness, ((LongMoments)obj)._skewness) == 0 &&
297 Double.compare(_kurtosis, ((LongMoments)obj)._kurtosis) == 0;
298 }
299
300 @Override
301 public String toString() {
302 return String.format(
303 "LongMoments[N=%d, ∧=%s, ∨=%s, Σ=%s, μ=%s, s²=%s, S=%s, K=%s]",
304 count(), min(), max(), sum(),
305 mean(), variance(), skewness(), kurtosis()
306 );
307 }
308
309 /**
310 * Create an immutable object which contains statistical values.
311 *
312 * @param count the count of values recorded
313 * @param min the minimum value
314 * @param max the maximum value
315 * @param sum the sum of the recorded values
316 * @param mean the arithmetic mean of values
317 * @param variance the variance of values
318 * @param skewness the skewness of values
319 * @param kurtosis the kurtosis of values
320 * @return an immutable object which contains statistical values
321 */
322 public static LongMoments of(
323 final long count,
324 final long min,
325 final long max,
326 final long sum,
327 final double mean,
328 final double variance,
329 final double skewness,
330 final double kurtosis
331 ) {
332 return new LongMoments(
333 count,
334 min,
335 max,
336 sum,
337 mean,
338 variance,
339 skewness,
340 kurtosis
341 );
342 }
343
344 /**
345 * Return a new value object of the statistical moments, currently
346 * represented by the {@code statistics} object.
347 *
348 * @param statistics the creating (mutable) statistics class
349 * @return the statistical moments
350 */
351 public static LongMoments of(final LongMomentStatistics statistics) {
352 return new LongMoments(
353 statistics.count(),
354 statistics.min(),
355 statistics.max(),
356 statistics.sum(),
357 statistics.mean(),
358 statistics.variance(),
359 statistics.skewness(),
360 statistics.kurtosis()
361 );
362 }
363
364 /**
365 * Return a {@code Collector} which returns moments-statistics for the
366 * resulting values.
367 *
368 * <pre>{@code
369 * final Stream<Long> stream = ...
370 * final LongMoments moments = stream.collect(toLongMoments()));
371 * }</pre>
372 *
373 * @since 4.1
374 *
375 * @param <N> the type of the input elements
376 * @return a {@code Collector} implementing the moments-statistics reduction
377 */
378 public static <N extends Number> Collector<N, ?, LongMoments>
379 toLongMoments() {
380 return toLongMoments(Number::longValue);
381 }
382
383 /**
384 * Return a {@code Collector} which applies an long-producing mapping
385 * function to each input element, and returns moments-statistics for the
386 * resulting values.
387 *
388 * <pre>{@code
389 * final Stream<SomeObject> stream = ...
390 * final LongMoments moments = stream
391 * .collect(toLongMoments(v -> v.longValue()));
392 * }</pre>
393 *
394 * @param mapper a mapping function to apply to each element
395 * @param <T> the type of the input elements
396 * @return a {@code Collector} implementing the moments-statistics reduction
397 * @throws java.lang.NullPointerException if the given {@code mapper} is
398 * {@code null}
399 */
400 public static <T> Collector<T, ?, LongMoments>
401 toLongMoments(final ToLongFunction<? super T> mapper) {
402 requireNonNull(mapper);
403 return Collector.of(
404 LongMomentStatistics::new,
405 (a, b) -> a.accept(mapper.applyAsLong(b)),
406 LongMomentStatistics::combine,
407 LongMoments::of
408 );
409 }
410
411 }
|