1

I am using a library for an optimizer (Brent's method) that has a function "local_min".

Its prototype is defined roughly as follows:

double local_min ( double f ( double x ) );

The function accepts a function pointer (?) as a parameter. Suppose f(x) is the function... the optimizer will test various values for x to find a minimum value for f(x).

The local_min function is called such as:

double f(double x){
    return .5 + x * x;
}

int main(){
    double fx = local_min(f);
    return 0;
}

The trouble I am having is that I want to define the .5 as a scalar for the function, but I do not want to use global values. Ideally, I would have everything in a single class. But everything I try, I change the function signature of f(x) and it will no longer be accepted by local_min().

For example:

int main(){
    double value = 0.5;

    auto lambda = [](double x) {
        return value + x * x;
    };

    double fx = local_min(f);
    return 0;
}

does not work because value is not accessible. Similarly,

int main(){
    double value = 0.5;

    auto lambda = [&](double x) {
        return value + x * x;
    };

    double fx = local_min(f);
    return 0;
}

changes the function signature and is no longer accepted by local_min().

JoeBass
  • 519
  • 7
  • 18
  • Do you absolutely need `local_min` to accept a function pointer? That's perhaps a stricter requirement than you want/need. Is there a reason you don't want to use a template or `std::function`? – Brian61354270 Jun 04 '21 at 20:35
  • @Brian I have the source code, and can modify it to suit my purposes, but I would like to keep the resulting code as general as possible. – JoeBass Jun 04 '21 at 20:36
  • The most general approach would be to make `local_min` a template over the callable type. This related question discusses why using template is generally the preferred approach: [std::function vs template](https://stackoverflow.com/questions/14677997/stdfunction-vs-template). Function pointers are best avoided in either case. – Brian61354270 Jun 04 '21 at 20:39

2 Answers2

0

Instead of a function pointer, make local_min accept an arbitrary type. This will let you pass it a lambda with captures as desired

template<typename F>
double local_min(F f) 
{
  // ... same usage as before
}

The callable f will still behave the same way as before, i.e. like a function that takes a double and returns a double. If you call local_min with an incompatible type, it will fail to compile. You can check for this with a static_assert to give the user a nice error message if you want.

cigien
  • 57,834
  • 11
  • 73
  • 112
0

In stead of capture by reference which requires the value to be available in the scope where the function it would be called. How about capture by value?

int main(){
    double value = 0.5;

    auto f = [value](double x) {
        return value + x * x;
    };

    double fx = local_min(f);
    return 0;
}
leafyoung
  • 11
  • 1
  • 2