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