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 */ 020package org.jenetics.util; 021 022import static java.lang.String.format; 023import static java.util.Objects.requireNonNull; 024import static org.jenetics.internal.util.object.eq; 025 026import java.util.Iterator; 027 028import org.jscience.mathematics.structure.GroupAdditive; 029 030import 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 */ 041public 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}