3

I have a class called Universe. The class includes a member function to calculate distance and requires numerically integrating an ugly looking function. I was trying to use GSL to perform the integration but I get the following error when I attempt to compile the library -

$ g++ -c -O3 -std=c++11 Universe.cpp -o Universe.o
$ error: cannot convert ‘Universe::Hz’ from type ‘double (Universe::)(double, void*)’ to type ‘double (*)(double, void*)’

Here's the class Universe without the constructors (for brevity):

Universe.h

#ifndef UNIVERSE_H
#define UNIVERSE_H

#include <cmath>
#include <gsl/gsl_integration.h>

using namespace std;

class Universe {
private:
    static constexpr double c = 299792458.0, Mpc2Km = 3.08567758e+19, Yrs2Sec = 3.15569e7;
    double H0 = 67.77, OmegaM = (0.022161+0.11889)/(H0*H0), OmegaL = 0.6914, OmegaG = 8.24e-5, OmegaK = 0.0009;
    double Ez(double z);
    double Hz(double z, void* params);
public:
    double distH, timeH;
    Universe() = default;
    Universe(double h0);
    Universe(double omegaM, double omegaL);
    Universe(double h0, double omegaM, double omegaL);
    Universe(double omegaM, double omegaL, double omegaG, double omegaK);
    Universe(double h0, double omegaM, double omegaL, double omegaG, double omegaK);
    //double radius();
    //double age();
    double distC(double z);
    };

#endif

Universe.cpp

#include <cmath>
#include <gsl/gsl_integration.h>
#include "Universe.h"

using namespace std;

double Universe::Hz(double z, void* params)  {
    double result = 1.0/pow(OmegaL + pow(1.0+z,3.0)*OmegaM + pow(1.0+z,4.0)*OmegaG + pow(1.0+z,2.0)*OmegaK, 0.5);
    return result;
    }

double Universe::distC(double z) { 
    double lower_limit = 0.0, abs_error = 1.0e-8, rel_error = 1.0e-8, alpha = 0.0, result, error;
    gsl_integration_workspace *work_ptr = gsl_integration_workspace_alloc(1000);
    gsl_function Hz_function;
    void* params_ptr = &alpha;
    Hz_function.function = Universe::Hz;
    Hz_function.params = params_ptr;
    gsl_integration_qags(&Hz_function, lower_limit, z, abs_error, rel_error, 1000, work_ptr, &result, &error);
    return distH*result;
    }

I don't quite know how to troubleshoot this problem and I'm using GSL for the first time based on the documentation at: http://www.gnu.org/software/gsl/manual/html_node/Numerical-integration-examples.html and the following guide: http://www.physics.ohio-state.edu/~ntg/780/gsl_examples/qags_test.cpp Thank you for looking and any answers!

DMH
  • 3,590
  • 2
  • 23
  • 23
  • 2
    There is a well known solution to your problem at [1] [1]: http://stackoverflow.com/questions/13074756/how-to-avoid-static-member-function-when-using-gsl-with-c/18181494#18181494 – Vivian Miranda Aug 12 '13 at 13:59

2 Answers2

3

Try the following: Make your Hz function static, like so:

static double Hz(double z, void* params) 

I verified that this works with your code.

I'm not an expert, but I believe (hand-wavy explanation follows) the basic problem is that, since the gsl_function structure needs a pointer to a function (i.e. double *), the compiler's not happy with using a class method from an "object" which hasn't even been instantiated. Making the function static in the class, however, means the compiler knows where the function can be found even before an instance of the class exists, and can deal with using a pointer to that function. (Maybe someone can give a better explanation than that, but hopefully I'm not too far off track here.)

Hope this helps.

DMH
  • 3,590
  • 2
  • 23
  • 23
0

what happens when you change the methode name of HZ?

Jinxi
  • 283
  • 1
  • 12