001 /*
002 * Java Genetic Algorithm Library (jenetics-4.0.0).
003 * Copyright (c) 2007-2017 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.lang.Double.NaN;
023 import static java.util.Objects.requireNonNull;
024
025 import java.io.Serializable;
026 import java.util.LongSummaryStatistics;
027 import java.util.function.ToLongFunction;
028 import java.util.stream.Collector;
029
030 /**
031 * <i>Value</i> objects which contains statistical summary information.
032 *
033 * @see java.util.LongSummaryStatistics
034 *
035 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
036 * @since 3.0
037 * @version 3.0
038 */
039 public final class LongSummary implements Serializable {
040
041 private static final long serialVersionUID = 1L;
042
043 private final long _count;
044 private final long _min;
045 private final long _max;
046 private final long _sum;
047 private final double _mean;
048
049 /**
050 * Create an immutable object which contains statistical summary values.
051 *
052 * @param count the count of values recorded
053 * @param min the minimum value
054 * @param max the maximum value
055 * @param sum the sum of the recorded values
056 * @param mean the arithmetic mean of values
057 */
058 private LongSummary(
059 final long count,
060 final long min,
061 final long max,
062 final long sum,
063 final double mean
064 ) {
065 _count = count;
066 _min = min;
067 _max = max;
068 _sum = sum;
069 _mean = mean;
070 }
071
072 /**
073 * Returns the count of values recorded.
074 *
075 * @return the count of recorded values
076 */
077 public long getCount() {
078 return _count;
079 }
080
081 /**
082 * Return the minimum value recorded, or {@code Long.MAX_VALUE} if no
083 * values have been recorded.
084 *
085 * @return the minimum value, or {@code Long.MAX_VALUE} if none
086 */
087 public long getMin() {
088 return _min;
089 }
090
091 /**
092 * Return the maximum value recorded, or {@code Long.MIN_VALUE} if no
093 * values have been recorded.
094 *
095 * @return the maximum value, or {@code Long.MIN_VALUE} if none
096 */
097 public long getMax() {
098 return _max;
099 }
100
101 /**
102 * Return the sum of values recorded, or zero if no values have been
103 * recorded.
104 *
105 * @return the sum of values, or zero if none
106 */
107 public long getSum() {
108 return _sum;
109 }
110
111 /**
112 * Return the arithmetic mean of values recorded, or zero if no values have
113 * been recorded.
114 *
115 * @return the arithmetic mean of values, or zero if none
116 */
117 public double getMean() {
118 return _mean;
119 }
120
121 @Override
122 public int hashCode() {
123 int hash = 17;
124 hash += 33*_count + 37;
125 hash += 33*_sum + 37;
126 hash += 33*_min + 37;
127 hash += 33*_max + 37;
128 hash += 33*Double.doubleToLongBits(_mean) + 37;
129 return hash;
130 }
131
132 @Override
133 public boolean equals(final Object obj) {
134 return obj instanceof LongSummary &&
135 _count == ((LongSummary)obj)._count &&
136 _sum == ((LongSummary)obj)._sum &&
137 _min == ((LongSummary)obj)._min &&
138 _max == ((LongSummary)obj)._max &&
139 Double.compare(_mean, ((LongSummary)obj)._mean) == 0;
140 }
141
142 @Override
143 public String toString() {
144 return String.format(
145 "LongSummary[N=%d, ∧=%s, ∨=%s, Σ=%s, μ=%s]",
146 getCount(), getMin(), getMax(), getSum(), getMean()
147 );
148 }
149
150 /**
151 * Create an immutable object which contains statistical summary values.
152 *
153 * @param count the count of values recorded
154 * @param min the minimum value
155 * @param max the maximum value
156 * @param sum the sum of the recorded values
157 * @param mean the arithmetic mean of values
158 * @return an immutable object which contains statistical values
159 */
160 public static LongSummary of(
161 final long count,
162 final long min,
163 final long max,
164 final long sum,
165 final double mean
166 ) {
167 return new LongSummary(
168 count,
169 min,
170 max,
171 sum,
172 mean
173 );
174 }
175
176 /**
177 * Return a new value object of the statistical summary, currently
178 * represented by the {@code statistics} object.
179 *
180 * @param statistics the creating (mutable) statistics class
181 * @return the statistical moments
182 */
183 public static LongSummary of(final LongSummaryStatistics statistics) {
184 return new LongSummary(
185 statistics.getCount(),
186 statistics.getMin(),
187 statistics.getMax(),
188 statistics.getSum(),
189 statistics.getAverage()
190 );
191 }
192
193 /**
194 * Return a {@code Collector} which applies an long-producing mapping
195 * function to each input element, and returns summary-statistics for the
196 * resulting values.
197 *
198 * <pre>{@code
199 * final Stream<SomeObject> stream = ...
200 * final LongSummary summary = stream
201 * .collect(toLongSummary(v -> v.longValue()));
202 * }</pre>
203 *
204 * @param mapper a mapping function to apply to each element
205 * @param <T> the type of the input elements
206 * @return a {@code Collector} implementing the summary-statistics reduction
207 * @throws java.lang.NullPointerException if the given {@code mapper} is
208 * {@code null}
209 */
210 public static <T> Collector<T, ?, LongSummary>
211 toLongSummary(final ToLongFunction<? super T> mapper) {
212 requireNonNull(mapper);
213 return Collector.of(
214 LongSummaryStatistics::new,
215 (a, b) -> a.accept(mapper.applyAsLong(b)),
216 (a, b) -> {a.combine(b); return a;},
217 LongSummary::of
218 );
219 }
220
221
222 /* *************************************************************************
223 * Some static helper methods.
224 **************************************************************************/
225
226 /**
227 * Return the minimum value of the given double array.
228 *
229 * @since 4.0
230 *
231 * @param values the array.
232 * @return the minimum value or {@link Long#MAX_VALUE} if the given array is
233 * empty.
234 * @throws NullPointerException if the given array is {@code null}.
235 */
236 public static long min(final long[] values) {
237 long min = Long.MAX_VALUE;
238 if (values.length > 0) {
239 min = values[0];
240
241 for (int i = 0; i < values.length; ++i) {
242 if (values[i] < min) {
243 min = values[i];
244 }
245 }
246 }
247
248 return min;
249 }
250
251 /**
252 * Return the maximum value of the given double array.
253 *
254 * @since 4.0
255 *
256 * @param values the array.
257 * @return the maximum value or {@link Long#MIN_VALUE} if the given array is
258 * empty.
259 * @throws NullPointerException if the given array is {@code null}.
260 */
261 public static long max(final long[] values) {
262 long max = Long.MIN_VALUE;
263 if (values.length > 0) {
264 max = values[0];
265
266 for (int i = 0; i < values.length; ++i) {
267 if (values[i] > max) {
268 max = values[i];
269 }
270 }
271 }
272
273 return max;
274 }
275
276 /**
277 * Return the sum of the given double array.
278 *
279 * @since 4.0
280 *
281 * @param values the values to sum up.
282 * @return the sum of the given {@code values}.
283 * @throws NullPointerException if the given array is {@code null}.
284 */
285 public static long sum(final long[] values) {
286 long sum = 0;
287 for (int i = values.length; --i >= 0;) {
288 sum += values[i];
289 }
290 return sum;
291 }
292
293 /**
294 * Returns a double describing the arithmetic mean of the values, or
295 * {@link Double#NaN} if the {@code values} array is empty.
296 *
297 * @since 4.0
298 *
299 * @param values the values to calculate the mean of
300 * @return the arithmetic mean of the given {@code values} or
301 * {@link Double#NaN} if the {@code values} array is empty
302 * @throws NullPointerException if the given array is {@code null}.
303 */
304 public static double mean(final long[] values) {
305 return values.length > 0 ? (double)sum(values)/values.length : NaN;
306 }
307
308 }
|