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.math4.optim;
018
019import org.apache.commons.math4.exception.TooManyEvaluationsException;
020import org.apache.commons.math4.exception.TooManyIterationsException;
021import org.apache.commons.math4.util.IntegerSequence;
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    @Override
063    public IntegerSequence.Incrementor getEvaluationCounter() {
064        return IntegerSequence.Incrementor.create()
065            .withMaximalCount(maxEvaluations)
066            .withCallback(MAX_EVAL_CALLBACK);
067    }
068
069    /** {@inheritDoc} */
070    @Override
071    public IntegerSequence.Incrementor getIterationCounter() {
072        return IntegerSequence.Incrementor.create()
073            .withMaximalCount(maxIterations)
074            .withCallback(MAX_ITER_CALLBACK);
075    }
076
077    /** {@inheritDoc} */
078    @Override
079    public ConvergenceChecker<PAIR> getConvergenceChecker() {
080        return checker;
081    }
082
083    /** Defines the action to perform when reaching the maximum number of evaluations. */
084    private static class MaxEvalCallback
085        implements IntegerSequence.Incrementor.MaxCountExceededCallback {
086        /**
087         * {@inheritDoc}
088         *
089         * @throws TooManyEvaluationsException
090         */
091        @Override
092        public void trigger(int max) {
093            throw new TooManyEvaluationsException(max);
094        }
095    }
096
097    /** Defines the action to perform when reaching the maximum number of evaluations. */
098    private static class MaxIterCallback
099        implements IntegerSequence.Incrementor.MaxCountExceededCallback {
100        /**
101         * {@inheritDoc}
102         *
103         * @throws TooManyIterationsException
104         */
105        @Override
106        public void trigger(int max) {
107            throw new TooManyIterationsException(max);
108        }
109    }
110
111}