GCC Code Coverage Report


Directory: ./
File: lib/geogram/numerics/optimizer.h
Date: 2026-09-07 02:36:43
Exec Total Coverage
Lines: 0 24 0.0%
Functions: 0 8 0.0%
Branches: 0 0 -%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40 #ifndef GEOGRAM_NUMERICS_OPTIMIZER
41 #define GEOGRAM_NUMERICS_OPTIMIZER
42
43 #include <geogram/basic/common.h>
44 #include <geogram/basic/numeric.h>
45 #include <geogram/basic/smart_pointer.h>
46 #include <geogram/basic/counted.h>
47 #include <geogram/basic/assert.h>
48 #include <geogram/basic/factory.h>
49
50 class HESSIAN_MATRIX;
51
52 /**
53 * \file geogram/numerics/optimizer.h
54 * \brief Abstract base class for numerical optimizers, used
55 * to minimize a multivariate function
56 */
57
58 namespace GEO {
59
60 /**
61 * \brief Optimizer minimizes a multivariate function.
62 *
63 * \details The dimension of the problem is defined by set_N().
64 * The multivariate function to be minimized is defined
65 * by a callback that evaluates the function and its
66 * gradient, specified by set_funcgrad_callback().
67 * Optimizer implements the numeric part of
68 * CentroidalVoronoiTesselation.
69 *
70 * Optimizer objects are created using method create() which
71 * uses the Factory service. New Optimizer%s can be implemented and
72 * registered to the factory using
73 * geo_register_Optimizer_creator().
74 * \see OptimizerFactory
75 * \see geo_register_Optimizer_creator
76 */
77 class GEOGRAM_API Optimizer : public Counted {
78 public:
79 /**
80 * \brief Optimizer callback that evaluates a function
81 * and its gradient.
82 * \see set_funcgrad_callback()
83 */
84 typedef void (* funcgrad_callback)(
85 index_t N, double* x, double& f, double* g
86 );
87
88 /**
89 * \brief Optimizer callback that is called at each iteration.
90 * \see set_newiteration_callback()
91 */
92 typedef void (* newiteration_callback)(
93 index_t N, const double* x, double f, const double* g, double gnorm
94 );
95
96 /**
97 * \brief Optimizer callback that evaluates a function,
98 * its gradient and its Hessian.
99 * \see set_evalhessian_callback()
100 */
101 typedef void (* evalhessian_callback)(
102 index_t N, double* x, double& f, double* g, HESSIAN_MATRIX& hessian
103 );
104
105 /**
106 * \brief Creates an Optimizer.
107 * \param[in] name name of the Optimizer to create:
108 * - "HLBFG" - BFGS (quasi-Newton)
109 * - "HM1QN3" - for non-smooth functions
110 * - "HCG" - non-linear conjugate gradient
111 * - "HLBFGS_HESS" - BFGS with Hessian (full Newton)
112 * - "default" - equivalent to "HLBFGS"
113 * \retval nullptr if \p name is not a valid Optimizer algorithm name
114 * \retval otherwise, a pointer to an Optimizer object. The returned
115 * pointer must be stored in a Optimizer_var that does automatic
116 * destruction:
117 * \code
118 * Optimizer_var optimizer = Optimizer::create("HLBFGS") ;
119 * \endcode
120 */
121 static Optimizer* create(const std::string& name = "default");
122
123 /**
124 * \brief Minimizes a function, starting from initial value x.
125 * \param[in] x is of size n, where n was defined with set_N()
126 */
127 virtual void optimize(double* x) = 0;
128
129 /**
130 * \brief Defines the number of variables.
131 */
132 void set_N(index_t N) {
133 n_ = N;
134 }
135
136 /**
137 * \brief Returns the number of variables.
138 */
139 index_t get_N() const {
140 return n_;
141 }
142
143 /**
144 * \brief Defines the inner number of iterations.
145 * \details Used by HLBFGSOptimizer.
146 */
147 void set_M(index_t M) {
148 m_ = M;
149 }
150
151 /**
152 * \brief Returns the inner number of iterations.
153 */
154 index_t get_M() const {
155 return m_;
156 }
157
158 /**
159 * \brief Defines the maximum number of iterations.
160 */
161 void set_max_iter(index_t maxiter) {
162 max_iter_ = maxiter;
163 }
164
165 /**
166 * \brief Returns the maximum number of iterations.
167 */
168 index_t get_max_iter() const {
169 return max_iter_;
170 }
171
172 /**
173 * \brief Defines the callback that evaluates
174 * the function to be minimized and its gradient.
175 */
176 void set_funcgrad_callback(funcgrad_callback fp) {
177 funcgrad_callback_ = fp;
178 }
179
180 /**
181 * \brief Defines a callback that will be
182 * called at each iteration.
183 */
184 void set_newiteration_callback(newiteration_callback fp) {
185 newiteration_callback_ = fp;
186 }
187
188 /**
189 * \brief Defines the callback that evaluates
190 * the Hessian of function to be minimized (second
191 * order derivatives).
192 *
193 * \details Only used in "HLBFGS_HESS" mode.
194 */
195 void set_evalhessian_callback(evalhessian_callback fp) {
196 evalhessian_callback_ = fp;
197 }
198
199 /**
200 * \brief Defines the stopping criterion
201 * in terms of gradient magnitude.
202 */
203 void set_epsg(double eg) {
204 epsg_ = eg;
205 }
206
207 /**
208 * \brief Defines the stopping criterion
209 * in terms of function value.
210 */
211 void set_epsf(double ef) {
212 epsf_ = ef;
213 }
214
215 /**
216 * \brief Defines the stopping criterion
217 * in terms of variation of x.
218 */
219 void set_epsx(double ex) {
220 epsx_ = ex;
221 }
222
223 /**
224 * \brief Enables or disables verbose logs.
225 */
226 void set_verbose(bool verb) {
227 verbose_ = verb;
228 }
229
230 protected:
231 /**
232 * \brief Optimizer constructor
233 * \details Should never be called directly, use create() instead.
234 */
235 Optimizer();
236
237 /**
238 * \brief Optimizer destructor
239 */
240 ~Optimizer() override;
241
242 protected:
243 /** Size of the problem */
244 index_t n_;
245 /**
246 * Number of corrections in the BFGS scheme of Hessian
247 * approximation update
248 */
249 index_t m_;
250 /** Max iterations */
251 index_t max_iter_;
252
253 funcgrad_callback funcgrad_callback_;
254 newiteration_callback newiteration_callback_;
255 evalhessian_callback evalhessian_callback_;
256
257 /** Error tolerance on x, f and g */
258 double epsg_, epsf_, epsx_;
259
260 bool verbose_;
261 };
262
263 /**
264 * \brief Smart pointer that contains an Optimizer object
265 * \relates Optimizer
266 */
267 typedef SmartPointer<Optimizer> Optimizer_var;
268
269 /**
270 * \brief Optimizer Factory
271 * \details This Factory is used to create Optimizer objects. It can also
272 * be used to register new Optimizer implementations.
273 * \see geo_register_Optimizer_creator
274 * \see Factory
275 * \relates Optimizer
276 */
277 typedef Factory0<Optimizer> OptimizerFactory;
278
279 /**
280 * \brief Helper macro to register an Optimizer implementation
281 * \see OptimizerFactory
282 * \relates Optimizer
283 */
284 #define geo_register_Optimizer_creator(type, name) \
285 geo_register_creator(GEO::OptimizerFactory, type, name)
286 }
287
288 #endif
289