AbstractOptimizer.h
Go to the documentation of this file.
1//===========================================================================
2/*!
3 *
4 *
5 * \brief AbstractOptimizer
6 *
7 *
8 *
9 * \author T.Voss, T. Glasmachers, O.Krause
10 * \date 2010-2011
11 *
12 *
13 * \par Copyright 1995-2017 Shark Development Team
14 *
15 * <BR><HR>
16 * This file is part of Shark.
17 * <https://shark-ml.github.io/Shark/>
18 *
19 * Shark is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU Lesser General Public License as published
21 * by the Free Software Foundation, either version 3 of the License, or
22 * (at your option) any later version.
23 *
24 * Shark is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU Lesser General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public License
30 * along with Shark. If not, see <http://www.gnu.org/licenses/>.
31 *
32 */
33//===========================================================================
34#ifndef SHARK_OBJECTIVEFUNCTIONS_ABSTRACTOPTIMIZER_H
35#define SHARK_OBJECTIVEFUNCTIONS_ABSTRACTOPTIMIZER_H
36
38
39namespace shark {
40
41/// \defgroup optimizers Algorithms to find a local minimum of \ref objfunctions.
42
43
44
45/// \brief An optimizer that optimizes general objective functions
46///
47/// After construction and configurationg the optimizer, init() is called with the objective function
48/// to be used. After that step() can be called until the required solution is found. The solution can be queried
49/// using solution(). The type of the solution depends on the optimisation problem at hand.
50/// It is allowed to add constrains on the features the objective function needs to offer
51///
52/// These are:
53/// - REQUIRES_VALUE: The function is evaluated to use the optimizer and
54/// the HAS_VALUE-flag must be set
55/// - REQUIRES_FIRST_DERIVATIVE: The first derivative needs to be evaluated and
56/// - HAS_FIRST_DERIVATIVE must be set
57/// - REQUIRES_SECOND_DERIVATIVE: The second derivative needs to be evaluated and
58/// - HAS_SECOND_DERIVATIVE must be set
59/// - CAN_SOLVE_CONSTRAINED: The optimizer can solve functions which are constrained and
60/// where the IS_CONSTRAINED_FEATURE is set.
61/// - REQUIRES_CLOSEST_FEASIBLE: If the function is constrained, it must offer a way to
62/// construct the closest feasible point and
63/// - CAN_PROVIDE_CLOSEST_FEASIBLE must be set
64///
65/// Also when init() is called as offered by the AbstractOptimizer interface, the function
66/// is required to have the CAN_PROPOSE_STARTING_POINT flag.
67///
68/// \tparam PointType The type of search space the optimizer works upon.
69/// \tparam ResultT The objective space the optimizer works upon.
70/// \tparam SolutionTypeT The type of the final solution.
71/// \ingroup optimizers
72template <typename PointType, typename ResultT, typename SolutionTypeT>
74public:
75 typedef PointType SearchPointType;
76 typedef ResultT ResultType;
77 typedef SolutionTypeT SolutionType;
79
80 /// \brief Models features that the optimizer requires from the objective function.
81 /// \sa AbstractObjectiveFunction
89
91
92 bool requiresValue()const{
93 return features()& REQUIRES_VALUE;
94 }
95
104 }
108
110
111 /// \brief Returns the number of points this method requires for initialisation
112 ///
113 /// The number of points supplied is allowed to be smaller, however in this case
114 /// the optimizer will resort to techniques generating additional points if needed.
115 virtual std::size_t numInitPoints() const = 0;
116
117 /// \brief Initialize the optimizer for the supplied objective function.
118 ///
119 /// Be aware that function.init() has to be called before calling this function!
120 /// This function will initialize the algorithm with a number of points proposed
121 /// by the function. Note that this must fail if the function can not propose starting point(s).
122 ///
123 /// \param [in] function The objective function to initialize for.
124 virtual void init( ObjectiveFunctionType const& function ){
125 SHARK_RUNTIME_CHECK(function.canProposeStartingPoint(), "Objective function does not propose a starting point");
126 std::vector<SearchPointType> initPoints(numInitPoints());
127 for(SearchPointType& point: initPoints){
128 point = function.proposeStartingPoint();
129 }
130 init(function,initPoints);
131 }
132
133
134 /// \brief Initialize the optimizer for the supplied objective function using a set of initialisation points
135 ///
136 /// Most single objective algorithms only require a single point. However multi-objective algorithms
137 /// need a set of initialisation points. The number of points required should be numInitPoints().
138 /// Otherwise the algorithm might use heuristics to generate additional points if needed.
139 ///
140 /// Be aware that function.init() has to be called before calling this function!
141 /// \param [in] function The objective function to initialize for.
142 /// \param [in] initPoints points used for initialisation. Should be at least numInitPoints().
143 virtual void init( ObjectiveFunctionType const& function, std::vector<SearchPointType> const& initPoints ) = 0;
144
145 /// \brief Carry out one step of the optimizer for the supplied objective function.
146 /// \param [in] function The objective function to initialize for.
147 virtual void step( ObjectiveFunctionType const& function ) = 0;
148
149 /// \brief Accesses the best solution obtained so far.
150 /// \return An immutable reference to the best solution obtained so far.
151 virtual SolutionType const& solution() const = 0; //mt_hint: try accessing this thing via solution().point and solution().value..
152
153protected:
154 /// \brief Convenience function that checks whether the features of the supplied objective function match with the required features of the optimizer.
155 /// \param [in] objectiveFunction The function to match with.
156 /// \throws shark::Exception
157 void checkFeatures (ObjectiveFunctionType const& objectiveFunction){
158 //test whether the function can be evaluated
159 SHARK_RUNTIME_CHECK(!requiresValue() || objectiveFunction.hasValue(), name()+" Requires value of objective function");
160 //test first derivative
161 SHARK_RUNTIME_CHECK(!requiresFirstDerivative() || objectiveFunction.hasFirstDerivative(), name()+" Requires first derivative of objective function");
162 //test second derivative
163 SHARK_RUNTIME_CHECK(!requiresSecondDerivative() || objectiveFunction.hasSecondDerivative(), name()+" Requires second derivative of objective function");
164 //test for constraints
165 if(objectiveFunction.isConstrained()){
166 SHARK_RUNTIME_CHECK(canSolveConstrained(), name()+" Can not solve constrained problems");
168 !requiresClosestFeasible() || objectiveFunction.canProvideClosestFeasible(),
169 name()+" Requires closest feasible solution for solving constrained problems"
170 );
171 }
172 }
173};
174
175}
176
177#endif // SHARK_CORE_ABSTRACTOPTIMIZER_H