Function that requires a function as an argument (brent_find_minima)?

M

Markus S

Hi,

I try to use a function that minimizes another function (namely from
the Boost library: brent_find_minima). When I provide the function to
be minized at the very top level (ie, in the .cpp file) and call
brent_find_minima from the main block, it works fine but when I create
a class and define the function to be minimized in there (and also call
brent_find_minima in another function in that class), I get this error
during compilation:
error: argument of type ‘double (Testclass::)(double)’ does not match
‘double (Testclass::*)(double)’

I had invoked brent_find_minima with this line (which works when called
in main);
std::pair<double, double> result =
boost::math::tools::brent_find_minima(TrickyF, min, max, bits);

I started with this example:
http://net.pku.edu.cn/~webg/src/par...nclude/boost-1_35/boost/math/tools/minima.hpp

Thanks,

Markus
 
V

Victor Bazarov

Markus said:
I try to use a function that minimizes another function (namely from the
Boost library: brent_find_minima). When I provide the function to be
minized at the very top level (ie, in the .cpp file) and call
brent_find_minima from the main block, it works fine but when I create a
class and define the function to be minimized in there (and also call
brent_find_minima in another function in that class), I get this error
during compilation:
error: argument of type ‘double (Testclass::)(double)’ does not match
‘double (Testclass::*)(double)’

I had invoked brent_find_minima with this line (which works when called
in main);
std::pair<double, double> result =
boost::math::tools::brent_find_minima(TrickyF, min, max, bits);

I started with this example:
http://net.pku.edu.cn/~webg/src/par...nclude/boost-1_35/boost/math/tools/minima.hpp

FAQ 5.8.

V
 
M

Markus S

FAQ
The sample code was essentially in that linked file but to be verbose
here comes a minimal set of files, compiled with bjam (Jamroot file at
the bottom) using the boost 1.39 library both on Mac OS X 10.5.7
(Intel) and on Debian (4.0, I think). The error message is the same on
both systems. Everything compiles and runs fine until I make the call
to brent_find_minima in Testclass.cc active (ie, uncomment it).

Testbrent.hpp:
-------------------
#include <boost/math/tools/minima.hpp>
#include "Testclass.h"
using namespace std;

double TrickyFunction(double x)
{
return (x-5.0);
}

int main()
{
double min = 0.0001;
double max = 1.0;
int bits = 50;
std::pair<double, double> result =
boost::math::tools::brent_find_minima(TrickyFunction, min, max, bits);
return 0;
}

Testclass.h:
----------------
#ifndef Testclass_h
#define Testclass_h Testclass_h

using namespace std;

class Testclass
{
public:
Testclass();
~Testclass();
double TrickyF(double x);
void CallTrickyF();
};

#endif

Testclass.cc:
-----------------
#include "Testclass.h"
#include <boost/math/tools/minima.hpp>

Testclass::Testclass() {}
Testclass::~Testclass() {}

double Testclass::TrickyF(double x)
{
return (x-5.0);
}

void Testclass::CallTrickyF()
{
double temp = 5.0;
double min = 0.0001;
double max = 1.0;
int bits = 50;
// std::pair<double, double> result =
boost::math::tools::brent_find_minima(TrickyF, min, max, bits);
}

Jamroot:
------------
exe testbrent
: TestBrent.cpp Testclass.cc
: <include>.
: <include>/usr/local/include/boost-1_39/
;
 
V

Victor Bazarov

Markus said:
The sample code was essentially in that linked file but to be verbose
here comes a minimal set of files, compiled with bjam (Jamroot file at
the bottom) using the boost 1.39 library both on Mac OS X 10.5.7 (Intel)
and on Debian (4.0, I think). The error message is the same on both
systems. Everything compiles and runs fine until I make the call to
brent_find_minima in Testclass.cc active (ie, uncomment it).

There is a difference between a function and a non-static member
function, especially AFA conversion to a function pointer is concerned.
A stand-alone function can be converted to a pointer-to-function
transparently. A member function has to be wrapped and the hidden first
argument (the object for which the member function is called) has to be
provided somehow. See 'bind1st' and 'memfun' templates.
Testbrent.hpp:
-------------------
#include <boost/math/tools/minima.hpp>
#include "Testclass.h"
using namespace std;

double TrickyFunction(double x)
{
return (x-5.0);
}

int main()
{
double min = 0.0001;
double max = 1.0;
int bits = 50;
std::pair<double, double> result =
boost::math::tools::brent_find_minima(TrickyFunction, min, max, bits);
return 0;
}

Testclass.h:
----------------
#ifndef Testclass_h
#define Testclass_h Testclass_h

using namespace std;

class Testclass
{
public:
Testclass();
~Testclass();
double TrickyF(double x);
void CallTrickyF();
};

#endif

Testclass.cc:
-----------------
#include "Testclass.h"
#include <boost/math/tools/minima.hpp>

Testclass::Testclass() {}
Testclass::~Testclass() {}

double Testclass::TrickyF(double x)
{
return (x-5.0);
}

void Testclass::CallTrickyF()
{
double temp = 5.0;
double min = 0.0001;
double max = 1.0;
int bits = 50;
// std::pair<double, double> result =
boost::math::tools::brent_find_minima(TrickyF, min, max, bits);
}

Jamroot:
------------
exe testbrent : TestBrent.cpp Testclass.cc
: <include>.
: <include>/usr/local/include/boost-1_39/
;

V
 
M

Markus S

There is a difference between a function and a non-static member
function, especially AFA conversion to a function pointer is concerned.
A stand-alone function can be converted to a pointer-to-function
transparently. A member function has to be wrapped and the hidden
first argument (the object for which the member function is called) has
to be provided somehow. See 'bind1st' and 'memfun' templates.
Thanks, I'll have a look at these things (just having the proper
description of what I want to do helps a lot in finding relevant
information).
 
M

Markus S

Markus said:
There is a difference between a function and a non-static member
function, especially AFA conversion to a function pointer is concerned.
A stand-alone function can be converted to a pointer-to-function
transparently. A member function has to be wrapped and the hidden
first argument (the object for which the member function is called) has
to be provided somehow. See 'bind1st' and 'memfun' templates.

I have finally figured it out how to use bind (and indirectly mem_fun):
When calling brent_find_minima, simply wrap the member function to be
minimized with bind:
brent_find_minima(boost::bind(&Testclass::TrickyF, this, _1), min, max, bits);

Reading the manual for bind or mem_fun (or mem_fn) did not really help
me, but I found the one example of it here which explained it:
http://cpplimitscience.blogspot.com/2006/11/making-algorithms-work-for-you.html

Below, is an example of complete, compilable code.

Markus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top