close Warning: Can't synchronize with repository "(default)" (/var/svn/tolp does not appear to be a Subversion repository.). Look in the Trac log for more information.

Opened 15 years ago

Last modified 14 years ago

#888 closed defect

La función SliceSampler1D falla con dominios inconexos — at Initial Version

Reported by: Víctor de Buen Remiro Owned by: Víctor de Buen Remiro
Priority: highest Milestone: Numerical methods
Component: BSR Version: 2.0.1
Severity: blocker Keywords:
Cc:

Description

Tal y como se puede ver en el siguiente código TOL, la función SliceSampler1D falla a veces con dominios inconexos, es decir, cuando en parte del intervalo la densidad vale 0, o lo que es lo mismo su logaritmo es -Inf.

Como no sucede de forma determinista hay que usar una semilla de geración distinta para reproducir cada caso posible.

Por lo que he podido ver, devuelve el último valor generado, por lo que si éste tiene densidad 0 el valor devuelto está fuera del dominio.

El ejemplo reproduce la simulación del coeficiente de grado 1 de un modelos AR puro de grado 6, tal y como lo hace internamente BSR.

//////////////////////////////////////////////////////////////////////////////
// Semilla de generación aleatoria fijada para reproducir el comportamiento
// exacto
// 
// 3 de 8 no estacionarias incluida la última: devuelve el valor inicial
// Real PutRandomSeed(1836343167);
// 
// ninguna no estacionaria: devuelve una simulación válida
// Real PutRandomSeed(1664310743);
// 
// 2 de 8 no estacionarias, pero no la última: devuelve una simulación válida
// Real PutRandomSeed(1664310743);
//////////////////////////////////////////////////////////////////////////////
Real PutRandomSeed(0);
Real rndSeed = GetRandomSeed(0);

WriteLn("TRACE  rndSeed:"<<rndSeed);

//Se define un modelo AR con un polinomio que tiene un dominio
//inconexo de estacionariedad para el coeficiente de grado 1
Polyn ar = 1-0.09944049062890037*B+0.4208976407813203*B^2-0.07979027150930651*B^3-0.524509273364506*B^4+0.1794384784972413*B^5+0.01042162544590616*B^6;
Polyn ma = 1;

//Se copia el polinomio ma para evitar efectos secundarios en la evaluación
Polyn p = Copy(ar);
Real d = 1;

//Esta función evalúa la estacionariedad de un polinomio pol con respecto al 
//coeficiente de grado d en el intervalo [-d,d] con longitud de paso h
Matrix get.stationary.map(Polyn pol, Real d, Real h)
{
  SetMat(EvalSet(Range(-d,d,h), Set(Real c)
  {
    Polyn p = Copy(pol);
    Real c_ = If(c, c, 1.E-10);
    Real PutCoef(p,d,c_);
    [[c,IsStationary(p)]]
  }))
};
Matrix map = get.stationary.map(p,d,0.001);

//Se debe comenzar por un polinomio que sea estacionario
Real isStationary = IsStationary(ar);

//Se generan aleatoriamente los residuos
VMatrix res = Gaussian(1000,1,0,1);

//Para ilustrar mejor como el dominio de estacioanriedad no es conexo
//construimos series de ruidos en tres valores

Real c1 = -0.5; VMatrix z1 = { Real PutCoef(p,d,c1); DifEq(ma/p,res) };
Real c2 = +0.3; VMatrix z2 = { Real PutCoef(p,d,c2); DifEq(ma/p,res) };
Real c3 = +0.7; VMatrix z3 = { Real PutCoef(p,d,c3); DifEq(ma/p,res) };

//Para las pruebas nos sirve cualquiera estacionario: tomamos el original
//Retomamos el valor inicial
VMatrix z = DifEq(ma/ar,res);
Polyn p := Copy(ar);

//Se genera el evaluador de la verosimilitud ARMA
NameBlock almagro = ARMAProcess::Eval.Almagro(ar,ma,z,1);
//Se calculan los valores iniciales condicionados
VMatrix u0 = almagro::Draw.U_cond_Z(0);
VMatrix z0 = almagro::Get.Z0(u0);
VMatrix a0 = almagro::Get.A0(u0);

//Se toma el coeficiente de grado 1
Real x0 = Coef(ar,d);
Real L = -1;    //Mínimo valor para el que se da estacionariedad
Real U = 0.807; //Máximo valor para el que se da estacionariedad

//Función de actualización del polinomio AR que devuelve cierto si es 
//estacionario con el nuevo coeficiente
Real SetValue(Real x0)
{
  //Se asegura de que no pone coeficiete 0 porque destruye la forma del 
  //polinomio como vector de monomios. Es algo que habría que arreglar.
  Real x = If(1+x==1, 0.000001, x);
  Real PutCoef(p, d, x);
  Real isStationary = IsStationary(p);
  WriteLn("TRACE  SetValue("<<x+") isStationary:"<<isStationary);
  isStationary
};
//Función de evaluación del logaritmo de la densidad
Real LogDens.Almagro.Z_cond_U(Real x)
{
  Real llh =  If(!SetValue(x), -1/0, {
    Copy(almagro::LogLH.Z_cond_U(p,ma,z0,a0))
  }) ;
  WriteLn("TRACE  LogDens.Almagro.Z_cond_U("<<x+") :"<<llh);
  llh
};
//Llamada al método de simulación escalar slice
Real x = MatDat(SliceSampler1D(LogDens.Almagro.Z_cond_U, L, U, x0),1,1);

WriteLn("TRACE x="<<x);

Change History (0)

Note: See TracTickets for help on using tickets.