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 */ 020package org.jenetics.util; 021 022import static java.lang.String.format; 023import static java.util.Objects.requireNonNull; 024import static org.jenetics.util.object.eq; 025import static org.jenetics.util.object.hashCodeOf; 026 027import java.util.Iterator; 028 029import 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 */ 040public 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 632