Tampoco son muy buenos... En general, trabajar con una distribución beta no central pertenece más bien a la clase de tareas no triviales. Nos las arreglamos para ver Boost desde el código fuente abierto. Y será más complicado que el que tenemos ahora en SB.
Es decir, se toman dos variables aleatorias, donde la primera es de una distribución chi-cuadrado no central y la segunda es de una distribución central. Probablemente el código se pueda corregir a esto:
//--- generar número aleatorio usando ChiCuadrado No Centraldouble chi1=MathRandomNoncentralChiSquare(a2,lambda2,error_code);double chi2=MathRandomChiSquare(b2,error_code);
result[i]=chi1/(chi1+chi2);
Los gráficos modificados del ejemplo serán los siguientes.
Gracias, tienes razón, hay que calcular a través de esta fórmula, sin embargo había otro error, el parámetro de no centralidad lambda debería ser sin multiplicador 2.
//+------------------------------------------------------------------+//| Variable aleatoria de la distribución Beta no central.//+------------------------------------------------------------------+//| Calcular la variable aleatoria de la Beta no central ||//| distribución con parámetros a,b y lambda. |||//||//| Argumentos:|//| a : Primer parámetro de forma |//| b : Segundo parámetro de forma |//| lambda : Parámetro de no centralidad//| error_code : Variable para el código de error |//||//| Valor de retorno:|//| Valor aleatorio con distribución Beta no central.//+------------------------------------------------------------------+double MathRandomNoncentralBeta(constdouble a,constdouble b,constdouble lambda,int &error_code)
{
//--- si lambda==0, devuelve la variante aleatoria betaif(lambda==0.0)
return MathRandomBeta(a,b,error_code);
//--- comprobar parámetrosif(!MathIsValidNumber(a) || !MathIsValidNumber(b) || !MathIsValidNumber(lambda))
{
error_code=ERR_ARGUMENTS_NAN;
return QNaN;
}
//--- a,b,lambda deben ser positivosif(a<=0.0 || b<=0.0 || lambda<0)
{
error_code=ERR_ARGUMENTS_INVALID;
return QNaN;
}
error_code=ERR_OK;
//--- generar número aleatorio usando ChiCuadrado No Centraldouble chi1=MathRandomNoncentralChiSquare(2*a,lambda,error_code);
double chi2=MathRandomChiSquare(2*b,error_code);return chi1/(chi1+chi2);
}
//+------------------------------------------------------------------+//| Variable aleatoria de la distribución Beta no central.//+------------------------------------------------------------------+//|| Genera variables aleatorias a partir de la distribución Beta no central ||//| con parámetros a,b, lambda.|//||//| Argumentos:|//| a : Primer parámetro de forma |//| b : Segundo parámetro de forma |//| lambda : Parámetro de no centralidad//| data_count : Número de valores necesarios ||//| resultado : Matriz de salida con valores aleatorios |//||//| Valor de retorno:|//| verdadero si tiene éxito, en caso contrario falso. ||//+------------------------------------------------------------------+bool MathRandomNoncentralBeta(constdouble a,constdouble b,constdouble lambda,constint data_count,double &result[])
{
//--- si lambda==0, devuelve la variante aleatoria betaif(lambda==0.0)
return MathRandomBeta(a,b,data_count,result);
//--- comprobar parámetrosif(!MathIsValidNumber(a) || !MathIsValidNumber(b) || !MathIsValidNumber(lambda))
returnfalse;
//--- a,b,lambda deben ser positivosif(a<=0.0 || b<=0.0 || lambda<0)
returnfalse;
int error_code=0;
//--- prepara la matriz de salida y calcula los valores aleatoriosArrayResize(result,data_count);
double a2=a*2;
double b2=b*2;
for(int i=0; i<data_count; i++)
{
//--- generar número aleatorio usando ChiCuadrado No Centraldouble chi1=MathRandomNoncentralChiSquare(a2,lambda,error_code);
double chi2=MathRandomChiSquare(b2,error_code);
result[i]=chi1/(chi1+chi2);
}
returntrue;
}
Script de prueba:
//+------------------------------------------------------------------+//|TestNoncentralBeta.mq5//|Copyright 2024, MetaQuotes Ltd. |//| https://www.mql5.com//+------------------------------------------------------------------+#property copyright"Copyright 2024, MetaQuotes Ltd."#property link"https://www.mql5.com"#property version"1.00"#include <Graphics\Graphic.mqh>
#include <Math\Stat\NoncentralBeta.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs//--- parámetros de entradainputdouble a_par=2; // primer parámetro de la distribución beta (shape1)inputdouble b_par=5; // segundo parámetro de distribución beta (shape2)inputdouble l_par=1; // parámetro de no centralidad (lambda)//+------------------------------------------------------------------+//| Función de inicio del programa de script|//+------------------------------------------------------------------+voidOnStart()
{
//--- desactivar la visualización del gráfico de preciosChartSetInteger(0,CHART_SHOW,false);
//--- inicializar el generador de números aleatorios MathSrand(GetTickCount());
//--- generar una muestra de la variable aleatorialong chart=0;
string name="GraphicNormal";
int n=1000000; // número de valores de la muestraint ncells=52; // número de intervalos en el histogramadouble x[]; // centros de intervalo del histogramadouble y[]; // número de valores de la muestra que entran en el intervalodouble data[]; // muestreo de valores aleatorios double max,min; // valores máximo y mínimo de la muestra//--- obtener una muestra de la distribución beta no central
MathRandomNoncentralBeta(a_par,b_par,l_par,n,data);
//--- calcular los datos para la construcción del histograma
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtener los límites de la secuencia y el paso para la construcción de la curva teóricadouble step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtenemos datos calculados teóricamente en el intervalo [min,max]double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityNoncentralBeta(x2,a_par,b_par,l_par,false,y2);
//--- escaladouble theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
for(int i=0; i<ncells; i++)
y[i]/=k;
//--- visualizar gráficos
CGraphic graphic;
if(ObjectFind(chart,name)<0)
graphic.Create(chart,name,0,0,0,780,380);
else
graphic.Attach(chart,name);
graphic.BackgroundMain(StringFormat("Noncentral Beta distribution alpha=%G beta=%G lambda=%G",
a_par,b_par,l_par));
graphic.BackgroundMainSize(16);
//--- trazar todas las curvas
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- y ahora vamos a trazar la curva de densidad de distribución teórica
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
graphic.CurvePlotAll();
//--- trazar todas las curvas
graphic.Update();
DebugBreak();
}
//+------------------------------------------------------------------+//| Calcular frecuencias para el conjunto de datos|//+------------------------------------------------------------------+bool CalculateHistogramArray(constdouble &data[],double &intervals[],double &frequency[],
double &maxv,double &minv,constint cells=10)
{
if(cells<=1) return (false);
int size=ArraySize(data);
if(size<cells*10) return (false);
minv=data[ArrayMinimum(data)];
maxv=data[ArrayMaximum(data)];
double range=maxv-minv;
double width=range/cells;
if(width==0) returnfalse;
ArrayResize(intervals,cells);
ArrayResize(frequency,cells);
//--- fijar los centros de los intervalosfor(int i=0; i<cells; i++)
{
intervals[i]=minv+(i+0.5)*width;
frequency[i]=0;
}
//--- rellenar las frecuencias de intervalofor(int i=0; i<size; i++)
{
int ind=int((data[i]-minv)/width);
if(ind>=cells) ind=cells-1;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+//| Calcula valores para la generación de secuencias |//+------------------------------------------------------------------+void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
{
//--- calcula la magnitud absoluta de la secuencia para obtener la precisión de la normalizacióndouble range=MathAbs(maxv-minv);
int degree=(int)MathRound(MathLog10(range));
//--- normalizar los valores máx. y mín. con la precisión especificada
maxv=NormalizeDouble(maxv,degree);
minv=NormalizeDouble(minv,degree);
//--- el paso de generación de la secuencia también se establece a partir de la precisión dada
stepv=NormalizeDouble(MathPow(10,-degree),degree);
if((maxv-minv)/stepv<10)
stepv/=10.;
}
Fuentes alternativas utilizan el algoritmo ASA310:
23 July 202405:23:28 PM
ASA310_PRB:
C++ version
Test the ASA310 library.
TEST01:
NCBETA computes the noncentral incomplete Beta function.
Compare to tabulated values.
A B LAMBDA X FX FX2
(Tabulated) (NCBETA) DIFF
55540.8640.45630210.45630224833903671.483 e-07551400.90.10413370.10413347908759822.209 e-07551700.9560.60223530.60224181585488076.516 e-061010540.86860.9187770.91877592543309741.075 e-0610101400.90.60081060.60080678940968323.811 e-0610102500.90.0902850.09028989932605594.899 e-062020540.87870.99986550.99986140486117034.095 e-0620201400.90.99259970.99259547773473624.222 e-0620202500.9220.96411119999999990.96411795457015096.755 e-0610201500.8680.93766265730.93766265552197311.778 e-0910101200.90.73068178580.7306817844791931.321 e-09155800.880.16042569180.16042569169197811.08 e-1020101100.850.18674853130.1867485309480683.519 e-102030650.660.65593868740000010.65593868739922887.713 e-1320501300.720.97968814860.97968814742020761.18 e-093020800.720.11623864230.11623864215237971.476 e-1030401300.80.99304300540.99304300423072621.169 e-09105200.6440.05068992730.050689879813552734.749 e-081010540.70.10309597060.10309597061126841.127 e-111030800.780.99784178320000010.99784178304248381.575 e-1015201200.760.25555523690.25555523558549331.315 e-09105550.7950.06683070640.06683070640851368.514 e-121217640.560.01136010670.011360106665912963.409 e-1130301400.80.78133666150.78133665911859012.381 e-093530200.670.88671264770.88671255693544489.076 e-08
ASA310_PRB:
Normal end of execution.
Por ejemplo algunos de los resultados en Wolfram Mathematica:
Para iniciar sesión y usar el sitio web MQL5.com es necesario permitir el uso de Сookies.
Por favor, active este ajuste en su navegador, de lo contrario, no podrá iniciar sesión.
Ha iniciado sesión. La autenticación de dos factores se ha desactivado. Vuelva a configurarla y escanee un nuevo código QR, o continúe con la autenticación de dos factores desactivada.
Estos son los resultados.
Tampoco son muy buenos... En general, trabajar con una distribución beta no central pertenece más bien a la clase de tareas no triviales. Nos las arreglamos para ver Boost desde el código fuente abierto. Y será más complicado que el que tenemos ahora en SB.
La misma Wikipedia lo tiene:
Es decir, se toman dos variables aleatorias, donde la primera es de una distribución chi-cuadrado no central y la segunda es de una distribución central. Probablemente el código se pueda corregir a esto:
Los gráficos modificados del ejemplo serán los siguientes.
Gracias, tienes razón, hay que calcular a través de esta fórmula, sin embargo había otro error, el parámetro de no centralidad lambda debería ser sin multiplicador 2.
Script de prueba:
Resultado:
También he comprobado la función CFD para la distribución beta no central.
Algunos resultados cuestionables:
Fuentes alternativas utilizan el algoritmo ASA310:
Por ejemplo algunos de los resultados en Wolfram Mathematica:
Que es más o menos similar a la verdad...