RNDXor128_by_victorg/Include/RNDXor128.mqh

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);};
};
//-----------------------------------------------------------------------------------