LongMoments.java
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 }