Avoiding use of global variables

Hello Everyone,

I made a function which finds local minima for an arbitrary function passed to it:

void Minimization(double *parameters, int Nparameters, double (*function_to_minimize)(double *, int));

I want (*function_to_minimize) to be able to access some data I have, stored as double data[Ndatapoints].

The problem is that I don't know how to let the function access this data without using global variables or changing Minimization.

So the ways I see around this are:
1) Declare *data as global so func can access this.
2) Rewrite/overload Minimization to accept this function.

Can anyone think of a better way?

Thanks,
Joe


Isn't what the first parameter is for?
Minimization adjusts parameters[0 through Nparameters-1] until a minimum is found. data should not be changed.

I guess I could append it to parameters, so
parameters[1 through Nparameters-1] would be parameters that I want to adjust, and parameters[Nparameters through (Nparameters+Ndatapoints)] would contain the data that (*function_to_minimize) uses.

I like this better than the other options, but do you think this is the best way to do it? If data were of another type, I wouldn't be able to do this.
You can either do that, or, if you're using C++, just wrap the function up in a functor that applies those extra arguments itself. Would also save your from type troubles.
There are built-in functor classes to do this.

For C++11, use bind(). (For C++03, use bind1st() or bind2nd().)

However, I am still unsure exactly what you are trying to do.
I have exactly the same problem, where I wrote a code for simplex algorithm for minimisation, and it requires communication with some data points. As a start, I defined an external linker pointer. I'm thinking I could include the minimiser and the data in a single class and avoid this problem, don't you think?
Thanks everyone,

I think the bind classes that Duoas suggested are the best for this purpose. If I understand them correctly, I should be able to do the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <functional>
using namespace std;

Double function_to_minimize(double *data, unsigned int ndata, double *parameters, unsigned int Nparameters,){ /*function here*/}

void Minimization(double *parameters, int Nparameters, double (*function_to_minimize)(double *, int)){ /*minimization technique here*/}

int main () {

  double *tmp_func;
  double data[10];
  double parameters[5];
  //initialize data and parameters

 *tmp_func=bind1st(function_to_minimize(),data);  //bind first parameter to data

 Minimization(parameters,5,bind1st((*tmp_func),10));  //bind first parameter of tmp_func, which is the second parameter of function_to_minimize, to ndata

return 0;
}
Last edited on
First of all, if you want to pass a variable that you wish to allow the function to change for the main function to see, then you want to use references so that you are passing the memory address rather then a pointer.

1
2
3
4
void function(double &var1)
{
     var1 = 500;
}


This function here will set any double you pass into it equal to 500. This will work for vectors, deque, arrays, etc...

All pointers do is point somewhere. References on the other hand are a direct link to the memory address. They go together real well though.

1
2
3
int y = 5;
int *x = &y;
*x = 10;


Now y will be 10 since x points to the memory address of y. x will actually equal the memory address of y, but still have its own memory address if you look at it through &y.

Once you understand pointers, double pointers, and references, they are not hard at all. The best way to play around with them is to write up a test program and just throw a whole bunch of different patterns into the program and see what comes out of it. Seeing is believing and seeing will help you learn more then some guy like me typing in words in a forum. It is how I learned, because reading books on it just got me more confused the more I tried to understand. Instead, I just decided to do what I suggested to you, see what happens and it stuck with me for over a decade now.
Another way to avoid using global variables is to use static variables. A good example of how to use this is in a window program.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
WinMain()
{
} // Not going to type out the details of this

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM, wParam, LPARAM lParam)
{
     static HWND hStatic;
     switch(msg)
     {
     case WM_CREATE:
          {
               hStatic = CreateWindow("static", "Some Text", WS_CHILD|WS_VISIBLE, 10, 10, 110, 110, hWnd, NULL, GetModuleHandle(0), NULL);
               break;
          }
     case WM_CHAR:
          {
               if(wParam = 'g')
                    SendMessage(hStatic, WM_SETTEXT, 0, (LPARAM)"This is your new text");
               break;
          }
     default:
          {
               return DefWindowProc(hWnd, msg, wParam, lParam);
          }
     }
     return 0;
}


In this procedure, hStatic is a static variable instead of a global variable so only one instance is created of it, which means even though WndProc is run completely though each time a message is processed, the same variable is used each time and when altered, stays altered.

Cheating: make the double* to be passed to function_to_minmze be a casted pointer to a parameter struct, which includes the additional parameter and the actual double*
Last edited on
Topic archived. No new replies allowed.