1

我必须开发一个优化器来计算隐藏马尔可夫链的 14 个参数(我知道它很多但可能:))。我已经使用 IMSL(我在实习期间使用过)完成了相同的优化器,我知道这是可能的,但我现在没有 IMSL 的许可证,因为我正在做一个学生项目,我正在尝试制作C++ 中的相同优化器。

但是我收到了这个错误(我已经在它出现的代码中评论过):

gsl:simplex.c:288:错误:遇到非有限函数值

调用默认 GSL 错误处理程序。

中止

我正在使用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:错误:遇到非有限函数值

调用默认 GSL 错误处理程序。

中止(核心转储)
    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;
}
4

0 回答 0