增加gsl minimizer的维度

时间:2013-01-25 13:15:47

标签: c++ gsl optimization

我要开发一个优化器来计算隐藏马尔可夫链的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;
}

0 个答案:

没有答案