我要开发一个优化器来计算隐藏马尔可夫链的14个参数(我知道它很多但可能:))。我已经使用IMSL完成了相同的优化器(我在一次会议期间),我知道这是可能的,但我现在没有IMSL的许可证,因为我正在做一个学生项目而我正在尝试制作与C ++相同的优化器。
但是我收到了这个错误(我在代码中注释了它):
gsl: simplex.c:288: ERROR: non-finite function value encountered Default GSL error handler invoked. Aborted
我正在使用GSL library
,更具体地说是子库multimin
。
我现在正在向您展示我的代码,如果您需要我可以更多地评论它,但我可以将数据发送给任何可以帮助我的人。
非常感谢你的时间和帮助。
本杰明,
优化器所需的结构:
struct dataMom {
int n; /* Number of data points */
gsl_vector *Rmom; /* Response data */
gsl_vector *Rm; /* Covariate */
};
计算值的函数
double my_f (const gsl_vector *v, void *params) {
struct dataMom *p = (struct dataMom *) params;
int i;
double loglik = 0;
所以你可以看到我们有14个要优化的参数。
double alphaC = gsl_vector_get (v, 0);
double beta0C =gsl_vector_get (v, 1);
double betaUC =gsl_vector_get (v, 2);
double sigmamomC =gsl_vector_get (v, 3);
double muC =gsl_vector_get (v, 4);
double sigmamC =gsl_vector_get (v, 5);
double probaC =gsl_vector_get (v, 6);
double alphaT= gsl_vector_get (v, 7);
double beta0T = gsl_vector_get (v, 8);
double betaUT= gsl_vector_get (v, 9);
double sigmamomT= gsl_vector_get (v, 10);
double muT =gsl_vector_get (v, 11);
double sigmamT = gsl_vector_get (v, 12);
double probaT =gsl_vector_get (v, 13);
double epsilonmomC;
double epsilonmC;
double epsilonmomT;
double epsilonmT;
double Rmomentum;
double Rmarket;
double IUT;
double Pc;
double Pt;
double PC;
double PT;
double PI = 3.14159;
double probac = (1-probaT)/(2-probaC-probaT);
double probat = 1-probac;
for (i=0;i<p->n;i++) {
Rmomentum = gsl_vector_get(p->Rmom, i)*0.01;
Rmarket = gsl_vector_get(p->Rm, i)*0.01;
if (Rmarket>0){IUT = 1;}
else {IUT = 0;}
epsilonmomC = (1/sigmamomC)*(Rmomentum - alphaC - (beta0C + IUT*betaUC)*Rmarket);
epsilonmC = (1/sigmamC)*(Rmarket-muC);
epsilonmomT = (1/sigmamomT)*(Rmomentum - alphaT - (beta0T + IUT*betaUT)*Rmarket);
epsilonmT = (1/sigmamT)*(Rmarket-muT);
Pc = ((1/(sigmamomC*sqrt(2*PI)))*exp(-(epsilonmomC*epsilonmomC)/2)) * ((1/(sigmamC*sqrt(2*PI)))*exp(-(epsilonmC*epsilonmC)/2));
Pt = ((1/(sigmamomT*sqrt(2*PI)))*exp(-(epsilonmomT*epsilonmomT)/2)) * ((1/(sigmamT*sqrt(2*PI)))*exp(-(epsilonmT*epsilonmT)/2));
PC = Pc * (probaC*probac + (1-probaC)*(probat));
PT = Pt * ((1-probaT)*(probac) + probaT*probat);
loglik -=log(PC+PT);
probac = PC / (PC+PT);
probat = PT / (PC+PT);
}
return loglik;
}
主要:
int main (void) {
/* Initialise data and model parameters */
//these are 2 vectors of return from txt files that i can give you
vector<double> Benchmark;
vector<double> Momentum;
//these are the 2 fonctions i'm using to get the return for the txt files
Benchmark = readBenchmark();
Momentum = readMomentum();
int i, n=Benchmark.size(), nparas=14;
double initial_p[14] = {0.0204,0.41,-0.52,0.0432 , 0.0098 , 0.0362 , 0.97, 0.0402 , -0.26 , -1.28 , 0.1105 , -0.0070 , 0.0904 , 0.92};
struct dataMom myStruct;
myStruct.n = n;
myStruct.Rmom = gsl_vector_alloc(myStruct.n);
myStruct.Rm = gsl_vector_alloc(myStruct.n);
vector<double>::iterator itbenchmark;
vector<double>::iterator itmomentum;
double tempmom;
double tempm;
itbenchmark = Benchmark.begin();
itmomentum = Momentum.begin();
for (i=0;i<myStruct.n;i++) {
tempmom = *itmomentum;
tempm = *itbenchmark;
gsl_vector_set (myStruct.Rmom, i, tempmom);
gsl_vector_set (myStruct.Rm, i, tempm);
itbenchmark++;
itmomentum++;
}
/* Starting point */
gsl_vector *paras;
paras = gsl_vector_alloc (nparas);
for (i=0;i<nparas;i++)
gsl_vector_set (paras, i, initial_p[i]);
/* Initialise algorithm parameters */
size_t iter = 0;
int status;
double size;
/* Set initial STEP SIZES to 1 */
gsl_vector *ss;
ss = gsl_vector_alloc (nparas);
gsl_vector_set_all (ss, 0.5);
const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
gsl_multimin_fminimizer *s = NULL;
gsl_multimin_function minex_func;
/* Initialize method and iterate */
minex_func.n = nparas;
minex_func.f = my_f;
minex_func.params = &myStruct;
s = gsl_multimin_fminimizer_alloc (T, nparas);
在此之前没有问题,但下一行会产生此错误:
gsl: simplex.c:288: ERROR: non-finite function value encountered Default GSL error handler invoked. Aborted (core dumped)
gsl_multimin_fminimizer_set (s, &minex_func, paras, ss);
do {
iter++;
status = gsl_multimin_fminimizer_iterate(s);
if (status)
break;
size = gsl_multimin_fminimizer_size (s);
status = gsl_multimin_test_size (size, 1);
if (status == GSL_SUCCESS)
printf ("converged to minimum at\n");
for (int z = 0 ; z<14 ; z++)
{
cout <<gsl_vector_get (s->x, z)<<endl;
}
}
while (status == GSL_CONTINUE && iter < 10000);
gsl_multimin_fminimizer_free (s);
gsl_vector_free(myStruct.Rmom);
gsl_vector_free(myStruct.Rm);
gsl_vector_free(paras);
gsl_vector_free(ss);
return status;
}