IterationManager.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.util;

  22. import java.util.Collection;
  23. import java.util.concurrent.CopyOnWriteArrayList;

  24. import org.hipparchus.exception.MathIllegalStateException;

  25. /**
  26.  * This abstract class provides a general framework for managing iterative
  27.  * algorithms. The maximum number of iterations can be set, and methods are
  28.  * provided to monitor the current iteration count. A lightweight event
  29.  * framework is also provided.
  30.  */
  31. public class IterationManager {

  32.     /** Keeps a count of the number of iterations. */
  33.     private final Incrementor iterations;

  34.     /** The collection of all listeners attached to this iterative algorithm. */
  35.     private final Collection<IterationListener> listeners;

  36.     /**
  37.      * Creates a new instance of this class.
  38.      *
  39.      * @param maxIterations the maximum number of iterations
  40.      */
  41.     public IterationManager(final int maxIterations) {
  42.         this.iterations = new Incrementor(maxIterations);
  43.         this.listeners  = new CopyOnWriteArrayList<>();
  44.     }

  45.     /**
  46.      * Creates a new instance of this class.
  47.      *
  48.      * @param maxIterations the maximum number of iterations
  49.      * @param callBack the function to be called when the maximum number of
  50.      * iterations has been reached
  51.      * @throws org.hipparchus.exception.NullArgumentException if {@code callBack} is {@code null}
  52.      */
  53.     public IterationManager(final int maxIterations,
  54.                             final Incrementor.MaxCountExceededCallback callBack) {
  55.         this.iterations = new Incrementor(maxIterations, callBack);
  56.         this.listeners = new CopyOnWriteArrayList<>();
  57.     }

  58.     /**
  59.      * Attaches a listener to this manager.
  60.      *
  61.      * @param listener A {@code IterationListener} object.
  62.      */
  63.     public void addIterationListener(final IterationListener listener) {
  64.         listeners.add(listener);
  65.     }

  66.     /**
  67.      * Informs all registered listeners that the initial phase (prior to the
  68.      * main iteration loop) has been completed.
  69.      *
  70.      * @param e The {@link IterationEvent} object.
  71.      */
  72.     public void fireInitializationEvent(final IterationEvent e) {
  73.         for (IterationListener l : listeners) {
  74.             l.initializationPerformed(e);
  75.         }
  76.     }

  77.     /**
  78.      * Informs all registered listeners that a new iteration (in the main
  79.      * iteration loop) has been performed.
  80.      *
  81.      * @param e The {@link IterationEvent} object.
  82.      */
  83.     public void fireIterationPerformedEvent(final IterationEvent e) {
  84.         for (IterationListener l : listeners) {
  85.             l.iterationPerformed(e);
  86.         }
  87.     }

  88.     /**
  89.      * Informs all registered listeners that a new iteration (in the main
  90.      * iteration loop) has been started.
  91.      *
  92.      * @param e The {@link IterationEvent} object.
  93.      */
  94.     public void fireIterationStartedEvent(final IterationEvent e) {
  95.         for (IterationListener l : listeners) {
  96.             l.iterationStarted(e);
  97.         }
  98.     }

  99.     /**
  100.      * Informs all registered listeners that the final phase (post-iterations)
  101.      * has been completed.
  102.      *
  103.      * @param e The {@link IterationEvent} object.
  104.      */
  105.     public void fireTerminationEvent(final IterationEvent e) {
  106.         for (IterationListener l : listeners) {
  107.             l.terminationPerformed(e);
  108.         }
  109.     }

  110.     /**
  111.      * Returns the number of iterations of this solver, 0 if no iterations has
  112.      * been performed yet.
  113.      *
  114.      * @return the number of iterations.
  115.      */
  116.     public int getIterations() {
  117.         return iterations.getCount();
  118.     }

  119.     /**
  120.      * Returns the maximum number of iterations.
  121.      *
  122.      * @return the maximum number of iterations.
  123.      */
  124.     public int getMaxIterations() {
  125.         return iterations.getMaximalCount();
  126.     }

  127.     /**
  128.      * Increments the iteration count by one, and throws an exception if the
  129.      * maximum number of iterations is reached. This method should be called at
  130.      * the beginning of a new iteration.
  131.      *
  132.      * @throws MathIllegalStateException if the maximum number of iterations is
  133.      * reached.
  134.      */
  135.     public void incrementIterationCount()
  136.         throws MathIllegalStateException {
  137.         iterations.increment();
  138.     }

  139.     /**
  140.      * Removes the specified iteration listener from the list of listeners
  141.      * currently attached to {@code this} object. Attempting to remove a
  142.      * listener which was <em>not</em> previously registered does not cause any
  143.      * error.
  144.      *
  145.      * @param listener The {@link IterationListener} to be removed.
  146.      */
  147.     public void removeIterationListener(final IterationListener listener) {
  148.         listeners.remove(listener);
  149.     }

  150.     /**
  151.      * Sets the iteration count to 0. This method must be called during the
  152.      * initial phase.
  153.      */
  154.     public void resetIterationCount() {
  155.         iterations.reset();
  156.     }
  157. }