Function Objects¶
Function Object Contents¶
Lambda functions and std::mem_fn
¶
Functions are passed to numerical routines using template-based
function classes, sometimes called “functors”. O2scl
classes which accept functions as parameters generally default to
types built upon std::function
. If the
user would like to use Boost function objects instead, these may
also be used, simply by specifying the Boost function type in the
template parameter.
Some template aliases are defined to save typing of the function types, e.g.
funct : One function of one variable (used in one-dimensional solver and minimizer classes, derivative classes, integration classes, etc.)
funct_ld : One function of one variable using long double
multi_funct : One function of several variables (used in minimizer and integration classes)
mm_funct: \(n\) functions of \(n\) variables (used in solver classes)
grad_funct: gradient function for minimizer classes
ode_funct: \(n\) derivatives as a function of \(n\) function values and the value of the independent variable
ode_jac_funct: Jacobian function for ODE classes
ode_it_funct: Function to specify ODEs for iterative solution
jac_funct : Jacobian function for solver and fitting classes
fit_funct: Fit function
ool_hfunct: Hessian matrix function for constrained minimization
First function object example¶
The example below demonstrates how C++11 function objects can be used with the root_brent_gsl solver.
/* Example: ex_lambda.cpp
-------------------------------------------------------------------
Demonstrate how to use standard library and lambda function objects
with O2scl.
*/
#include <iostream>
#include <functional>
#include <o2scl/root_brent_gsl.h>
#include <o2scl/test_mgr.h>
using namespace std;
using namespace o2scl;
// A global function
double gfn(double x) {
return sin(x)-0.1;
}
// A global function with a parameter
double gfn_param(double x, double a) {
return sin(x)-a;
}
class a_class {
public:
// A member function
double mfn(double x) {
return sin(x)-0.1;
}
// A member function with a parameter
double mfn_param(double x, double a) {
return sin(x)-a;
}
// A member function with a const and non-const reference parameter
double mfn_param_ref(double x, const double &a, double &b) {
b=x*x;
return sin(x)-a;
}
};
int main(void) {
test_mgr t;
t.set_output_level(2);
cout.setf(ios::scientific);
// The O2scl solver. Note that we use the same solver for
// all the examples below.
root_brent_gsl<std::function<double(double)> > grb;
// For the initial bracket
double a, b;
// With a global function
{
a=-0.9, b=0.9;
std::function<double(double)> f=gfn;
grb.solve_bkt(a,b,f);
t.test_rel(a,asin(0.1),1.0e-12,"Global function");
}
// O2scl defines 'funct' as std::function<double(double)>, so this
// shorter notation also works.
{
a=-0.9, b=0.9;
funct f=gfn;
grb.solve_bkt(a,b,f);
t.test_rel(a,asin(0.1),1.0e-12,"Global function (take 2)");
}
// With a global function
{
a=-0.9, b=0.9;
funct f=std::bind(gfn_param,std::placeholders::_1,0.1);
grb.solve_bkt(a,b,f);
t.test_rel(a,asin(0.1),1.0e-12,"Global function with parameter");
}
// With a member function
{
a=-0.9, b=0.9;
a_class ac;
funct f=std::bind(std::mem_fn<double(double)>(&a_class::mfn),
ac,std::placeholders::_1);
grb.solve_bkt(a,b,f);
t.test_rel(a,asin(0.1),1.0e-12,"Member function");
}
// With a member function which has a fixed parameter
{
a=-0.9, b=0.9;
a_class ac;
funct f=std::bind(std::mem_fn<double(double,double)>
(&a_class::mfn_param),
ac,std::placeholders::_1,0.1);
grb.solve_bkt(a,b,f);
t.test_rel(a,asin(0.1),1.0e-12,"Member function with parameter");
}
// Inline specification of the function
{
a=-0.9, b=0.9;
funct f=[](double x) -> double { double z=sin(x)-0.1; return z; };
grb.solve_bkt(a,b,f);
t.test_rel(a,asin(0.1),1.0e-12,"Inline 1");
}
// A bit of a shorter notation
{
a=-0.9, b=0.9;
funct f=[](double x){ return sin(x)-0.1; };
grb.solve_bkt(a,b,f);
t.test_rel(a,asin(0.1),1.0e-12,"Inline 2");
// Show copy construction works
a=-0.9, b=0.9;
funct f2=f;
grb.solve_bkt(a,b,f2);
t.test_rel(a,asin(0.1),1.0e-12,"Inline 3");
}
// With a member function and reference parameters. Note that
// we use std::cref for the const reference and std::ref
// for the non-const reference
{
a=-0.9, b=0.9;
a_class ac;
double param1=0.1, param2;
funct f=std::bind(std::mem_fn<double(double,const double &,double &)>
(&a_class::mfn_param_ref),
ac,std::placeholders::_1,std::cref(param1),
std::ref(param2));
grb.solve_bkt(a,b,f);
t.test_rel(a,asin(0.1),1.0e-12,"Member function with references");
// The last function call isn't always at the final root!
t.test_rel(param2,0.01,1.0e-2,"Reference 2");
}
t.report();
return 0;
}
General comments about function objects¶
The C++ standard library functors employ copy construction at various types, so one must be careful about the types involved in creating the functor. Generally, all classes should have constructors and structs should be avoided because they can cause difficulties with default copy construction.
There is a small overhead associated with the indirection: a “user class” accesses the function class which then calls function which was specified in the constructor of the function class. In many problems, the overhead associated with the indirection is small. Some of this overhead can always be avoided by inheriting directly from the function class and thus the user class will make a direct virtual function call. To eliminate the overhead entirely, one can specify a new type for the template parameter in the user class.
Second function object example¶
This example shows how to provide functions to O2scl classes by solving the equation
Where \(p_1 = 0.01\) and \(p_2 = 1.1\). The parameter \(p_1\) is stored as member data for the class, and the parameter \(p_2\) is an argument to the member function.
The image below shows how the solver progresses to the solution of the example function.

/* Example: ex_fptr.cpp
-------------------------------------------------------------------
This gives an example of the how member functions and external
parameters are supplied to numerical routines. In this case, a
member function with two parameters is passed to the root_brent_gsl
class, which solves the equation. One of the parameters is member
data, and the other is specified using the extra parameter argument
to the function.
*/
#include <fstream>
#include <o2scl/funct.h>
#include <o2scl/root_brent_gsl.h>
#include <o2scl/test_mgr.h>
using namespace std;
using namespace o2scl;
class my_class {
private:
double parameter;
public:
void set_parameter() { parameter=0.01; }
// A function demonstrating the different ways of implementing
// function parameters
double function_to_solve(double x, double &p) {
return atan((x-parameter)*4)*(1.0+sin((x-parameter)*50.0)/p);
}
};
// This header contains the code for write_file()
#include "ex_fptr.h"
int main(void) {
cout.setf(ios::scientific);
test_mgr t;
// Only print something out if one of the tests fails
t.set_output_level(1);
// The solver, specifying the type of the parameter (double)
// and the function type (funct<double>)
root_brent_gsl<> solver;
my_class c;
c.set_parameter();
double p=1.1;
// This is the code that allows specification of class member
// functions as functions to solve. This approach avoids the use of
// static variables and functions and multiple inheritance at the
// expense of a little overhead. We need to provide the address of
// an instantiated object and the address of the member function.
funct function=std::bind(std::mem_fn<double(double,double &)>
(&my_class::function_to_solve),
&c,std::placeholders::_1,std::ref(p));
double x1=-1;
double x2=2;
// The value verbose=1 prints out iteration information
// and verbose=2 requires a keypress between iterations.
solver.verbose=1;
solver.solve_bkt(x1,x2,function);
// This is actually a somewhat difficult function to solve because
// of the sinusoidal behavior.
cout << "Solution: " << x1
<< " Function value: " << c.function_to_solve(x1,p) << endl;
// Write the function being solved to a file (see source code
// in examples directory for details)
write_file(x1);
// Obtain and summarize test results
t.test_abs(c.function_to_solve(x1,p),0.0,1.0e-10,"ex_fptr");
t.report();
return 0;
}
Function typedefs¶
-
typedef std::function<double(double)> o2scl::funct¶
One-dimensional function typedef in src/base/funct.h.
-
typedef std::function<long double(long double)> o2scl::funct_ld¶
One-dimensional function typedef in src/base/funct.h.
-
typedef std::function<double(size_t, const boost::numeric::ublas::vector<double>&)> o2scl::multi_funct¶
Multi-dimensional function typedef in src/base/multi_funct.h.
-
typedef std::function<int(size_t, const boost::numeric::ublas::vector<double>&, boost::numeric::ublas::vector<double>&)> o2scl::mm_funct¶
Array of multi-dimensional functions typedef in src/base/mm_funct.h.
-
typedef std::function<int(size_t, boost::numeric::ublas::vector<double>&, boost::numeric::ublas::vector<double>&)> o2scl::grad_funct¶
Array of multi-dimensional functions typedef in src/min/mmin.h.
-
typedef std::function<int(double, size_t, const boost::numeric::ublas::vector<double>&, boost::numeric::ublas::vector<double>&)> o2scl::ode_funct¶
Ordinary differential equation function in src/ode/ode_funct.h.
-
typedef std::function<int(double, size_t, const boost::numeric::ublas::vector<double>&, boost::numeric::ublas::matrix<double>&, boost::numeric::ublas::vector<double>&)> o2scl::ode_jac_funct¶
Functor for ODE Jacobians in src/ode/ode_jac_funct.h.
-
typedef std::function<double(size_t, double, boost::numeric::ublas::matrix_row<boost::numeric::ublas::matrix<double>>&)> o2scl::ode_it_funct¶
Function for iterative solving of ODEs.
-
typedef std::function<int(size_t, boost::numeric::ublas::vector<double>&, size_t, boost::numeric::ublas::vector<double>&, boost::numeric::ublas::matrix<double>&)> o2scl::jac_funct¶
Jacobian function (not necessarily square) in src/root/jacobian.h.
-
typedef std::function<double(size_t, const boost::numeric::ublas::vector<double>&, double)> o2scl::fit_funct¶
Array of multi-dimensional functions typedef (C++11 version) in src/fit/fit_base.h.
-
typedef std::function<int(size_t, const boost::numeric::ublas::vector<double>&, const boost::numeric::ublas::vector<double>&, boost::numeric::ublas::vector<double>&)> o2scl::ool_hfunct¶
Hessian product function for o2scl::mmin_constr.