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