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 — <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 – <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(_min) < 0) {
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 – <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(_max) > 0) {
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 – <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(_min) < 0) {
300 _min = value;
301 } else if (value.compareTo(_max) > 0) {
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 – <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
|