Hi,

Thank you for his response. I attach the program in c for details.











El 17/06/12 10:12, Juan Pablo Amorocho D. escribió:
Hola Claudio,

Without the code and concrete problem is very difficult to say anything about your question.

Cheers,

Juan Pablo

2012/6/17 Claudio Tablada <[email protected] <mailto:[email protected]>>

    Hi,

    I am trying to maximize a -log likelihood function of a
    Birnbaum-Saunders distribution with two parameters using BFGS and
    Monte Carlo. I have the samples generates using
    gsl_ran_gaussian_ziggurat and later transforming for the
    Birnbaum-Saunders distribution. The problem is that for some
    values of the sample the algorithm converges and for other values
    it results in NaN. Thanks in advanced.



#include <stdio.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <gsl/gsl_multimin.h>
#include <gsl/gsl_math.h>
#include <math.h>
#define N 100 //tamaño de la muestra
#define B 1.0  //parámetro beta fijado en 1.0
#define NREP 200  //número de replicas Monte Carlo

double logv(const gsl_vector *v , void *params);
void dlogv(const gsl_vector *v , void *params , gsl_vector *df);
void logv_dlogv(const gsl_vector *x , void *params , double *f , gsl_vector *df);
double *mle(double array[]);
double *montecarlo(double *mle(double array1[]) , double alpha);
gsl_rng * r;
gsl_multimin_fdfminimizer *s;
gsl_vector *x;
double z[4];

int main(void)
{  
  int i , op;
  float alpha;
  double sigma;
  double *a;
  const gsl_rng_type *T;
  FILE *ofp1; //puntero para archivo
  
  printf("Ingrese un valor del parámetro alpha\n");
  scanf("%f",&alpha);
  
  sigma = alpha/2;

  ofp1 = fopen("saida1.txt","a");

  /*Crea un generador por la variable GSL_RNG_TYPE*/
  gsl_rng_env_setup();
  T = gsl_rng_default;
  r = gsl_rng_alloc (T);
  
  
  /*Generación de las replicas Monte Carlo*/

      a = montecarlo(mle , alpha);

      fprintf(ofp1, "Estimación de los parámetros alpha y beta de máxima verosimilitud\n");
      fprintf(ofp1 , "Número de replicas Monte Carlo: %d\n" , NREP);      
      fprintf(ofp1 , "Salida para muestra con N=%i, alpha=%1.2f e beta=1.00\n" , N , alpha);
      fprintf(ofp1 , "alpha_MC:            % 2.6f\t  beta_MC:            % 2.6f\n", a[0] , a[1]);
      fprintf(ofp1 , "sesgo relativo alpha: % 2.6f\t sesgo relativo beta:  % 2.6f\n", (a[0] - alpha)/alpha , (a[1] - B)/B);
      fprintf(ofp1 , "EQM alpha:           % 2.6f\t EQM beta:            % 2.6f\n", (a[0] - alpha)*(a[0] - alpha) + (a[2] - a[0]*a[0]) , (a[1] - B)*(a[1] - B) + (a[3] - a[1]*a[1]));
      fprintf(ofp1 , "Var alpha:           % 2.6f\t Var beta:            % 2.6f\n\n" , a[2] - a[0]*a[0] , a[3] - a[1]*a[1]);

return 0;
}


/*-log-likelihood function*/

double logv(const gsl_vector *v , void *params)
{
  int i;
  double x1 , y1 , soma1 , soma2;
  double *p = (double *)params;
 
  x1 = gsl_vector_get(v , 0);
  y1 = gsl_vector_get(v , 1);

  for(i = 0 , soma1 = 0.0 ; i < N ; i++)
    soma1 += log(sqrt(y1/p[i]) + sqrt((y1/p[i])*(y1/p[i])*(y1/p[i])));

  for(i = 0 , soma2 = 0.0 ; i < N ; i++)
    soma2 += p[i]/y1 + y1/p[i] - 2;

  return N*log(x1*y1) - soma1 + soma2/(2*x1*x1);
}



/*gradient of logv, dlogv=(dlogv/dx,dlogv/dy)*/

void dlogv(const gsl_vector *v , void *params , gsl_vector *df)
{
  int i;
  double x1 , y1 , soma1 , soma2 , soma3;
  double *p = (double *)params;

  x1 = gsl_vector_get(v , 0);
  y1 = gsl_vector_get(v , 1);

  for(i = 0 , soma1 = 0.0 ; i < N ; i++)
    soma1 += p[i];

  for(i = 0 , soma2 = 0.0 ; i < N ; i++)
    soma2 += 1./p[i];

  for(i = 0 , soma3 = 0.0 ; i < N ; i++)
    {
      //soma3 = 1./(p[i] + y1);
      soma3 += (1./(sqrt(y1/p[i]) + sqrt((y1/p[i])*(y1/p[i])*(y1/p[i]))))*(1./(2*p[i]))*(sqrt(p[i]/y1) + 3*sqrt(y1/p[i]));
    }
  gsl_vector_set(df , 0 , (N/x1)*(1. + 2./(x1*x1)) - soma1/(x1*x1*x1*y1) - (y1/(x1*x1*x1))*soma2);
  gsl_vector_set(df , 1 , N/(y1) - soma3 - soma1/(2*x1*x1*y1*y1) + soma2/(2*x1*x1));
}



/*logv and dlogv*/

void logv_dlogv(const gsl_vector *x , void *params , double *f , gsl_vector *df)
{
  *f = logv(x , params);
  dlogv(x , params , df);
}


/*mle function (maximum-likelihood estimators)*/

double *mle(double array[])
{
  const gsl_multimin_fdfminimizer_type *V;
  gsl_multimin_function_fdf func;
  int iter = 0;
  int i , status;  

  func.n = 2; //número de componentes
  func.f = &logv;
  func.df = &dlogv;
  func.fdf = &logv_dlogv;
  func.params = array;
  
  /*Punto inicial x=(1,1)*/
  x = gsl_vector_alloc (2);
  gsl_vector_set(x , 0 , 1.0);
  gsl_vector_set(x , 1 , 1.0);
  
  V = gsl_multimin_fdfminimizer_vector_bfgs2;
  s = gsl_multimin_fdfminimizer_alloc(V , 2);
  
  gsl_multimin_fdfminimizer_set(s , &func , x , 0.01 , 1e-4);
  
  do{
    iter++;
    status = gsl_multimin_fdfminimizer_iterate(s);
    
    if(status)
      break;
    
    status = gsl_multimin_test_gradient(s -> gradient , 1e-3);
    
    if(status == GSL_SUCCESS)
    printf("Minimo hallado en: \n");
    
    printf("%5d %.5f %.5f %10.5f\n" , iter , gsl_vector_get(s->x , 0) , gsl_vector_get(s->x , 1) , s->f);
    
  }
  while(status == GSL_CONTINUE && iter < 100);
  
  z[0] = gsl_vector_get(s->x , 0);
  z[1] = gsl_vector_get(s->x , 1);

  return z;
}


/*montecarlo function*/

double *montecarlo(double *mle(double array1[]) , double alpha)
{
  int i , k;
  double u , soma1 , soma2 , soma3 , soma4 , sigma;
  double vetor_MC[N];
  double *a;
  
  sigma = alpha/2;
  
  for(k = 0 , soma1 = 0.0 , soma2 = 0.0 , soma3 = 0.0 , soma4 = 0.0 ; k < NREP ; k++)
    {
      for(i = 0 ; i < N ; i++)
	{
	  double u = gsl_ran_gaussian_ziggurat (r , sigma);
	  
	  /*generación de los datos con distribución Birnbaum-Saunders*/
	  vetor_MC[i] = (double)B*(1 + 2*u*u + 2*u*sqrt(1 + u*u));
	}
      
      a = mle(vetor_MC);
      
      soma1 += a[0];
      soma2 += a[1];
      soma3 += a[0]*a[0];
      soma4 += a[1]*a[1];
      
    }
  
  gsl_rng_free (r);
  gsl_multimin_fdfminimizer_free(s);
  gsl_vector_free(x);
  
  z[0] = soma1/NREP;
  z[1] = soma2/NREP;
  z[2] = soma3/NREP;
  z[3] = soma4/NREP;
  
  return z;
}

Reply via email to