View Javadoc
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  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.util;
23  
24  import java.util.Collection;
25  import java.util.concurrent.CopyOnWriteArrayList;
26  
27  import org.hipparchus.exception.MathIllegalStateException;
28  
29  /**
30   * This abstract class provides a general framework for managing iterative
31   * algorithms. The maximum number of iterations can be set, and methods are
32   * provided to monitor the current iteration count. A lightweight event
33   * framework is also provided.
34   */
35  public class IterationManager {
36  
37      /** Keeps a count of the number of iterations. */
38      private final Incrementor iterations;
39  
40      /** The collection of all listeners attached to this iterative algorithm. */
41      private final Collection<IterationListener> listeners;
42  
43      /**
44       * Creates a new instance of this class.
45       *
46       * @param maxIterations the maximum number of iterations
47       */
48      public IterationManager(final int maxIterations) {
49          this.iterations = new Incrementor(maxIterations);
50          this.listeners  = new CopyOnWriteArrayList<>();
51      }
52  
53      /**
54       * Creates a new instance of this class.
55       *
56       * @param maxIterations the maximum number of iterations
57       * @param callBack the function to be called when the maximum number of
58       * iterations has been reached
59       * @throws org.hipparchus.exception.NullArgumentException if {@code callBack} is {@code null}
60       */
61      public IterationManager(final int maxIterations,
62                              final Incrementor.MaxCountExceededCallback callBack) {
63          this.iterations = new Incrementor(maxIterations, callBack);
64          this.listeners = new CopyOnWriteArrayList<>();
65      }
66  
67      /**
68       * Attaches a listener to this manager.
69       *
70       * @param listener A {@code IterationListener} object.
71       */
72      public void addIterationListener(final IterationListener listener) {
73          listeners.add(listener);
74      }
75  
76      /**
77       * Informs all registered listeners that the initial phase (prior to the
78       * main iteration loop) has been completed.
79       *
80       * @param e The {@link IterationEvent} object.
81       */
82      public void fireInitializationEvent(final IterationEvent e) {
83          for (IterationListener l : listeners) {
84              l.initializationPerformed(e);
85          }
86      }
87  
88      /**
89       * Informs all registered listeners that a new iteration (in the main
90       * iteration loop) has been performed.
91       *
92       * @param e The {@link IterationEvent} object.
93       */
94      public void fireIterationPerformedEvent(final IterationEvent e) {
95          for (IterationListener l : listeners) {
96              l.iterationPerformed(e);
97          }
98      }
99  
100     /**
101      * Informs all registered listeners that a new iteration (in the main
102      * iteration loop) has been started.
103      *
104      * @param e The {@link IterationEvent} object.
105      */
106     public void fireIterationStartedEvent(final IterationEvent e) {
107         for (IterationListener l : listeners) {
108             l.iterationStarted(e);
109         }
110     }
111 
112     /**
113      * Informs all registered listeners that the final phase (post-iterations)
114      * has been completed.
115      *
116      * @param e The {@link IterationEvent} object.
117      */
118     public void fireTerminationEvent(final IterationEvent e) {
119         for (IterationListener l : listeners) {
120             l.terminationPerformed(e);
121         }
122     }
123 
124     /**
125      * Returns the number of iterations of this solver, 0 if no iterations has
126      * been performed yet.
127      *
128      * @return the number of iterations.
129      */
130     public int getIterations() {
131         return iterations.getCount();
132     }
133 
134     /**
135      * Returns the maximum number of iterations.
136      *
137      * @return the maximum number of iterations.
138      */
139     public int getMaxIterations() {
140         return iterations.getMaximalCount();
141     }
142 
143     /**
144      * Increments the iteration count by one, and throws an exception if the
145      * maximum number of iterations is reached. This method should be called at
146      * the beginning of a new iteration.
147      *
148      * @throws MathIllegalStateException if the maximum number of iterations is
149      * reached.
150      */
151     public void incrementIterationCount()
152         throws MathIllegalStateException {
153         iterations.increment();
154     }
155 
156     /**
157      * Removes the specified iteration listener from the list of listeners
158      * currently attached to {@code this} object. Attempting to remove a
159      * listener which was <em>not</em> previously registered does not cause any
160      * error.
161      *
162      * @param listener The {@link IterationListener} to be removed.
163      */
164     public void removeIterationListener(final IterationListener listener) {
165         listeners.remove(listener);
166     }
167 
168     /**
169      * Sets the iteration count to 0. This method must be called during the
170      * initial phase.
171      */
172     public void resetIterationCount() {
173         iterations.reset();
174     }
175 }