NumberStatistics.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-2.0.2).
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;
021 
022 import static java.lang.Double.NaN;
023 import static java.lang.String.format;
024 import static org.jenetics.internal.util.object.eq;
025 
026 import java.util.concurrent.Executor;
027 
028 import org.jenetics.internal.util.HashBuilder;
029 
030 import org.jenetics.stat.Variance;
031 import org.jenetics.util.accumulators;
032 import org.jenetics.util.accumulators.MinMax;
033 
034 /**
035  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
036  @since 1.0
037  @version 2.0 &mdash; <em>$Date: 2014-04-11 $</em>
038  */
039 public class NumberStatistics<
040     extends Gene<?, G>,
041     extends Number & Comparable<? super R>
042 >
043     extends Statistics<G, R>
044 {
045 
046     /**
047      * Builder for the NumberStatistics class.
048      *
049      @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
050      @since 1.0
051      @version 2.0 &mdash; <em>$Date: 2014-04-11 $</em>
052      */
053     public static class Builder<
054         extends Gene<?, G>,
055         extends Number & Comparable<? super R>
056     >
057         extends Statistics.Builder<G, R>
058     {
059         protected double _fitnessMean = NaN;
060         protected double _fitnessVariance = NaN;
061         protected double _standardError = NaN;
062 
063         /**
064          * Create a new NumberStatistics builder.
065          */
066         public Builder() {
067         }
068 
069         @Override
070         public Builder<G, R> statistics(final Statistics<G, R> statistics) {
071             super.statistics(statistics);
072             return this;
073         }
074 
075         /**
076          * Set the values of this builder with the values of the given
077          * {@code statistics}.
078          *
079          @param statistics the statistics values. If the {@code statistics}
080          *         is {@code null} nothing is set.
081          @return this builder instance.
082          */
083         public Builder<G, R> statistics(final NumberStatistics<G, R> statistics) {
084             if (statistics != null) {
085                 super.statistics(statistics);
086                 _fitnessMean = statistics._fitnessMean;
087                 _fitnessVariance = statistics._fitnessVariance;
088                 _standardError = statistics._standardError;
089             }
090             return this;
091         }
092 
093         /**
094          @see NumberStatistics#getFitnessMean()
095          *
096          @param fitnessMean the mean of the fitness value
097          @return this builder instance
098          */
099         public Builder<G, R> fitnessMean(final double fitnessMean) {
100             _fitnessMean = fitnessMean;
101             return this;
102         }
103 
104         /**
105          @see NumberStatistics#getFitnessVariance()
106          *
107          @param fitnessVariance the variance of the fitness value
108          @return this builder instance
109          */
110         public Builder<G, R> fitnessVariance(final double fitnessVariance) {
111             _fitnessVariance = fitnessVariance;
112             return this;
113         }
114 
115         /**
116          @see NumberStatistics#getStandardError()
117          *
118          @param standardError the standard error of the fitness mean value
119          @return this builder instancett
120          */
121         public Builder<G, R> standardError(final double standardError) {
122             _standardError = standardError;
123             return this;
124         }
125 
126         @Override
127         public NumberStatistics<G, R> build() {
128             return new NumberStatistics<>(
129                 _optimize,
130                 _generation,
131                 _best,
132                 _worst,
133                 _fitnessMean,
134                 _fitnessVariance,
135                 _samples,
136                 _ageMean,
137                 _ageVariance,
138                 _standardError,
139                 _killed,
140                 _invalid
141             );
142         }
143     }
144 
145     private static final long serialVersionUID = 3L;
146 
147     protected final double _fitnessMean;
148     protected final double _fitnessVariance;
149     protected final double _standardError;
150 
151     protected NumberStatistics(
152         final Optimize optimize,
153         final int generation,
154         final Phenotype<G, R> best,
155         final Phenotype<G, R> worst,
156         final double fitnessMean,
157         final double fitnessVariance,
158         final int samples,
159         final double ageMean,
160         final double ageVariance,
161         final double errorOfMean,
162         final int killed,
163         final int invalid
164     ) {
165         super(
166             optimize,
167             generation,
168             best,
169             worst,
170             samples,
171             ageMean,
172             ageVariance,
173             killed,
174             invalid
175         );
176 
177         _fitnessMean = fitnessMean;
178         _fitnessVariance = fitnessVariance;
179         _standardError = errorOfMean;
180     }
181 
182     /**
183      * Return the mean of the fitness values.
184      *
185      @return the mean of the fitness values.
186      */
187     public double getFitnessMean() {
188         return _fitnessMean;
189     }
190 
191     /**
192      * Return the variance of the fitness values.
193      *
194      @return the variance of the fitness values.
195      */
196     public double getFitnessVariance() {
197         return _fitnessVariance;
198     }
199 
200     /**
201      * Return the <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Standard_error_%28statistics%29">
202      * Standard error
203      </a> of the calculated fitness mean.
204      *
205      @return the standard error of the calculated fitness mean.
206      */
207     public double getStandardError() {
208         return _standardError;
209     }
210 
211     @Override
212     public int hashCode() {
213         return HashBuilder.of(getClass()).
214                 and(super.hashCode()).
215                 and(_fitnessMean).
216                 and(_fitnessVariance).
217                 and(_standardError).value();
218     }
219 
220     @Override
221     public boolean equals(final Object obj) {
222         if (obj == this) {
223             return true;
224         }
225         if (!(obj instanceof NumberStatistics<?, ?>)) {
226             return false;
227         }
228 
229         final NumberStatistics<?, ?> statistics = (NumberStatistics<?, ?>obj;
230         return eq(statistics._fitnessMean, _fitnessMean&&
231                 eq(statistics._fitnessVariance, _fitnessVariance&&
232                 eq(statistics._standardError, _standardError&&
233                 super.equals(obj);
234     }
235 
236     @Override
237     public String toString() {
238         final String fpattern = "| %28s: %-26.11f|\n";
239 
240         final StringBuilder out = new StringBuilder();
241         out.append(super.toString()).append("\n");
242         out.append("+---------------------------------------------------------+\n");
243         out.append("|  Fitness Statistics                                     |\n");
244         out.append("+---------------------------------------------------------+\n");
245         out.append(format(fpattern, "Fitness mean", _fitnessMean));
246         out.append(format(fpattern, "Fitness variance", _fitnessVariance));
247         out.append(format(fpattern, "Fitness error of mean", _standardError));
248         out.append("+---------------------------------------------------------+");
249 
250         return out.toString();
251     }
252 
253     /**
254      @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
255      @since 1.0
256      @version 2.0 &mdash; <em>$Date: 2014-04-11 $</em>
257      */
258     public static class Calculator<
259         extends Gene<?, G>,
260         extends Number & Comparable<? super R>
261     >
262         extends Statistics.Calculator<G, R>
263     {
264 
265         public Calculator() {
266         }
267 
268         @Override
269         public NumberStatistics.Builder<G, R> evaluate(
270             final Executor executor,
271             final Iterable<? extends Phenotype<G, R>> population,
272             final int generation,
273             final Optimize opt
274         ) {
275             final Builder<G, R> builder = new Builder<>();
276             builder.generation(generation);
277             builder.optimize(opt);
278 
279             final MinMax<Phenotype<G, R>> minMax = new MinMax<>();
280             final Variance<Integer> age = new Variance<>();
281             final Variance<R> fitness = new Variance<>();
282 
283             accumulators.accumulate(
284                     executor,
285                     population,
286                     minMax,
287                     age.map(Phenotype.Age(generation)),
288                     fitness.map(Phenotype.<R>Fitness())
289                 );
290             builder.bestPhenotype(opt.best(minMax.getMax(), minMax.getMin()));
291             builder.worstPhenotype(opt.worst(minMax.getMax(), minMax.getMin()));
292             builder.fitnessMean(fitness.getMean());
293             builder.fitnessVariance(fitness.getVariance());
294             builder.samples((int)minMax.getSamples());
295             builder.ageMean(age.getMean());
296             builder.ageVariance(age.getVariance());
297             builder.standardError(fitness.getStandardError());
298 
299             return builder;
300         }
301     }
302 
303 }