Vorrei utilizzare GSL all'interno di una classe C++ senza dichiarare funzioni membro come static
. Il motivo è perché non li conosco troppo bene e non sono sicuro della sicurezza dei thread. Da quello che ho letto, std::function
potrebbe essere una soluzione, ma non sono sicuro di come usarlo.come evitare la funzione di membro statico quando si utilizza gsl con C++
La mia domanda si riduce a come posso rimuovere static
nella dichiarazione di g
?
#include<iostream>
#include <functional>
#include <stdlib.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_monte.h>
#include <gsl/gsl_monte_plain.h>
#include <gsl/gsl_monte_miser.h>
#include <gsl/gsl_monte_vegas.h>
using namespace std;
class A {
public:
static double g (double *k, size_t dim, void *params)
{
double A = 1.0/(M_PI * M_PI * M_PI);
return A/(1.0 - cos (k[0]) * cos (k[1]) * cos (k[2]));
}
double result() {
double res, err;
double xl[3] = { 0, 0, 0 };
double xu[3] = { M_PI, M_PI, M_PI };
const gsl_rng_type *T;
gsl_rng *r;
////// the following 3 lines didn't work ///////
//function<double(A,double*, size_t, void*)> fg;
//fg = &A::g;
//gsl_monte_function G = { &fg, 3, 0 };
gsl_monte_function G = { &g, 3, 0 };
size_t calls = 500000;
gsl_rng_env_setup();
T = gsl_rng_default;
r = gsl_rng_alloc (T);
{
gsl_monte_plain_state *s = gsl_monte_plain_alloc (3);
gsl_monte_plain_integrate (&G, xl, xu, 3, calls, r, s, &res, &err);
gsl_monte_plain_free (s);
}
gsl_rng_free (r);
return res;
}
};
main() {
A a;
cout <<"gsl mc result is " << a.result() <<"\n";
}
Update (1):
Ho provato a cambiare gsl_monte_function G = { &g, 3, 0 };
-gsl_monte_function G = { bind(&A::g, this,_1,_2,_3), 3, 0 };
, ma non ha funzionato
Update (2): Ho provato ad utilizzare assigning std::function to a member function ma didn' anche lavorare.
Update (3) alla fine ho scritto una funzione non membro:
double gmf (double *k, size_t dim, void *params) {
auto *mf = static_cast<A*>(params);
return abs(mf->g(k,dim,params));
//return 1.0;
};
Ha funzionato, ma è una soluzione disordinata perché avevo bisogno di scrivere una funzione di supporto. Con lambdas, function e bind, dovrebbe esserci un modo per avere tutto logico all'interno della classe.
so che la mia risposta è arrivata piuttosto tardi, ma spero che la classe involucro può aiutare in futuro. Questo wrap è molto utile perché consente anche di integrare le funzioni lambda o di associare le funzioni a più di un parametro (se si desidera integrare f (x, a) = a x dove a è un parametro, ad esempio). –