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