101 lines
5.3 KiB
MQL5
101 lines
5.3 KiB
MQL5
//-----------------------------------------------------------------------------------
|
|
// RNDXor128.mqh
|
|
// 2011, victorg
|
|
// http://www.mql5.com
|
|
//-----------------------------------------------------------------------------------
|
|
#property copyright "2011, victorg"
|
|
#property link "http://www.mql5.com"
|
|
|
|
#include <Object.mqh>
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
// Генерация псевдослучайной последовательности. Используется алгоритм Xorshift RNG
|
|
// (George Marsaglia) с периодом генерируемой последовательности (2**128)-1.
|
|
// uint rand_xor128()
|
|
// {
|
|
// static uint x=123456789,y=362436069,z=521288629,w=88675123;
|
|
// uint t=(x^(x<<11));x=y;y=z;z=w;
|
|
// return(w=(w^(w>>19))^(t^(t>>8)));
|
|
// }
|
|
// Методы:
|
|
// Rand() - равномерное распределение на отрезке [0,UINT_MAX=4294967295].
|
|
// Rand_01() - равномерное распределение на отрезке [0,1].
|
|
// Rand_Norm() - нормальное распределение с нулевым средним и единичной дисперсией.
|
|
// Rand_Exp() - экспоненциальное распределение с параметром 1.0.
|
|
// Rand_Laplace() - распределение Лапласа параметром 1.0
|
|
// Reset() - сброс всех исходных значений в первоначальное состояние.
|
|
// SRand() - установка новых исходных значений генератора.
|
|
//-----------------------------------------------------------------------------------
|
|
#define xor32 xx=xx^(xx<<13);xx=xx^(xx>>17);xx=xx^(xx<<5)
|
|
#define xor128 t=(x^(x<<11));x=y;y=z;z=w;w=(w^(w>>19))^(t^(t>>8))
|
|
#define inidat x=123456789;y=362436069;z=521288629;w=88675123;xx=2463534242
|
|
|
|
class RNDXor128:public CObject
|
|
{
|
|
protected:
|
|
uint x,y,z,w,xx,t;
|
|
uint UINT_half;
|
|
public:
|
|
RNDXor128() {UINT_half=UINT_MAX>>1;inidat;};
|
|
double Rand() {xor128;return((double)w);};
|
|
int Rand(double& a[],int n)
|
|
{int i;if(n<1)return(-1);
|
|
if(ArraySize(a)<n)return(-2);
|
|
for(i=0;i<n;i++){xor128;a[i]=(double)w;}
|
|
return(0);};
|
|
double Rand_01() {xor128;return((double)w/UINT_MAX);};
|
|
int Rand_01(double& a[],int n)
|
|
{int i;if(n<1)return(-1);
|
|
if(ArraySize(a)<n)return(-2);
|
|
for(i=0;i<n;i++){xor128;a[i]=(double)w/UINT_MAX;}
|
|
return(0);};
|
|
double Rand_Norm() {double v1,v2,s,sln;static double ra;static uint b=0;
|
|
if(b==w){b=0;return(ra);}
|
|
do{
|
|
xor128;v1=(double)w/UINT_half-1.0;
|
|
xor128;v2=(double)w/UINT_half-1.0;
|
|
s=v1*v1+v2*v2;
|
|
}
|
|
while(s>=1.0||s==0.0);
|
|
sln=MathLog(s);sln=MathSqrt((-sln-sln)/s);
|
|
ra=v2*sln;b=w;
|
|
return(v1*sln);};
|
|
int Rand_Norm(double& a[],int n)
|
|
{int i;if(n<1)return(-1);
|
|
if(ArraySize(a)<n)return(-2);
|
|
for(i=0;i<n;i++)a[i]=Rand_Norm();
|
|
return(0);};
|
|
double Rand_Exp() {xor128;if(w==0)return(DBL_MAX);
|
|
return(-MathLog((double)w/UINT_MAX));};
|
|
int Rand_Exp(double& a[],int n)
|
|
{int i;if(n<1)return(-1);
|
|
if(ArraySize(a)<n)return(-2);
|
|
for(i=0;i<n;i++)a[i]=Rand_Exp();
|
|
return(0);};
|
|
double Rand_Laplace() {double a;xor128;
|
|
a=(double)w/UINT_half;
|
|
if(w>UINT_half)
|
|
{a=2.0-a;
|
|
if(a==0.0)return(-DBL_MAX);
|
|
return(MathLog(a));}
|
|
else
|
|
{if(a==0.0)return(DBL_MAX);
|
|
return(-MathLog(a));}};
|
|
int Rand_Laplace(double& a[],int n)
|
|
{int i;if(n<1)return(-1);
|
|
if(ArraySize(a)<n)return(-2);
|
|
for(i=0;i<n;i++)a[i]=Rand_Laplace();
|
|
return(0);};
|
|
void Reset() {inidat;};
|
|
void SRand(uint seed) {int i;if(seed!=0)xx=seed;
|
|
for(i=0;i<16;i++){xor32;}
|
|
xor32;x=xx;xor32;y=xx;
|
|
xor32;z=xx;xor32;w=xx;
|
|
for(i=0;i<16;i++){xor128;}};
|
|
int SRand(uint xs,uint ys,uint zs,uint ws)
|
|
{int i;if(xs==0&&ys==0&&zs==0&&ws==0)return(-1);
|
|
x=xs;y=ys;z=zs;w=ws;
|
|
for(i=0;i<16;i++){xor128;}
|
|
return(0);};
|
|
};
|
|
//-----------------------------------------------------------------------------------
|