001 /*
002 * Java Genetic Algorithm Library (jenetics-8.0.0).
003 * Copyright (c) 2007-2024 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.Serial;
025 import java.io.Serializable;
026 import java.util.function.ToLongFunction;
027 import java.util.stream.Collector;
028
029 /**
030 * <i>Value</i> objects which contains statistical moments.
031 *
032 * @see io.jenetics.stat.LongMomentStatistics
033 *
034 * @param count the count of values recorded
035 * @param min the minimum value recorded, or {@link Long#MAX_VALUE} if no
036 * values have been recorded
037 * @param max the maximum value recorded, or {@link Long#MIN_VALUE} if no
038 * values have been recorded
039 * @param sum the sum of values recorded, or zero if no values have been recorded
040 * @param mean the arithmetic mean of values recorded, or zero if no values have
041 * been recorded
042 * @param variance the variance of values recorded, or {@link Double#NaN} if no
043 * values have been recorded
044 * @param skewness the <a href="https://en.wikipedia.org/wiki/Skewness">Skewness</a>
045 * of values recorded, or {@link Double#NaN} if less than two values have
046 * been recorded
047 * @param kurtosis the <a href="https://en.wikipedia.org/wiki/Kurtosis">Kurtosis</a>
048 * of values recorded, or {@link Double#NaN} if less than four values
049 * have been recorded
050 *
051 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
052 * @since 3.0
053 * @version 7.0
054 */
055 public record LongMoments(
056 long count,
057 long min,
058 long max,
059 long sum,
060 double mean,
061 double variance,
062 double skewness,
063 double kurtosis
064 )
065 implements Serializable
066 {
067
068 @Serial
069 private static final long serialVersionUID = 2;
070
071 @Override
072 public String toString() {
073 return String.format(
074 "LongMoments[N=%d, ∧=%s, ∨=%s, Σ=%s, μ=%s, s²=%s, S=%s, K=%s]",
075 count(), min(), max(), sum(),
076 mean(), variance(), skewness(), kurtosis()
077 );
078 }
079
080 /**
081 * Return a new value object of the statistical moments, currently
082 * represented by the {@code statistics} object.
083 *
084 * @param statistics the creating (mutable) statistics class
085 * @return the statistical moments
086 */
087 public static LongMoments of(final LongMomentStatistics statistics) {
088 return new LongMoments(
089 statistics.count(),
090 statistics.min(),
091 statistics.max(),
092 statistics.sum(),
093 statistics.mean(),
094 statistics.variance(),
095 statistics.skewness(),
096 statistics.kurtosis()
097 );
098 }
099
100 /**
101 * Return a {@code Collector} which returns moments-statistics for the
102 * resulting values.
103 *
104 * {@snippet lang="java":
105 * final Stream<Long> stream = null; // @replace substring='null' replacement="..."
106 * final LongMoments moments = stream.collect(toLongMoments());
107 * }
108 *
109 * @since 4.1
110 *
111 * @param <N> the type of the input elements
112 * @return a {@code Collector} implementing the moments-statistics reduction
113 */
114 public static <N extends Number> Collector<N, ?, LongMoments>
115 toLongMoments() {
116 return toLongMoments(Number::longValue);
117 }
118
119 /**
120 * Return a {@code Collector} which applies a long-producing mapping
121 * function to each input element, and returns moments-statistics for the
122 * resulting values.
123 *
124 * {@snippet lang="java":
125 * final Stream<SomeObject> stream = null; // @replace substring='null' replacement="..."
126 * final LongMoments moments = stream
127 * .collect(toLongMoments(v -> v.longValue()));
128 * }
129 *
130 * @param mapper a mapping function to apply to each element
131 * @param <T> the type of the input elements
132 * @return a {@code Collector} implementing the moments-statistics reduction
133 * @throws java.lang.NullPointerException if the given {@code mapper} is
134 * {@code null}
135 */
136 public static <T> Collector<T, ?, LongMoments>
137 toLongMoments(final ToLongFunction<? super T> mapper) {
138 requireNonNull(mapper);
139 return Collector.of(
140 LongMomentStatistics::new,
141 (a, b) -> a.accept(mapper.applyAsLong(b)),
142 LongMomentStatistics::combine,
143 LongMoments::of
144 );
145 }
146
147 }
|