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