/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package edu.hawaii.jmotif.sampler; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.logging.ConsoleHandler; import java.util.logging.Formatter; import java.util.logging.Handler; import java.util.logging.Logger; import org.apache.commons.lang3.ArrayUtils; import org.hackystat.utilities.logger.HackystatLogger; import edu.hawaii.jmotif.text.SAXCollectionStrategy; import edu.hawaii.jmotif.util.BriefFormatter; /** * Simple solver encapsulating the optimization method calculation and checking method stop * condition together with a max iteration stop condition. * * @author ytoh */ // @Component(name="Basic solver", // description="Simple solver encapsulating the optimization method calculation and checking method stop condition together with a max iteration stop condition.") public class UCRSolver implements Solver, Callable<List<String>> { private static final Object COMMA = ","; // static final Logger logger = Logger.getLogger(BasicSolver.class); private Function function; private StopCondition[] methodConditions; private StopCondition[] systemConditions; private IterationStopCondition iterations; private Synchronization synchronization; private Consumer<? super Synchronization> synchronizationConsumer; private OptimizationMethod<? extends Telemetry> method; private BaseObjectiveFunction baseObjectiveFunction; // convenience shortcut private List<StopCondition> metConditions; // @Property(name="Maximum number of interations", // description="How many optimization steps are allowed before the optimization process is stopped.") // @Range(from=1, to=Integer.MAX_VALUE) private int maxIterations = Integer.MAX_VALUE; public int getMaxIterations() { return maxIterations; } public void setMaxIterations(int maxIterations) { this.maxIterations = maxIterations; } // @Property(name="Use delay") private boolean useDelay = false; public boolean isUseDelay() { return useDelay; } public void setUseDelay(boolean useDelay) { this.useDelay = useDelay; } // @Property(name="Delay between steps",description="How many miniseconds should this solver wait before doing another optimization step") // @Range(from=0,to=Integer.MAX_VALUE) private int milisDelay; private Logger consoleLogger; public int getMilisDelay() { return milisDelay; } public void setMilisDelay(int milisDelay) { this.milisDelay = milisDelay; } public PropertyState getMilisDelayState() { return useDelay ? PropertyState.ENABLED : PropertyState.DISABLED; } /** * Constructs an instance of <code>BasicSolver</code> with a special system stop condition making * sure that the optimization calculation doesn't exceed a certain count. * * @param maxIterations maximum number of main cycle iterations */ public UCRSolver(int maxIterations) { assert maxIterations > 0; this.maxIterations = maxIterations; // logger business consoleLogger = HackystatLogger.getLogger("debug.console", "preseries"); consoleLogger.setUseParentHandlers(false); for (Handler handler : consoleLogger.getHandlers()) { consoleLogger.removeHandler(handler); } ConsoleHandler handler = new ConsoleHandler(); Formatter formatter = new BriefFormatter(); handler.setFormatter(formatter); consoleLogger.addHandler(handler); HackystatLogger.setLoggingLevel(consoleLogger, "ALL"); } @SuppressWarnings("unchecked") public void init(Function function, @SuppressWarnings("rawtypes") OptimizationMethod method) throws Exception { this.function = function; this.method = method; baseObjectiveFunction = new BaseObjectiveFunction(function); if (!baseObjectiveFunction.hasAnalyticalGradient()) { baseObjectiveFunction.setNumericalGradient(new CentralDifferenceGradient()); } if (!baseObjectiveFunction.hasAnalyticalHessian()) { baseObjectiveFunction.setNumericalHessian(new CentralDifferenceHessian()); } synchronization = new Synchronization(); method.init(baseObjectiveFunction); // get method specific stop conditions methodConditions = ArrayUtils.clone(method.getStopConditions()); metConditions = new ArrayList<StopCondition>(); iterations = new IterationStopCondition(maxIterations); systemConditions = new StopCondition[] { iterations }; } public void addSystemStopCondition(StopCondition condition) { systemConditions = ArrayUtils.add(systemConditions, condition); } @Override public List<String> call() throws Exception { solve(); ValuePointListTelemetryColored res = (ValuePointListTelemetryColored) method.getValue(); List<String> resList = new ArrayList<String>(); for (ValuePointColored v : res.getValue()) { resList.add(toLogStr(v, function.getSAXSamplingStrategy())); } return resList; } private String toLogStr(ValuePointColored v, SAXCollectionStrategy saxCollectionStrategy) { StringBuffer sb = new StringBuffer(); // strategy if (saxCollectionStrategy.equals(SAXCollectionStrategy.CLASSIC)) { sb.append("CLASSIC,"); } else if (saxCollectionStrategy.equals(SAXCollectionStrategy.EXACT)) { sb.append("EXACT,"); } else if (saxCollectionStrategy.equals(SAXCollectionStrategy.NOREDUCTION)) { sb.append("NOREDUCTION,"); } // coordinate sb.append(v.getPoint().toArray()[0]).append(COMMA); sb.append(v.getPoint().toArray()[1]).append(COMMA); sb.append(v.getPoint().toArray()[2]).append(COMMA); // error value sb.append(v.getValue()); return sb.toString(); } public void solve() throws Exception { int iteration = 0; // logger.debug("main cycle start"); while (checkStopConditions()) { if (useDelay) { try { Thread.sleep(milisDelay); } catch (InterruptedException ex) { throw new OptimizationException("Stopping optimization", ex); } } consoleLogger.info("Iteration: " + iteration + " out of " + this.maxIterations + ", stats: " + baseObjectiveFunction.getStatistics()); synchronization = new Synchronization(++iteration); if (synchronizationConsumer != null) { synchronizationConsumer.notifyOf(this); } iterations.nextIteration(); // main optimization cycle method.optimize(); } } /** * Convenience method for checking stop condition satisfaction. * * @return true if any of the custom/system stop conditions have been met, else if no stop * conditions have been met */ private boolean checkStopConditions() { // logger.debug("checking stop conditions"); for (int i = 0; i < methodConditions.length; i++) { if (methodConditions[i].isConditionMet()) { // if(logger.isDebugEnabled()) { // logger.debug("condition met: " + methodConditions[i]); // } metConditions.add(methodConditions[i]); } } for (int i = 0; i < systemConditions.length; i++) { if (systemConditions[i].isConditionMet()) { // if(logger.isDebugEnabled()) { // logger.debug("condition met: " + systemConditions[i]); // } metConditions.add(systemConditions[i]); } } return metConditions.isEmpty(); } public OptimizationResults getResults() { return new OptimizationResults(method.getValue(), baseObjectiveFunction.getStatistics(), synchronization.getValue(), metConditions); } public void addConsumer(Consumer<? super Synchronization> consumer) { this.synchronizationConsumer = consumer; } public Synchronization getValue() { return synchronization; } }