老狼的天空
2005-10-04
  类成员函数指针的调用
临近毕业,手上剩余工作不太多了,想趁机把以前的部分代码重新整理一下,同时把以前用的数学运算库(Numerical Receipe in C)换成GSL(Gnu Scientific Library)。

首先我打算用C写一个通用的Monte Carlo采样的库,比如Metropolis-Hastings sampling:

/* args: c_state - continuous states
d_state - discrete states
logpos - function to evaluate log posterior of states
vp - extra information */
int mc_metrohast ( double* c_state, int* d_state, double (*logpos) (double*, int*, void*), void *vp );

这样就可以调用这个函数进行采样,只需要提供当前Markov chain的状态(c_state, d_state)和评价log后验概率的函数指针logpos,如果需要的话其他信息可以用过指针vp来传递。

现在问题来了。我的模型都封装在一个类里面,比如说Gaussian process:
class CGp:{
...
public:
void sample();
double logpos();
...
};
成员函数sample()如下:
void sample()
{
...
int acc = mc_metrohast ( c_state, d_state, logpos, NULL );
...
}
这样是不行的,因为logpos是CGp的类成员函数,其函数指针不能这样简单传递给mc_metrohast,除非mc_metrohast定义如下:
int mc_metrohast ( double* c_state, int* d_state, double (CGp::*logpos) (double*, int*, void*), void *vp );
但是这样的话要为每一个模型的类都重写一个mc_metrohast函数 ...

最后我逼不得已用了一个很土的解决办法,那就是写一个标准C函数logposext,用它调用CGp类成员函数来计算后验概率,这样logposext就可以作为普通函数指针传递给mc_metrohast了:
double logposext (double* c_state, int* d_state, void *vp)
{
CGp * gp = (CGp*) vp;
double logpos = gp->logpos();
return logpos;
}
此时vp指针用于传递类CGp的信息。
 
Comments: 发表评论

<< Home
我原本不叫老狼,老狼是个歌手;后来欧欧叫我老狼,于是我成了老狼

当前帖子
类成员函数指针的调用

存档
2005/08 / 2005/09 / 2005/10 / 2006/01 / 2006/02 / 2006/05 / 2006/08 / 2006/10 / 2007/04 /


Powered by Blogger