accumulators.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-1.5.0).
003  * Copyright (c) 2007-2013 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.util;
021 
022 import static java.lang.String.format;
023 import static java.util.Objects.requireNonNull;
024 import static org.jenetics.util.object.eq;
025 import static org.jenetics.util.object.hashCodeOf;
026 
027 import java.util.Iterator;
028 
029 import org.jscience.mathematics.structure.GroupAdditive;
030 
031 
032 /**
033  * Collection of some general purpose Accumulators and some static helper classes
034  * for accumulating.
035  *
036  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
037  @since 1.0
038  @version 1.0 &mdash; <em>$Date: 2013-11-22 $</em>
039  */
040 public final class accumulators extends StaticObject {
041     private accumulators() {}
042 
043     public static final Accumulator<Object> NULL = new Accumulator<Object>() {
044         @Override
045         public void accumulate(final Object value) {
046         }
047     };
048 
049     /**
050      * Calculates min value.
051      *
052      <p/>
053      <strong>Note that this implementation is not synchronized.</strong> If
054      * multiple threads access this object concurrently, and at least one of the
055      * threads modifies it, it must be synchronized externally.
056      *
057      @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
058      @since 1.0
059      @version 1.0 &ndash; <em>$Revision$</em>
060      */
061     public static final class Min<C extends Comparable<? super C>>
062         extends MappedAccumulator<C>
063     {
064         private C _min;
065 
066         /**
067          * Create a new Min accumulator.
068          */
069         public Min() {
070         }
071 
072         /**
073          * Copy constructor.
074          *
075          @param min the accumulator to copy.
076          @throws NullPointerException if {@code min} is {@code null}.
077          */
078         public Min(final Min<C> min) {
079             requireNonNull(min, "Min");
080             _samples = min._samples;
081             _min = min._min;
082         }
083 
084         /**
085          * Return the min value, accumulated so far.
086          *
087          @return the min value, accumulated so far.
088          */
089         public C getMin() {
090             return _min;
091         }
092 
093         /**
094          @throws NullPointerException if the given {@code value} is {@code null}.
095          */
096         @Override
097         public void accumulate(final C value) {
098             if (_min == null) {
099                 _min = value;
100             else {
101                 if (value.compareTo(_min0) {
102                     _min = value;
103                 }
104             }
105 
106             ++_samples;
107         }
108 
109         @Override
110         public int hashCode() {
111             return hashCodeOf(getClass()).and(super.hashCode()).and(_min).value();
112         }
113 
114         @Override
115         public boolean equals(final Object obj) {
116             if (obj == this) {
117                 return true;
118             }
119             if (obj == null || obj.getClass() != getClass()) {
120                 return false;
121             }
122 
123             final Min<?> min = (Min<?>)obj;
124             return super.equals(obj&& eq(_min, min._min);
125         }
126 
127         @Override
128         public String toString() {
129             return format(
130                     "%s[samples=%d, min=%s]",
131                     getClass().getSimpleName(), getSamples(), getMin()
132                 );
133         }
134 
135         @Override
136         public Min<C> clone() {
137             return (Min<C>)super.clone();
138         }
139     }
140 
141 
142     /**
143      * Calculates max value.
144      *
145      <p/>
146      <strong>Note that this implementation is not synchronized.</strong> If
147      * multiple threads access this object concurrently, and at least one of the
148      * threads modifies it, it must be synchronized externally.
149      *
150      @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
151      @since 1.0
152      @version 1.0 &ndash; <em>$Revision$</em>
153      */
154     public static final class Max<C extends Comparable<? super C>>
155         extends MappedAccumulator<C>
156     {
157         private C _max;
158 
159         /**
160          * Create a new Max accumulator.
161          */
162         public Max() {
163         }
164 
165         /**
166          * Copy constructor.
167          *
168          @param max the accumulator to copy.
169          @throws NullPointerException if {@code max} is {@code null}.
170          */
171         public Max(final Max<C> max) {
172             requireNonNull(max, "Max");
173             _samples = max._samples;
174             _max = max._max;
175         }
176 
177         /**
178          * Return the max value, accumulated so far.
179          *
180          @return the max value, accumulated so far.
181          */
182         public C getMax() {
183             return _max;
184         }
185 
186         /**
187          @throws NullPointerException if the given {@code value} is {@code null}.
188          */
189         @Override
190         public void accumulate(final C value) {
191             if (_max == null) {
192                 _max = value;
193             else {
194                 if (value.compareTo(_max0) {
195                     _max = value;
196                 }
197             }
198 
199             ++_samples;
200         }
201 
202         @Override
203         public int hashCode() {
204             return hashCodeOf(getClass()).and(super.hashCode()).and(_max).value();
205         }
206 
207         @Override
208         public boolean equals(final Object obj) {
209             if (obj == this) {
210                 return true;
211             }
212             if (obj == null || obj.getClass() != getClass()) {
213                 return false;
214             }
215 
216             final Max<?> max = (Max<?>)obj;
217             return super.equals(obj&& eq(_max, max._max);
218         }
219 
220         @Override
221         public String toString() {
222             return format(
223                     "%s[samples=%d, max=%s]",
224                     getClass().getSimpleName(), getSamples(), getMax()
225                 );
226         }
227 
228         @Override
229         public Max<C> clone() {
230             return (Max<C>)super.clone();
231         }
232     }
233 
234 
235     /**
236      * Calculates min and max values.
237      *
238      <p/>
239      <strong>Note that this implementation is not synchronized.</strong> If
240      * multiple threads access this object concurrently, and at least one of the
241      * threads modifies it, it must be synchronized externally.
242      *
243      @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
244      @since 1.0
245      @version 1.0 &ndash; <em>$Revision$</em>
246      */
247     public static final class MinMax<C extends Comparable<? super C>>
248         extends MappedAccumulator<C>
249     {
250         private C _min;
251         private C _max;
252 
253         /**
254          * Create a new min-max accumulator.
255          */
256         public MinMax() {
257         }
258 
259         /**
260          * Copy constructor.
261          *
262          @param mm the accumulator to copy.
263          @throws NullPointerException if {@code mm} is {@code null}.
264          */
265         public MinMax(final MinMax<C> mm) {
266             requireNonNull(mm, "MinMax");
267             _samples = mm._samples;
268             _min = mm._min;
269             _max = mm._max;
270         }
271 
272         /**
273          * Return the min value, accumulated so far.
274          *
275          @return the min value, accumulated so far.
276          */
277         public C getMin() {
278             return _min;
279         }
280 
281         /**
282          * Return the max value, accumulated so far.
283          *
284          @return the max value, accumulated so far.
285          */
286         public C getMax() {
287             return _max;
288         }
289 
290         /**
291          @throws NullPointerException if the given {@code value} is {@code null}.
292          */
293         @Override
294         public void accumulate(final C value) {
295             if (_min == null) {
296                 _min = value;
297                 _max = value;
298             else {
299                 if (value.compareTo(_min0) {
300                     _min = value;
301                 else if (value.compareTo(_max0) {
302                     _max = value;
303                 }
304             }
305 
306             ++_samples;
307         }
308 
309         @Override
310         public int hashCode() {
311             return hashCodeOf(getClass()).
312                     and(super.hashCode()).
313                     and(_min).
314                     and(_max).value();
315         }
316 
317         @Override
318         public boolean equals(final Object obj) {
319             if (obj == this) {
320                 return true;
321             }
322             if (obj == null || obj.getClass() != getClass()) {
323                 return false;
324             }
325 
326             final MinMax<?> mm = (MinMax<?>)obj;
327             return super.equals(obj&& eq(_min, mm._min&& eq(_max, mm._max);
328         }
329 
330         @Override
331         public String toString() {
332             return format(
333                     "%s[samples=%d, min=%s, max=%s]",
334                     getClass().getSimpleName(), getSamples(), getMin(), getMax()
335                 );
336         }
337 
338         @Override
339         public MinMax<C> clone() {
340             return (MinMax<C>)super.clone();
341         }
342     }
343 
344     /**
345      * Calculates the sum of the accumulated values.
346      *
347      <p/>
348      <strong>Note that this implementation is not synchronized.</strong> If
349      * multiple threads access this object concurrently, and at least one of the
350      * threads modifies it, it must be synchronized externally.
351      *
352      @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
353      @since 1.0
354      @version 1.0 &ndash; <em>$Revision$</em>
355      */
356     public static class Sum<G extends GroupAdditive<G>>
357         extends MappedAccumulator<G>
358     {
359 
360         private G _sum = null;
361 
362         public Sum() {
363         }
364 
365         public Sum(final G start) {
366             _sum = start;
367         }
368 
369         @Override
370         public void accumulate(final G value) {
371             if (_sum == null) {
372                 _sum = value;
373             else {
374                 _sum = _sum.plus(value);
375             }
376 
377             ++_samples;
378         }
379 
380         public G getSum() {
381             return _sum;
382         }
383 
384     }
385 
386     /**
387      * Calls the {@link Accumulator#accumulate(Object)} method of all given
388      * {@code accumulators} with each value of the given {@code values}. The
389      * accumulation is done in parallel.
390      *
391      @param <T> the value type.
392      @param values the values to accumulate.
393      @param accus the accumulators to apply.
394      @throws NullPointerException if one of the given arguments is {@code null}.
395      */
396     public static <T> void accumulate(
397         final Iterable<? extends T> values,
398         final Seq<? extends Accumulator<? super T>> accus
399     ) {
400         switch (accus.length()) {
401         case 1:
402             accumulators.<T>accumulate(
403                 values,
404                 accus.get(0)
405             );
406             break;
407         case 2:
408             accumulators.<T>accumulate(
409                 values,
410                 accus.get(0),
411                 accus.get(1)
412             );
413             break;
414         case 3:
415             accumulators.<T>accumulate(
416                 values,
417                 accus.get(0),
418                 accus.get(1),
419                 accus.get(2)
420             );
421             break;
422         case 4:
423             accumulators.<T>accumulate(
424                 values,
425                 accus.get(0),
426                 accus.get(1),
427                 accus.get(2),
428                 accus.get(3)
429             );
430             break;
431         case 5:
432             accumulators.<T>accumulate(
433                 values,
434                 accus.get(0),
435                 accus.get(1),
436                 accus.get(2),
437                 accus.get(3),
438                 accus.get(4)
439             );
440             break;
441         default:
442             try (Concurrency c = Concurrency.start()) {
443                 for (final Accumulator<? super T> accumulator : accus) {
444                     c.execute(new Acc<>(values, accumulator));
445                 }
446             }
447         }
448     }
449 
450     /**
451      * Calls the {@link Accumulator#accumulate(Object)} method of all given
452      * {@code accumulators} with each value of the given {@code values}. The
453      * accumulation is done in parallel.
454      *
455      @param <T> the value type.
456      @param values the values to accumulate.
457      @param accus the accumulators to apply.
458      @throws NullPointerException if one of the given arguments is {@code null}.
459      */
460     @SafeVarargs
461     public static <T> void accumulate(
462         final Iterable<? extends T> values,
463         final Accumulator<? super T>... accus
464     ) {
465         accumulate(values, Array.valueOf(accus));
466     }
467 
468     /**
469      * Calls the {@link Accumulator#accumulate(Object)} method of the given
470      * {@code accumulator} with each value of the given {@code values}.
471      *
472      @param <T> the value type.
473      @param values the values to accumulate.
474      @param a the accumulator.
475      @throws NullPointerException if one of the given arguments is {@code null}.
476      */
477     public static <T> void accumulate(
478         final Iterator<? extends T> values,
479         final Accumulator<? super T> a
480     ) {
481         while (values.hasNext()) {
482             a.accumulate(values.next());
483         }
484     }
485 
486     /**
487      * Calls the {@link Accumulator#accumulate(Object)} method of the given
488      * {@code accumulator} with each value of the given {@code values}.
489      *
490      @param <T> the value type.
491      @param values the values to accumulate.
492      @param a the accumulator.
493      @throws NullPointerException if one of the given arguments is {@code null}.
494      */
495     public static <T> void accumulate(
496         final Iterable<? extends T> values,
497         final Accumulator<? super T> a
498     ) {
499         for (final T value : values) {
500             a.accumulate(value);
501         }
502     }
503 
504     /**
505      * Calls the {@link Accumulator#accumulate(Object)} method of all given
506      * {@code accumulators} with each value of the given {@code values}. The
507      * accumulation is done in parallel.
508      *
509      @param <T> the value type.
510      @param values the values to accumulate.
511      @param a1 the first accumulator.
512      @param a2 the second accumulator.
513      @throws NullPointerException if one of the given arguments is {@code null}.
514      */
515     public static <T> void accumulate(
516         final Iterable<? extends T> values,
517         final Accumulator<? super T> a1,
518         final Accumulator<? super T> a2
519     ) {
520         try (Concurrency c = Concurrency.start()) {
521             c.execute(new Acc<>(values, a1));
522             c.execute(new Acc<>(values, a2));;
523         }
524     }
525 
526     /**
527      * Calls the {@link Accumulator#accumulate(Object)} method of all given
528      * {@code accumulators} with each value of the given {@code values}. The
529      * accumulation is done in parallel.
530      *
531      @param <T> the value type.
532      @param values the values to accumulate.
533      @param a1 the first accumulator.
534      @param a2 the second accumulator.
535      @param a3 the third accumulator
536      @throws NullPointerException if one of the given arguments is {@code null}.
537      */
538     public static <T> void accumulate(
539         final Iterable<? extends T> values,
540         final Accumulator<? super T> a1,
541         final Accumulator<? super T> a2,
542         final Accumulator<? super T> a3
543     ) {
544         try (Concurrency c = Concurrency.start()) {
545             c.execute(new Acc<>(values, a1));
546             c.execute(new Acc<>(values, a2));
547             c.execute(new Acc<>(values, a3));
548         }
549     }
550 
551     /**
552      * Calls the {@link Accumulator#accumulate(Object)} method of all given
553      * {@code accumulators} with each value of the given {@code values}. The
554      * accumulation is done in parallel.
555      *
556      @param <T> the value type.
557      @param values the values to accumulate.
558      @param a1 the first accumulator.
559      @param a2 the second accumulator.
560      @param a3 the third accumulator.
561      @param a4 the fourth accumulator.
562      @throws NullPointerException if one of the given arguments is {@code null}.
563      */
564     public static <T> void accumulate(
565         final Iterable<? extends T> values,
566         final Accumulator<? super T> a1,
567         final Accumulator<? super T> a2,
568         final Accumulator<? super T> a3,
569         final Accumulator<? super T> a4
570     ) {
571         try (Concurrency c = Concurrency.start()) {
572             c.execute(new Acc<>(values, a1));
573             c.execute(new Acc<>(values, a2));
574             c.execute(new Acc<>(values, a3));
575             c.execute(new Acc<>(values, a4));
576         }
577     }
578 
579     /**
580      * Calls the {@link Accumulator#accumulate(Object)} method of all given
581      * {@code accumulators} with each value of the given {@code values}. The
582      * accumulation is done in parallel.
583      *
584      @param <T> the value type.
585      @param values the values to accumulate.
586      @param a1 the first accumulator.
587      @param a2 the second accumulator.
588      @param a3 the third accumulator.
589      @param a4 the fourth accumulator.
590      @param a5 the fifth accumulator.
591      @throws NullPointerException if one of the given arguments is {@code null}.
592      */
593     public static <T> void accumulate(
594         final Iterable<? extends T> values,
595         final Accumulator<? super T> a1,
596         final Accumulator<? super T> a2,
597         final Accumulator<? super T> a3,
598         final Accumulator<? super T> a4,
599         final Accumulator<? super T> a5
600     ) {
601         try (Concurrency c = Concurrency.start()) {
602             c.execute(new Acc<>(values, a1));
603             c.execute(new Acc<>(values, a2));
604             c.execute(new Acc<>(values, a3));
605             c.execute(new Acc<>(values, a4));
606             c.execute(new Acc<>(values, a5));
607         }
608     }
609 
610     private static final class Acc<T> implements Runnable {
611         private final Iterable<? extends T> _values;
612         private final Accumulator<? super T> _accumulator;
613 
614         public Acc(
615             final Iterable<? extends T> values,
616             final Accumulator<? super T> accumulator
617         ) {
618             _values = values;
619             _accumulator = accumulator;
620         }
621 
622         @Override
623         public void run() {
624             for (final T value : _values) {
625                 _accumulator.accumulate(value);
626             }
627         }
628     }
629 
630 }
631