001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. 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 package org.apache.commons.math3.util; 018 019 import java.util.Collection; 020 import java.util.concurrent.CopyOnWriteArrayList; 021 022 import org.apache.commons.math3.exception.MaxCountExceededException; 023 024 /** 025 * This abstract class provides a general framework for managing iterative 026 * algorithms. The maximum number of iterations can be set, and methods are 027 * provided to monitor the current iteration count. A lightweight event 028 * framework is also provided. 029 * 030 * @version $Id: IterationManager.java 1422313 2012-12-15 18:53:41Z psteitz $ 031 */ 032 public class IterationManager { 033 034 /** Keeps a count of the number of iterations. */ 035 private final Incrementor iterations; 036 037 /** The collection of all listeners attached to this iterative algorithm. */ 038 private final Collection<IterationListener> listeners; 039 040 /** 041 * Creates a new instance of this class. 042 * 043 * @param maxIterations the maximum number of iterations 044 */ 045 public IterationManager(final int maxIterations) { 046 this.iterations = new Incrementor(maxIterations); 047 this.listeners = new CopyOnWriteArrayList<IterationListener>(); 048 } 049 050 /** 051 * Creates a new instance of this class. 052 * 053 * @param maxIterations the maximum number of iterations 054 * @param callBack the function to be called when the maximum number of 055 * iterations has been reached 056 * @throws org.apache.commons.math3.exception.NullArgumentException if {@code callBack} is {@code null} 057 * @since 3.1 058 */ 059 public IterationManager(final int maxIterations, 060 final Incrementor.MaxCountExceededCallback callBack) { 061 this.iterations = new Incrementor(maxIterations, callBack); 062 this.listeners = new CopyOnWriteArrayList<IterationListener>(); 063 } 064 065 /** 066 * Attaches a listener to this manager. 067 * 068 * @param listener A {@code IterationListener} object. 069 */ 070 public void addIterationListener(final IterationListener listener) { 071 listeners.add(listener); 072 } 073 074 /** 075 * Informs all registered listeners that the initial phase (prior to the 076 * main iteration loop) has been completed. 077 * 078 * @param e The {@link IterationEvent} object. 079 */ 080 public void fireInitializationEvent(final IterationEvent e) { 081 for (IterationListener l : listeners) { 082 l.initializationPerformed(e); 083 } 084 } 085 086 /** 087 * Informs all registered listeners that a new iteration (in the main 088 * iteration loop) has been performed. 089 * 090 * @param e The {@link IterationEvent} object. 091 */ 092 public void fireIterationPerformedEvent(final IterationEvent e) { 093 for (IterationListener l : listeners) { 094 l.iterationPerformed(e); 095 } 096 } 097 098 /** 099 * Informs all registered listeners that a new iteration (in the main 100 * iteration loop) has been started. 101 * 102 * @param e The {@link IterationEvent} object. 103 */ 104 public void fireIterationStartedEvent(final IterationEvent e) { 105 for (IterationListener l : listeners) { 106 l.iterationStarted(e); 107 } 108 } 109 110 /** 111 * Informs all registered listeners that the final phase (post-iterations) 112 * has been completed. 113 * 114 * @param e The {@link IterationEvent} object. 115 */ 116 public void fireTerminationEvent(final IterationEvent e) { 117 for (IterationListener l : listeners) { 118 l.terminationPerformed(e); 119 } 120 } 121 122 /** 123 * Returns the number of iterations of this solver, 0 if no iterations has 124 * been performed yet. 125 * 126 * @return the number of iterations. 127 */ 128 public int getIterations() { 129 return iterations.getCount(); 130 } 131 132 /** 133 * Returns the maximum number of iterations. 134 * 135 * @return the maximum number of iterations. 136 */ 137 public int getMaxIterations() { 138 return iterations.getMaximalCount(); 139 } 140 141 /** 142 * Increments the iteration count by one, and throws an exception if the 143 * maximum number of iterations is reached. This method should be called at 144 * the beginning of a new iteration. 145 * 146 * @throws MaxCountExceededException if the maximum number of iterations is 147 * reached. 148 */ 149 public void incrementIterationCount() 150 throws MaxCountExceededException { 151 iterations.incrementCount(); 152 } 153 154 /** 155 * Removes the specified iteration listener from the list of listeners 156 * currently attached to {@code this} object. Attempting to remove a 157 * listener which was <em>not</em> previously registered does not cause any 158 * error. 159 * 160 * @param listener The {@link IterationListener} to be removed. 161 */ 162 public void removeIterationListener(final IterationListener listener) { 163 listeners.remove(listener); 164 } 165 166 /** 167 * Sets the iteration count to 0. This method must be called during the 168 * initial phase. 169 */ 170 public void resetIterationCount() { 171 iterations.resetCount(); 172 } 173 }