LongSummary.java
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(_mean37;
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 > (double)sum(values)/values.length : NaN;
306     }
307 
308 }