Auch nicht sehr gut... Im Allgemeinen gehört die Arbeit mit nicht-zentralen Beta-Verteilungen eher zu den nicht-trivialen Aufgaben. Wir haben es geschafft, Boost aus dem offenen Quellcode zu sehen. Und es wird komplizierter sein als das, was wir jetzt in SB haben.
Das heißt, es werden zwei Zufallsvariablen genommen, wobei die erste aus einer nicht zentralen Chi-Quadrat-Verteilung und die zweite aus einer zentralen Verteilung stammt. Wahrscheinlich kann der Code dahingehend korrigiert werden:
//--- Zufallszahl mit Noncentral ChiSquare erzeugendouble chi1=MathRandomNoncentralChiSquare(a2,lambda2,error_code);double chi2=MathRandomChiSquare(b2,error_code);
result[i]=chi1/(chi1+chi2);
Die geänderten Graphen im Beispiel werden unten stehen.
Vielen Dank, Sie haben Recht, wir müssen durch diese Formel zu berechnen, aber es war ein weiterer Fehler, der Lambda Nicht-Zentralität Parameter sollte ohne Multiplikator 2 sein.
//+------------------------------------------------------------------+//| Zufallsvariable aus der nicht-zentralen Beta-Verteilung |//+------------------------------------------------------------------+//| Berechnen Sie die Zufallsvariable aus dem nichtzentralen Beta |//| Verteilung mit den Parametern a, b und lambda.//||//| Argumente:|//| a : Erster Formparameter |//| b : Zweiter Formparameter |//| lambda : Parameter der Nicht-Zentralität |//| error_code : Variable für Fehlercode |//||//| Rückgabewert:|//| Der Zufallswert mit nichtzentraler Beta-Verteilung.//+------------------------------------------------------------------+double MathRandomNoncentralBeta(constdouble a,constdouble b,constdouble lambda,int &error_code)
{
//--- wenn lambda==0, Rückgabe der Zufallsvariante betaif(lambda==0.0)
return MathRandomBeta(a,b,error_code);
//--- Parameter prüfenif(!MathIsValidNumber(a) || !MathIsValidNumber(b) || !MathIsValidNumber(lambda))
{
error_code=ERR_ARGUMENTS_NAN;
return QNaN;
}
//--- a,b,lambda muss positiv seinif(a<=0.0 || b<=0.0 || lambda<0)
{
error_code=ERR_ARGUMENTS_INVALID;
return QNaN;
}
error_code=ERR_OK;
//--- Zufallszahl mit Noncentral ChiSquare erzeugendouble chi1=MathRandomNoncentralChiSquare(2*a,lambda,error_code);
double chi2=MathRandomChiSquare(2*b,error_code);return chi1/(chi1+chi2);
}
//+------------------------------------------------------------------+//| Zufallsvariable aus der nicht-zentralen Beta-Verteilung |//+------------------------------------------------------------------+//|| Erzeugt Zufallsvariablen aus der nicht-zentralen Beta-Verteilung |//| mit den Parametern a,b, lambda.|//||//| Argumente:|//| a : Erster Formparameter |//| b : Zweiter Formparameter |//| lambda : Parameter der Nicht-Zentralität |data_count : Anzahl der benötigten Werte //|//| Ergebnis: Array mit Zufallswerten ausgeben |//||//| Rückgabewert:|//| true wenn erfolgreich, sonst false. ||//+------------------------------------------------------------------+bool MathRandomNoncentralBeta(constdouble a,constdouble b,constdouble lambda,constint data_count,double &result[])
{
//--- wenn lambda==0, Rückgabe der Zufallsvariante betaif(lambda==0.0)
return MathRandomBeta(a,b,data_count,result);
//--- Parameter prüfenif(!MathIsValidNumber(a) || !MathIsValidNumber(b) || !MathIsValidNumber(lambda))
returnfalse;
//--- a,b,lambda muss positiv seinif(a<=0.0 || b<=0.0 || lambda<0)
returnfalse;
int error_code=0;
//--- Ausgabe-Array vorbereiten und Zufallswerte berechnenArrayResize(result,data_count);
double a2=a*2;
double b2=b*2;
for(int i=0; i<data_count; i++)
{
//--- Zufallszahl mit Noncentral ChiSquare erzeugendouble chi1=MathRandomNoncentralChiSquare(a2,lambda,error_code);
double chi2=MathRandomChiSquare(b2,error_code);
result[i]=chi1/(chi1+chi2);
}
returntrue;
}
Test-Skript:
//+------------------------------------------------------------------+//|TestNoncentralBeta.mq5 |//|Urheberrecht 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//--- Eingabeparameterinputdouble a_par=2; // erster Parameter der Beta-Verteilung (shape1)inputdouble b_par=5; // zweiter Parameter der Beta-Verteilung (shape2)inputdouble l_par=1; // Parameter der Nicht-Zentralität (Lambda)//+------------------------------------------------------------------+//| Skript-Programmstartfunktion|//+------------------------------------------------------------------+voidOnStart()
{
//--- Anzeige des Preisdiagramms deaktivierenChartSetInteger(0,CHART_SHOW,false);
//--- Initialisierung des Zufallszahlengenerators MathSrand(GetTickCount());
//--- Erzeugen einer Stichprobe der Zufallsvariablenlong chart=0;
string name="GraphicNormal";
int n=1000000; // Anzahl der Werte in der Stichprobeint ncells=52; // Anzahl der Intervalle im Histogrammdouble x[]; // Histogramm-Intervallzentrendouble y[]; // Anzahl der Werte aus der Stichprobe, die in das Intervall fallendouble data[]; // Stichprobe von Zufallswerten double max,min; // Höchst- und Mindestwerte in der Stichprobe//--- eine Stichprobe aus der nicht zentralen Beta-Verteilung erhalten
MathRandomNoncentralBeta(a_par,b_par,l_par,n,data);
//--- Daten für die Erstellung von Histogrammen berechnen
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- Ermittlung der Sequenzgrenzen und des Schritts für die theoretische Kurvenkonstruktiondouble step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- wir erhalten theoretisch berechnete Daten auf dem Intervall [min,max]double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityNoncentralBeta(x2,a_par,b_par,l_par,false,y2);
//--- Skalierungdouble 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;
//--- Diagramme anzeigen
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);
//--- alle Kurven zeichnen
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- und nun zeichnen wir die theoretische Verteilungsdichtekurve
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
graphic.CurvePlotAll();
//--- alle Kurven zeichnen
graphic.Update();
DebugBreak();
}
//+------------------------------------------------------------------+//| Häufigkeiten für den Datensatz berechnen|//+------------------------------------------------------------------+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);
//--- die Zentren der Intervalle festlegenfor(int i=0; i<cells; i++)
{
intervals[i]=minv+(i+0.5)*width;
frequency[i]=0;
}
//--- Ausfüllen der Intervallfrequenzenfor(int i=0; i<size; i++)
{
int ind=int((data[i]-minv)/width);
if(ind>=cells) ind=cells-1;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+//| Berechnet Werte für die Sequenzerstellung |//+------------------------------------------------------------------+void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
{
//--- Berechnung des absoluten Betrags der Sequenz, um die Normalisierungsgenauigkeit zu erhaltendouble range=MathAbs(maxv-minv);
int degree=(int)MathRound(MathLog10(range));
//--- Maximal- und Minimalwerte mit der angegebenen Genauigkeit normalisieren
maxv=NormalizeDouble(maxv,degree);
minv=NormalizeDouble(minv,degree);
//--- Schritt der Sequenzerstellung ebenfalls von der angegebenen Genauigkeit ausgehend festgelegt
stepv=NormalizeDouble(MathPow(10,-degree),degree);
if((maxv-minv)/stepv<10)
stepv/=10.;
}
Alternative Quellen verwenden den ASA310-Algorithmus:
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.
Zum Beispiel einige der Ergebnisse in Wolfram Mathematica:
Das sind die Ergebnisse.
Auch nicht sehr gut... Im Allgemeinen gehört die Arbeit mit nicht-zentralen Beta-Verteilungen eher zu den nicht-trivialen Aufgaben. Wir haben es geschafft, Boost aus dem offenen Quellcode zu sehen. Und es wird komplizierter sein als das, was wir jetzt in SB haben.
Die gleiche Wikipedia hat es:
Das heißt, es werden zwei Zufallsvariablen genommen, wobei die erste aus einer nicht zentralen Chi-Quadrat-Verteilung und die zweite aus einer zentralen Verteilung stammt. Wahrscheinlich kann der Code dahingehend korrigiert werden:
Die geänderten Graphen im Beispiel werden unten stehen.
Vielen Dank, Sie haben Recht, wir müssen durch diese Formel zu berechnen, aber es war ein weiterer Fehler, der Lambda Nicht-Zentralität Parameter sollte ohne Multiplikator 2 sein.
Test-Skript:
Ergebnis:
Ich habe auch die CFD-Funktion für die nichtzentrale Beta-Verteilung überprüft.
Einige fragwürdige Ergebnisse:
Alternative Quellen verwenden den ASA310-Algorithmus:
Zum Beispiel einige der Ergebnisse in Wolfram Mathematica:
Was der Wahrheit mehr oder weniger ähnlich ist...