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 */
017package org.apache.commons.math3.optim;
018
019import org.apache.commons.math3.exception.TooManyEvaluationsException;
020import org.apache.commons.math3.exception.TooManyIterationsException;
021import org.apache.commons.math3.util.Incrementor;
022
023/**
024 * Base class for implementing optimization problems. It contains the boiler-plate code
025 * for counting the number of evaluations of the objective function and the number of
026 * iterations of the algorithm, and storing the convergence checker.
027 *
028 * @param <PAIR> Type of the point/value pair returned by the optimization algorithm.
029 * @since 3.3
030 */
031public abstract class AbstractOptimizationProblem<PAIR>
032        implements OptimizationProblem<PAIR> {
033
034    /** Callback to use for the evaluation counter. */
035    private static final MaxEvalCallback MAX_EVAL_CALLBACK = new MaxEvalCallback();
036    /** Callback to use for the iteration counter. */
037    private static final MaxIterCallback MAX_ITER_CALLBACK = new MaxIterCallback();
038
039    /** max evaluations */
040    private final int maxEvaluations;
041    /** max iterations */
042    private final int maxIterations;
043    /** Convergence checker. */
044    private final ConvergenceChecker<PAIR> checker;
045
046    /**
047     * Create an {@link AbstractOptimizationProblem} from the given data.
048     *
049     * @param maxEvaluations the number of allowed model function evaluations.
050     * @param maxIterations  the number of allowed iterations.
051     * @param checker        the convergence checker.
052     */
053    protected AbstractOptimizationProblem(final int maxEvaluations,
054                                          final int maxIterations,
055                                          final ConvergenceChecker<PAIR> checker) {
056        this.maxEvaluations = maxEvaluations;
057        this.maxIterations = maxIterations;
058        this.checker = checker;
059    }
060
061    /** {@inheritDoc} */
062    public Incrementor getEvaluationCounter() {
063        return new Incrementor(this.maxEvaluations, MAX_EVAL_CALLBACK);
064    }
065
066    /** {@inheritDoc} */
067    public Incrementor getIterationCounter() {
068        return new Incrementor(this.maxIterations, MAX_ITER_CALLBACK);
069    }
070
071    /** {@inheritDoc} */
072    public ConvergenceChecker<PAIR> getConvergenceChecker() {
073        return checker;
074    }
075
076    /** Defines the action to perform when reaching the maximum number of evaluations. */
077    private static class MaxEvalCallback
078            implements Incrementor.MaxCountExceededCallback {
079        /**
080         * {@inheritDoc}
081         *
082         * @throws TooManyEvaluationsException
083         */
084        public void trigger(int max) {
085            throw new TooManyEvaluationsException(max);
086        }
087    }
088
089    /** Defines the action to perform when reaching the maximum number of evaluations. */
090    private static class MaxIterCallback
091            implements Incrementor.MaxCountExceededCallback {
092        /**
093         * {@inheritDoc}
094         *
095         * @throws TooManyIterationsException
096         */
097        public void trigger(int max) {
098            throw new TooManyIterationsException(max);
099        }
100    }
101
102}