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 — <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<SomeObject> stream = ...
203 * final DoubleSummary summary = stream
204 * .collect(toDoubleSummary(v -> 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 }
|