2
double randNormal(double (*fun)(double, double, double), double xmin, double xmax, double sigma, double mju)
{
static double (*Fun)(double, double, double) = NULL, YMin, YMax;
static bool First = true;

if (First)
{
    First = false;
    srand((unsigned) time(NULL));
}

if (fun != Fun)
{
  Fun = fun;
  YMin = 0, YMax = Fun(xmin, sigma, mju); 


for (int iX = 1; iX < 10000; iX++)
  {
    double X = xmin + (xmax - xmin) * iX / 10000;
    double Y = Fun(X, sigma, mju);
    YMax = Y > YMax ? Y : YMax;
  }
}

double X = xmin + (xmax - xmin) * rand() / RAND_MAX;
double Y = YMin + (YMax - YMin) * rand() / RAND_MAX;

return Y < fun(X, sigma, mju) ? X : randomNormal(Fun, xmin, xmax, sigma, mju);

}

I am very new to C++ and I am struggling with understanding the code above. What is the role of (*fun)(double, double, double) when we define the function randNormal? Furthermore, what is accomplished by the second line starting with static double? I would appreciate your help!

ELD
  • 177
  • 5
  • 1
    [cdecl.org](http://cdecl.ridiculousfish.com/?q=double+%28*fun%29%28double%2C+double%2C+double%29), [wikipedia](https://en.wikipedia.org/w/index.php?oldid=701493252) – Kijewski Feb 02 '16 at 19:51

3 Answers3

5

This is a function pointer. In this case to a function that returns a double and takes 3 doubles as an argument. Fun is declared the same way and later called, using 3 doubles as parameters)

The static double line declares a function pointer Fun just as fun and two double values. static here means that the values are preserved and still available when the function is called the next time.

Edit: To read more about function pointers, see here: How do function pointers in C work?

Community
  • 1
  • 1
Anedar
  • 4,235
  • 1
  • 23
  • 41
3

double (*fun)(double, double, double) is a pointer to a function that takes 3 doubles as argument and returns a double. For example when you have

double example(double a, double b, double c){
    return a+b+c;
}

you can pass this function via

double x = randNormal(example,...);

The static Fun keeps its value between function calls. Thats why in the function it is checked, if Fun != fun and only if this is true the parameter is assigned to the static variable. However, to explain better, I would have to know what is the logic of this function.

PS: typedefs can help a lot when working with function pointers. Using

typedef (double)(*FUNCTION_TYPE)(double,double,double); 

or more generally,

typedef (return_type)(*FUNCTION_TYPE)(parameter_type);

can help to make the declarations easier to write and possibly read.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • Just to expand on this answer: if you're planning on writing something like that, the preferred "modern" (C++11) way is to use [`std::function`](http://en.cppreference.com/w/cpp/utility/functional/function) and friends. The notation is also more explicit and easier to understand, in my opinion. – mindriot Feb 02 '16 at 19:58
  • I have edited the post to include the entire function, thank you for your help – ELD Feb 02 '16 at 19:59
0

The first argument "double (*fun)(double, double, double)" of the function randNormal is a function pointer. The below example will explain you the usage of the function pointer for some level. The code comment will explain in detail.

#include <iostream>
//Actual function 1
double fnGetMax(double a, double b, double c) {
    //return someMathLibrary::StaticMaxOf(a, b ,c);
    return a-b-c;
}
//Actual function 2
double fnGetMin(double a, double b, double c) {
    //return someMathLibrary::StaticMinOf(a, b ,c);
    return a+b+c;
}
//Actual function 3 
//which takes the "function pointer" as argument of the actual functions like 1 & 2
double randNormal(double (*fun)(double, double, double), double xmin, double xmax, double sigma, double mju) {
    static double (*Fun)(double, double, double) = NULL, YMin, YMax;
    static bool First = true;

    if (First) {
        First = false;
        srand((unsigned) time(NULL));
    }

    if (fun != Fun) {
        Fun = fun;
        //calling actual function 1 or 2
        YMin = 0, YMax = Fun(xmin, sigma, mju); 
    } else {
        //calling actual function 1 or 2
        YMax = 0, YMin = Fun(xmax, sigma, mju);
    }
    return YMin + YMax;
}

int main(int argc, char** argv) {
    //Creating function pointer for the actual function 1
    double (*funMax_ptr)(double, double, double) = &fnGetMax;
    //Creating function pointer for the actual function 2
    double (*funMin_ptr)(double, double, double) = &fnGetMin;

    //Passing the function pointer to the randNormal (actual function 3) 
    std::cout << randNormal(funMax_ptr,1.0,2.0,3.0,4.0) << std::endl;
    std::cout << randNormal(funMin_ptr,1.0,2.0,3.0,4.0) << std::endl;

    return 0;
}

Output:
-6
8

Jeet
  • 1,006
  • 1
  • 14
  • 25