Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
FCNAdapter.h
Go to the documentation of this file.
1// @(#)root/minuit2:$Id$
2// Author: L. Moneta 10/2006
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2006 ROOT Foundation, CERN/PH-SFT *
7 * *
8 **********************************************************************/
9
10#ifndef ROOT_Minuit2_FCNAdapter
11#define ROOT_Minuit2_FCNAdapter
12
13#include "Minuit2/FCNBase.h"
14
15#include <ROOT/RSpan.hxx>
16
17#include <vector>
18#include <functional>
19
20namespace ROOT::Minuit2 {
21
22/// Adapter class to wrap user-provided functions into the FCNBase interface.
23///
24/// This class allows users to supply their function (and optionally its gradient,
25/// diagonal second derivatives, and Hessian) in the form of `std::function` objects.
26/// It adapts these functions so that they can be used transparently with the MINUIT
27/// minimizers via the `FCNBase` interface.
28///
29/// Typical usage:
30/// - Pass the function to minimize to the constructor.
31/// - Optionally set the gradient, G2 (second derivative diagonal), or Hessian
32/// functions using the provided setter methods.
33/// - MINUIT will then query these functions if available, or fall back to numerical
34/// approximations if they are not provided.
35///
36/// \ingroup Minuit
37class FCNAdapter : public FCNBase {
38
39public:
40 /// Construct an adapter around a user-provided function.
41 ///
42 /// @param f Function to minimize. It must take a pointer to the parameter array
43 /// (`double const*`) and return the function value.
44 /// @param up Error definition parameter (defaults to 1.0).
45 FCNAdapter(std::function<double(double const *)> f, double up = 1.) : fUp(up), fFunc(std::move(f)) {}
46
47 /// Indicate whether an analytic gradient has been provided.
48 ///
49 /// @return `true` if a gradient function was set, otherwise `false`.
50 bool HasGradient() const override { return bool(fGradFunc); }
51
52 /// Indicate whether analytic second derivatives (diagonal of the Hessian) are available.
53 ///
54 /// @return `true` if a G2 function or a Hessian function has been set, otherwise `false`.
55 bool HasG2() const override { return bool(fG2Func); }
56
57 /// Indicate whether an analytic Hessian has been provided.
58 ///
59 /// @return `true` if a Hessian function was set, otherwise `false`.
60 bool HasHessian() const override { return bool(fHessianFunc); }
61
62 /// Evaluate the function at the given parameter vector.
63 ///
64 /// @param v Parameter vector.
65 /// @return Function value at the specified parameters.
66 double operator()(std::vector<double> const &v) const override { return fFunc(v.data()); }
67
68 /// Return the error definition parameter (`up`).
69 ///
70 /// @return Current error definition value.
71 double Up() const override { return fUp; }
72
73 /// Evaluate the gradient of the function at the given parameter vector.
74 ///
75 /// @param v Parameter vector.
76 /// @return Gradient vector (∂f/∂xᵢ) at the specified parameters.
77 std::vector<double> Gradient(std::vector<double> const &v) const override
78 {
79 std::vector<double> output(v.size());
80 fGradFunc(v.data(), output.data());
81 return output;
82 }
83
84 /// Return the diagonal elements of the Hessian (second derivatives).
85 ///
86 /// If a G2 function is set, it is used directly. If only a Hessian function
87 /// is available, the diagonal is extracted from the full Hessian.
88 ///
89 /// @param x Parameter vector.
90 /// @return Vector of second derivatives (one per parameter).
91 std::vector<double> G2(std::vector<double> const &x) const override
92 {
93 std::vector<double> output;
94 if (fG2Func)
95 return fG2Func(x);
96 if (fHessianFunc) {
97 std::size_t n = x.size();
98 output.resize(n);
99 if (fHessian.empty())
100 fHessian.resize(n * n);
101 fHessianFunc(x, fHessian.data());
102 if (!fHessian.empty()) {
103 // Extract diagonal elements of Hessian
104 for (unsigned int i = 0; i < n; i++)
105 output[i] = fHessian[i * n + i];
106 }
107 }
108 return output;
109 }
110
111 /// Return the full Hessian matrix.
112 ///
113 /// If a Hessian function is available, it is used to fill the matrix.
114 /// If the Hessian function fails, it is cleared and not used again.
115 ///
116 /// @param x Parameter vector.
117 /// @return Flattened Hessian matrix in row-major order.
118 std::vector<double> Hessian(std::vector<double> const &x) const override
119 {
120 std::vector<double> output;
121 if (fHessianFunc) {
122 std::size_t n = x.size();
123 output.resize(n * n);
124 bool ret = fHessianFunc(x, output.data());
125 if (!ret) {
126 output.clear();
127 fHessianFunc = nullptr;
128 }
129 }
130
131 return output;
132 }
133
134 /// Set the analytic gradient function.
135 ///
136 /// @param f Gradient function of type `void(double const*, double*)`.
137 /// The first argument is the parameter array, the second is
138 /// the output array for the gradient values.
139 void SetGradientFunction(std::function<void(double const *, double *)> f) { fGradFunc = std::move(f); }
140
141 /// Set the function providing diagonal second derivatives (G2).
142 ///
143 /// @param f Function taking a parameter vector and returning the
144 /// diagonal of the Hessian matrix as a vector.
145 void SetG2Function(std::function<std::vector<double>(std::vector<double> const &)> f) { fG2Func = std::move(f); }
146
147 /// Set the function providing the full Hessian matrix.
148 ///
149 /// @param f Function of type `bool(std::vector<double> const&, double*)`.
150 /// The first argument is the parameter vector, the second is
151 /// the output buffer (flattened matrix). The return value
152 /// should be `true` on success, `false` on failure.
153 void SetHessianFunction(std::function<bool(std::vector<double> const &, double *)> f)
154 {
155 fHessianFunc = std::move(f);
156 }
157
158 /// Update the error definition parameter.
159 ///
160 /// @param up New error definition value.
161 void SetErrorDef(double up) override { fUp = up; }
162
163private:
164 using Function = std::function<double(double const *)>;
165 using GradFunction = std::function<void(double const *, double *)>;
166 using G2Function = std::function<std::vector<double>(std::vector<double> const &)>;
167 using HessianFunction = std::function<bool(std::vector<double> const &, double *)>;
168
169 double fUp = 1.; ///< Error definition parameter.
170 mutable std::vector<double> fHessian; ///< Storage for intermediate Hessian values.
171
172 Function fFunc; ///< Wrapped function to minimize.
173 GradFunction fGradFunc; ///< Optional gradient function.
174 G2Function fG2Func; ///< Optional diagonal second-derivative function.
175 mutable HessianFunction fHessianFunc; ///< Optional Hessian function.
176};
177
178} // namespace ROOT::Minuit2
179
180#endif // ROOT_Minuit2_FCNAdapter
#define f(i)
Definition RSha256.hxx:104
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Adapter class to wrap user-provided functions into the FCNBase interface.
Definition FCNAdapter.h:37
std::vector< double > G2(std::vector< double > const &x) const override
Return the diagonal elements of the Hessian (second derivatives).
Definition FCNAdapter.h:91
FCNAdapter(std::function< double(double const *)> f, double up=1.)
Construct an adapter around a user-provided function.
Definition FCNAdapter.h:45
Function fFunc
Wrapped function to minimize.
Definition FCNAdapter.h:172
GradFunction fGradFunc
Optional gradient function.
Definition FCNAdapter.h:173
void SetGradientFunction(std::function< void(double const *, double *)> f)
Set the analytic gradient function.
Definition FCNAdapter.h:139
void SetHessianFunction(std::function< bool(std::vector< double > const &, double *)> f)
Set the function providing the full Hessian matrix.
Definition FCNAdapter.h:153
std::function< void(double const *, double *)> GradFunction
Definition FCNAdapter.h:165
std::function< bool(std::vector< double > const &, double *)> HessianFunction
Definition FCNAdapter.h:167
double operator()(std::vector< double > const &v) const override
Evaluate the function at the given parameter vector.
Definition FCNAdapter.h:66
std::vector< double > Hessian(std::vector< double > const &x) const override
Return the full Hessian matrix.
Definition FCNAdapter.h:118
bool HasHessian() const override
Indicate whether an analytic Hessian has been provided.
Definition FCNAdapter.h:60
void SetErrorDef(double up) override
Update the error definition parameter.
Definition FCNAdapter.h:161
std::vector< double > Gradient(std::vector< double > const &v) const override
Evaluate the gradient of the function at the given parameter vector.
Definition FCNAdapter.h:77
G2Function fG2Func
Optional diagonal second-derivative function.
Definition FCNAdapter.h:174
bool HasG2() const override
Indicate whether analytic second derivatives (diagonal of the Hessian) are available.
Definition FCNAdapter.h:55
void SetG2Function(std::function< std::vector< double >(std::vector< double > const &)> f)
Set the function providing diagonal second derivatives (G2).
Definition FCNAdapter.h:145
std::function< double(double const *)> Function
Definition FCNAdapter.h:164
double fUp
Error definition parameter.
Definition FCNAdapter.h:169
HessianFunction fHessianFunc
Optional Hessian function.
Definition FCNAdapter.h:175
double Up() const override
Return the error definition parameter (up).
Definition FCNAdapter.h:71
std::function< std::vector< double >(std::vector< double > const &)> G2Function
Definition FCNAdapter.h:166
bool HasGradient() const override
Indicate whether an analytic gradient has been provided.
Definition FCNAdapter.h:50
std::vector< double > fHessian
Storage for intermediate Hessian values.
Definition FCNAdapter.h:170
Interface (abstract class) defining the function to be minimized, which has to be implemented by the ...
Definition FCNBase.h:37
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
static void output()