DoubleSummary.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-3.0.0).
003  * Copyright (c) 2007-2014 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@gmx.at)
019  */
020 package org.jenetics.stat;
021 
022 import static java.util.Objects.requireNonNull;
023 import static org.jenetics.internal.util.Equality.eq;
024 
025 import java.io.Serializable;
026 import java.util.DoubleSummaryStatistics;
027 import java.util.function.ToDoubleFunction;
028 import java.util.stream.Collector;
029 
030 import org.jenetics.internal.util.Equality;
031 import org.jenetics.internal.util.Hash;
032 
033 /**
034  <i>Value</i> objects which contains statistical summary information.
035  *
036  @see java.util.DoubleSummaryStatistics
037  *
038  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
039  @since 3.0
040  @version 3.0 &mdash; <em>$Date: 2014-12-28 $</em>
041  */
042 public final class DoubleSummary implements Serializable {
043 
044     private static final long serialVersionUID = 1L;
045 
046     private final long _count;
047     private final double _min;
048     private final double _max;
049     private final double _sum;
050     private final double _mean;
051 
052     /**
053      * Create an immutable object which contains statistical summary values.
054      *
055      @param count the count of values recorded
056      @param min the minimum value
057      @param max the maximum value
058      @param sum the sum of the recorded values
059      @param mean the arithmetic mean of values
060      */
061     private DoubleSummary(
062         final long count,
063         final double min,
064         final double max,
065         final double sum,
066         final double mean
067     ) {
068         _count = count;
069         _min = min;
070         _max = max;
071         _sum = sum;
072         _mean = mean;
073     }
074 
075     /**
076      * Returns the count of values recorded.
077      *
078      @return the count of recorded values
079      */
080     public long getCount() {
081         return _count;
082     }
083 
084     /**
085      * Return the minimum value recorded, or {@code Double.POSITIVE_INFINITY} if
086      * no values have been recorded.
087      *
088      @return the minimum value, or {@code Double.POSITIVE_INFINITY} if none
089      */
090     public double getMin() {
091         return _min;
092     }
093 
094     /**
095      * Return the maximum value recorded, or {@code Double.NEGATIVE_INFINITY} if
096      * no values have been recorded.
097      *
098      @return the maximum value, or {@code Double.NEGATIVE_INFINITY} if none
099      */
100     public double getMax() {
101         return _max;
102     }
103 
104     /**
105      * Return the sum of values recorded, or zero if no values have been
106      * recorded.
107      *
108      @return the sum of values, or zero if none
109      */
110     public double getSum() {
111         return _sum;
112     }
113 
114     /**
115      * Return the arithmetic mean of values recorded, or zero if no values have
116      * been recorded.
117      *
118      @return the arithmetic mean of values, or zero if none
119      */
120     public double getMean() {
121         return _mean;
122     }
123 
124     @Override
125     public int hashCode() {
126         return Hash.of(DoubleMoments.class)
127             .and(_count)
128             .and(_sum)
129             .and(_min)
130             .and(_max)
131             .and(_mean).value();
132     }
133 
134     @Override
135     public boolean equals(final Object obj) {
136         return Equality.of(this, obj).test(summary ->
137             eq(_count, summary._count&&
138             eq(_sum, summary._sum&&
139             eq(_min, summary._min&&
140             eq(_max, summary._max&&
141             eq(_mean, summary._mean)
142         );
143     }
144 
145     @Override
146     public String toString() {
147         return String.format(
148             "DoubleSummary[N=%d, ∧=%s, ∨=%s, Σ=%s, μ=%s]",
149             getCount(), getMin(), getMax(), getSum(), getMean()
150         );
151     }
152 
153     /**
154      * Create an immutable object which contains statistical summary values.
155      *
156      @param count the count of values recorded
157      @param min the minimum value
158      @param max the maximum value
159      @param sum the sum of the recorded values
160      @param mean the arithmetic mean of values
161      @return an immutable object which contains statistical summary values
162      */
163     public static DoubleSummary of(
164         final long count,
165         final double min,
166         final double max,
167         final double sum,
168         final double mean
169     ) {
170         return new DoubleSummary(
171             count,
172             min,
173             max,
174             sum,
175             mean
176         );
177     }
178 
179     /**
180      * Return a new value object of the statistical summary, currently
181      * represented by the {@code statistics} object.
182      *
183      @param statistics the creating (mutable) statistics class
184      @return the statistical moments
185      */
186     public static DoubleSummary of(final DoubleSummaryStatistics statistics) {
187         return new DoubleSummary(
188             statistics.getCount(),
189             statistics.getMin(),
190             statistics.getMax(),
191             statistics.getSum(),
192             statistics.getAverage()
193         );
194     }
195 
196     /**
197      * Return a {@code Collector} which applies an double-producing mapping
198      * function to each input element, and returns summary-statistics for the
199      * resulting values.
200      *
201      * [code]
202      * final Stream&lt;SomeObject&gt; stream = ...
203      * final DoubleSummary summary = stream
204      *     .collect(toDoubleSummary(v -&gt; v.doubleValue()));
205      * [/code]
206      *
207      @param mapper a mapping function to apply to each element
208      @param <T> the type of the input elements
209      @return a {@code Collector} implementing the summary-statistics reduction
210      @throws java.lang.NullPointerException if the given {@code mapper} is
211      *         {@code null}
212      */
213     public static <T> Collector<T, ?, DoubleSummary>
214     toDoubleSummary(final ToDoubleFunction<? super T> mapper) {
215         requireNonNull(mapper);
216         return Collector.of(
217             DoubleSummaryStatistics::new,
218             (a, b-> a.accept(mapper.applyAsDouble(b)),
219             (a, b-> {a.combine(b)return a;},
220             DoubleSummary::of
221         );
222     }
223 
224 }