/************************************************************************* * * L'Ecuyer, Efficient and portable combined random number generators *************************************************************************/ private static int hqrndintegerbase(ref hqrndstate state) { int result = 0; int k = 0; System.Diagnostics.Debug.Assert(state.magicv == hqrndmagic, "HQRNDIntegerBase: State is not correctly initialized!"); k = state.s1 / 53668; state.s1 = 40014 * (state.s1 - k * 53668) - k * 12211; if (state.s1 < 0) { state.s1 = state.s1 + 2147483563; } k = state.s2 / 52774; state.s2 = 40692 * (state.s2 - k * 52774) - k * 3791; if (state.s2 < 0) { state.s2 = state.s2 + 2147483399; } // // Result // result = state.s1 - state.s2; if (result < 1) { result = result + 2147483562; } return(result); }
/************************************************************************* * Random number generator: normal numbers * * This function generates two independent random numbers from normal * distribution. Its performance is equal to that of HQRNDNormal() * * State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). * * -- ALGLIB -- * Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndnormal2(ref hqrndstate state, ref double x1, ref double x2) { double u = 0; double v = 0; double s = 0; while (true) { u = 2 * hqrnduniformr(ref state) - 1; v = 2 * hqrnduniformr(ref state) - 1; s = AP.Math.Sqr(u) + AP.Math.Sqr(v); if ((double)(s) > (double)(0) & (double)(s) < (double)(1)) { // // two Sqrt's instead of one to // avoid overflow when S is too small // s = Math.Sqrt(-(2 * Math.Log(s))) / Math.Sqrt(s); x1 = u * s; x2 = v * s; return; } } }
/************************************************************************* * This function generates random real number in (0,1), * not including interval boundaries * * State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). * * -- ALGLIB -- * Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static double hqrnduniformr(ref hqrndstate state) { double result = 0; result = state.v * hqrndintegerbase(ref state); return(result); }
/************************************************************************* * HQRNDState initialization with seed values * * -- ALGLIB -- * Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndseed(int s1, int s2, ref hqrndstate state) { state.s1 = s1 % (hqrndm1 - 1) + 1; state.s2 = s2 % (hqrndm2 - 1) + 1; state.v = (double)(1) / (double)(hqrndmax); state.magicv = hqrndmagic; }
/************************************************************************* * Random number generator: exponential distribution * * State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). * * -- ALGLIB -- * Copyright 11.08.2007 by Bochkanov Sergey *************************************************************************/ public static double hqrndexponential(double lambda, ref hqrndstate state) { double result = 0; System.Diagnostics.Debug.Assert((double)(lambda) > (double)(0), "HQRNDExponential: Lambda<=0!"); result = -(Math.Log(hqrnduniformr(ref state)) / lambda); return(result); }
/************************************************************************* HQRNDState initialization with seed values -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndseed(int s1, int s2, ref hqrndstate state) { state.s1 = s1%(hqrndm1-1)+1; state.s2 = s2%(hqrndm2-1)+1; state.v = (double)(1)/(double)(hqrndmax); state.magicv = hqrndmagic; }
/************************************************************************* * Random number generator: normal numbers * * This function generates one random number from normal distribution. * Its performance is equal to that of HQRNDNormal2() * * State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). * * -- ALGLIB -- * Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static double hqrndnormal(ref hqrndstate state) { double result = 0; double v1 = 0; double v2 = 0; hqrndnormal2(ref state, ref v1, ref v2); result = v1; return(result); }
/************************************************************************* * Random number generator: random X and Y such that X^2+Y^2=1 * * State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). * * -- ALGLIB -- * Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndunit2(ref hqrndstate state, ref double x, ref double y) { double v = 0; double mx = 0; double mn = 0; do { hqrndnormal2(ref state, ref x, ref y); }while(!((double)(x) != (double)(0) | (double)(y) != (double)(0))); mx = Math.Max(Math.Abs(x), Math.Abs(y)); mn = Math.Min(Math.Abs(x), Math.Abs(y)); v = mx * Math.Sqrt(1 + AP.Math.Sqr(mn / mx)); x = x / v; y = y / v; }
/************************************************************************* * This function generates random integer number in [0, N) * * 1. N must be less than HQRNDMax-1. * 2. State structure must be initialized with HQRNDRandomize() or HQRNDSeed() * * -- ALGLIB -- * Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static int hqrnduniformi(int n, ref hqrndstate state) { int result = 0; int mx = 0; // // Correct handling of N's close to RNDBaseMax // (avoiding skewed distributions for RNDBaseMax<>K*N) // System.Diagnostics.Debug.Assert(n > 0, "HQRNDUniformI: N<=0!"); System.Diagnostics.Debug.Assert(n < hqrndmax - 1, "HQRNDUniformI: N>=RNDBaseMax-1!"); mx = hqrndmax - 1 - (hqrndmax - 1) % n; do { result = hqrndintegerbase(ref state) - 1; }while(result >= mx); result = result % n; return(result); }
/************************************************************************* This function generates random integer number in [0, N) 1. N must be less than HQRNDMax-1. 2. State structure must be initialized with HQRNDRandomize() or HQRNDSeed() -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static int hqrnduniformi(hqrndstate state, int n) { int result = hqrnd.hqrnduniformi(state.innerobj, n); return result; }
/************************************************************************* Random number generator: normal numbers This function generates one random number from normal distribution. Its performance is equal to that of HQRNDNormal2() State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static double hqrndnormal(hqrndstate state) { double result = hqrnd.hqrndnormal(state.innerobj); return result; }
/************************************************************************* This function generates random number from continuous distribution given by finite sample X. INPUT PARAMETERS State - high quality random number generator, must be initialized with HQRNDRandomize() or HQRNDSeed(). X - finite sample, array[N] (can be larger, in this case only leading N elements are used). THIS ARRAY MUST BE SORTED BY ASCENDING. N - number of elements to use, N>=1 RESULT this function returns random number from continuous distribution which tries to approximate X as mush as possible. min(X)<=Result<=max(X). -- ALGLIB -- Copyright 08.11.2011 by Bochkanov Sergey *************************************************************************/ public static double hqrndcontinuous(hqrndstate state, double[] x, int n) { double result = 0; double mx = 0; double mn = 0; int i = 0; alglib.ap.assert(n>0, "HQRNDContinuous: N<=0"); alglib.ap.assert(n<=alglib.ap.len(x), "HQRNDContinuous: Length(X)<N"); if( n==1 ) { result = x[0]; return result; } i = hqrnduniformi(state, n-1); mn = x[i]; mx = x[i+1]; alglib.ap.assert((double)(mx)>=(double)(mn), "HQRNDDiscrete: X is not sorted by ascending"); if( (double)(mx)!=(double)(mn) ) { result = (mx-mn)*hqrnduniformr(state)+mn; } else { result = mn; } return result; }
/************************************************************************* L'Ecuyer, Efficient and portable combined random number generators *************************************************************************/ private static int hqrndintegerbase(hqrndstate state) { int result = 0; int k = 0; alglib.ap.assert(state.magicv==hqrndmagic, "HQRNDIntegerBase: State is not correctly initialized!"); k = state.s1/53668; state.s1 = 40014*(state.s1-k*53668)-k*12211; if( state.s1<0 ) { state.s1 = state.s1+2147483563; } k = state.s2/52774; state.s2 = 40692*(state.s2-k*52774)-k*3791; if( state.s2<0 ) { state.s2 = state.s2+2147483399; } // // Result // result = state.s1-state.s2; if( result<1 ) { result = result+2147483562; } return result; }
/************************************************************************* This function generates random real number in (0,1), not including interval boundaries State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static double hqrnduniformr(hqrndstate state) { double result = hqrnd.hqrnduniformr(state.innerobj); return result; }
/************************************************************************* * HQRNDState initialization with random values which come from standard * RNG. * * -- ALGLIB -- * Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndrandomize(ref hqrndstate state) { hqrndseed(AP.Math.RandomInteger(hqrndm1), AP.Math.RandomInteger(hqrndm2), ref state); }
/************************************************************************* This function generates random real number in (0,1), not including interval boundaries State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static double hqrnduniformr(hqrndstate state) { double result = 0; result = state.v*hqrndintegerbase(state); return result; }
/************************************************************************* Random number generator: normal numbers This function generates one random number from normal distribution. Its performance is equal to that of HQRNDNormal2() State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static double hqrndnormal(hqrndstate state) { double result = 0; double v1 = 0; double v2 = 0; hqrndnormal2(state, ref v1, ref v2); result = v1; return result; }
/************************************************************************* This function generates random number from continuous distribution given by finite sample X. INPUT PARAMETERS State - high quality random number generator, must be initialized with HQRNDRandomize() or HQRNDSeed(). X - finite sample, array[N] (can be larger, in this case only leading N elements are used). THIS ARRAY MUST BE SORTED BY ASCENDING. N - number of elements to use, N>=1 RESULT this function returns random number from continuous distribution which tries to approximate X as mush as possible. min(X)<=Result<=max(X). -- ALGLIB -- Copyright 08.11.2011 by Bochkanov Sergey *************************************************************************/ public static double hqrndcontinuous(hqrndstate state, double[] x, int n) { double result = hqrnd.hqrndcontinuous(state.innerobj, x, n); return result; }
/************************************************************************* HQRNDState initialization with seed values -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndseed(int s1, int s2, out hqrndstate state) { state = new hqrndstate(); hqrnd.hqrndseed(s1, s2, state.innerobj); return; }
/************************************************************************* Random number generator: exponential distribution State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 11.08.2007 by Bochkanov Sergey *************************************************************************/ public static double hqrndexponential(hqrndstate state, double lambdav) { double result = hqrnd.hqrndexponential(state.innerobj, lambdav); return result; }
/************************************************************************* Random number generator: random X and Y such that X^2+Y^2=1 State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndunit2(hqrndstate state, out double x, out double y) { x = 0; y = 0; hqrnd.hqrndunit2(state.innerobj, ref x, ref y); return; }
/************************************************************************* HQRNDState initialization with random values which come from standard RNG. -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndrandomize(ref hqrndstate state) { hqrndseed(AP.Math.RandomInteger(hqrndm1), AP.Math.RandomInteger(hqrndm2), ref state); }
/************************************************************************* Random number generator: exponential distribution State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 11.08.2007 by Bochkanov Sergey *************************************************************************/ public static double hqrndexponential(double lambda, ref hqrndstate state) { double result = 0; System.Diagnostics.Debug.Assert((double)(lambda)>(double)(0), "HQRNDExponential: Lambda<=0!"); result = -(Math.Log(hqrnduniformr(ref state))/lambda); return result; }
/************************************************************************* This function generates random integer number in [0, N) 1. N must be less than HQRNDMax-1. 2. State structure must be initialized with HQRNDRandomize() or HQRNDSeed() -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static int hqrnduniformi(int n, ref hqrndstate state) { int result = 0; int mx = 0; // // Correct handling of N's close to RNDBaseMax // (avoiding skewed distributions for RNDBaseMax<>K*N) // System.Diagnostics.Debug.Assert(n>0, "HQRNDUniformI: N<=0!"); System.Diagnostics.Debug.Assert(n<hqrndmax-1, "HQRNDUniformI: N>=RNDBaseMax-1!"); mx = hqrndmax-1-(hqrndmax-1)%n; do { result = hqrndintegerbase(ref state)-1; } while( result>=mx ); result = result%n; return result; }
/************************************************************************* Random number generator: normal numbers This function generates two independent random numbers from normal distribution. Its performance is equal to that of HQRNDNormal() State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndnormal2(hqrndstate state, out double x1, out double x2) { x1 = 0; x2 = 0; hqrnd.hqrndnormal2(state.innerobj, ref x1, ref x2); return; }
public override alglib.apobject make_copy() { hqrndstate _result = new hqrndstate(); _result.s1 = s1; _result.s2 = s2; _result.magicv = magicv; return _result; }
/************************************************************************* This function generates random number from discrete distribution given by finite sample X. INPUT PARAMETERS State - high quality random number generator, must be initialized with HQRNDRandomize() or HQRNDSeed(). X - finite sample N - number of elements to use, N>=1 RESULT this function returns one of the X[i] for random i=0..N-1 -- ALGLIB -- Copyright 08.11.2011 by Bochkanov Sergey *************************************************************************/ public static double hqrnddiscrete(hqrndstate state, double[] x, int n) { double result = hqrnd.hqrnddiscrete(state.innerobj, x, n); return result; }
/************************************************************************* HQRNDState initialization with seed values -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndseed(int s1, int s2, hqrndstate state) { // // Protection against negative seeds: // // SEED := -(SEED+1) // // We can use just "-SEED" because there exists such integer number N // that N<0, -N=N<0 too. (This number is equal to 0x800...000). Need // to handle such seed correctly forces us to use a bit complicated // formula. // if( s1<0 ) { s1 = -(s1+1); } if( s2<0 ) { s2 = -(s2+1); } state.s1 = s1%(hqrndm1-1)+1; state.s2 = s2%(hqrndm2-1)+1; state.magicv = hqrndmagic; }
/************************************************************************* HQRNDState initialization with random values which come from standard RNG. -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndrandomize(out hqrndstate state) { state = new hqrndstate(); hqrnd.hqrndrandomize(state.innerobj); return; }
/************************************************************************* This function generates random real number in (0,1), not including interval boundaries State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static double hqrnduniformr(hqrndstate state) { double result = 0; result = (double)(hqrndintegerbase(state)+1)/(double)(hqrndmax+2); return result; }
/************************************************************************* HQRNDState initialization with random values which come from standard RNG. -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndrandomize(hqrndstate state) { int s0 = 0; int s1 = 0; s0 = math.randominteger(hqrndm1); s1 = math.randominteger(hqrndm2); hqrndseed(s0, s1, state); }
/************************************************************************* This function generates random integer number in [0, N) 1. State structure must be initialized with HQRNDRandomize() or HQRNDSeed() 2. N can be any positive number except for very large numbers: * close to 2^31 on 32-bit systems * close to 2^62 on 64-bit systems An exception will be generated if N is too large. -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static int hqrnduniformi(hqrndstate state, int n) { int result = 0; int maxcnt = 0; int mx = 0; int a = 0; int b = 0; alglib.ap.assert(n>0, "HQRNDUniformI: N<=0!"); maxcnt = hqrndmax+1; // // Two branches: one for N<=MaxCnt, another for N>MaxCnt. // if( n>maxcnt ) { // // N>=MaxCnt. // // We have two options here: // a) N is exactly divisible by MaxCnt // b) N is not divisible by MaxCnt // // In both cases we reduce problem on interval spanning [0,N) // to several subproblems on intervals spanning [0,MaxCnt). // if( n%maxcnt==0 ) { // // N is exactly divisible by MaxCnt. // // [0,N) range is dividided into N/MaxCnt bins, // each of them having length equal to MaxCnt. // // We generate: // * random bin number B // * random offset within bin A // Both random numbers are generated by recursively // calling HQRNDUniformI(). // // Result is equal to A+MaxCnt*B. // alglib.ap.assert(n/maxcnt<=maxcnt, "HQRNDUniformI: N is too large"); a = hqrnduniformi(state, maxcnt); b = hqrnduniformi(state, n/maxcnt); result = a+maxcnt*b; } else { // // N is NOT exactly divisible by MaxCnt. // // [0,N) range is dividided into Ceil(N/MaxCnt) bins, // each of them having length equal to MaxCnt. // // We generate: // * random bin number B in [0, Ceil(N/MaxCnt)-1] // * random offset within bin A // * if both of what is below is true // 1) bin number B is that of the last bin // 2) A >= N mod MaxCnt // then we repeat generation of A/B. // This stage is essential in order to avoid bias in the result. // * otherwise, we return A*MaxCnt+N // alglib.ap.assert(n/maxcnt+1<=maxcnt, "HQRNDUniformI: N is too large"); result = -1; do { a = hqrnduniformi(state, maxcnt); b = hqrnduniformi(state, n/maxcnt+1); if( b==n/maxcnt && a>=n%maxcnt ) { continue; } result = a+maxcnt*b; } while( result<0 ); } } else { // // N<=MaxCnt // // Code below is a bit complicated because we can not simply // return "HQRNDIntegerBase() mod N" - it will be skewed for // large N's in [0.1*HQRNDMax...HQRNDMax]. // mx = maxcnt-maxcnt%n; do { result = hqrndintegerbase(state); } while( result>=mx ); result = result%n; } return result; }
/************************************************************************* This function generates random integer number in [0, N) 1. N must be less than HQRNDMax-1. 2. State structure must be initialized with HQRNDRandomize() or HQRNDSeed() -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static int hqrnduniformi(hqrndstate state, int n) { int result = 0; int mx = 0; // // Correct handling of N's close to RNDBaseMax // (avoiding skewed distributions for RNDBaseMax<>K*N) // alglib.ap.assert(n>0, "HQRNDUniformI: N<=0!"); alglib.ap.assert(n<hqrndmax-1, "HQRNDUniformI: N>=RNDBaseMax-1!"); mx = hqrndmax-1-(hqrndmax-1)%n; do { result = hqrndintegerbase(state)-1; } while( result>=mx ); result = result%n; return result; }
/************************************************************************* HQRNDState initialization with random values which come from standard RNG. -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndrandomize(hqrndstate state) { hqrndseed(math.randominteger(hqrndm1), math.randominteger(hqrndm2), state); }
/************************************************************************* Random number generator: random X and Y such that X^2+Y^2=1 State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndunit2(hqrndstate state, ref double x, ref double y) { double v = 0; double mx = 0; double mn = 0; x = 0; y = 0; do { hqrndnormal2(state, ref x, ref y); } while( !((double)(x)!=(double)(0) || (double)(y)!=(double)(0)) ); mx = Math.Max(Math.Abs(x), Math.Abs(y)); mn = Math.Min(Math.Abs(x), Math.Abs(y)); v = mx*Math.Sqrt(1+math.sqr(mn/mx)); x = x/v; y = y/v; }
/************************************************************************* Random number generator: exponential distribution State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 11.08.2007 by Bochkanov Sergey *************************************************************************/ public static double hqrndexponential(hqrndstate state, double lambdav) { double result = 0; alglib.ap.assert((double)(lambdav)>(double)(0), "HQRNDExponential: LambdaV<=0!"); result = -(Math.Log(hqrnduniformr(state))/lambdav); return result; }
/************************************************************************* Random number generator: normal numbers This function generates two independent random numbers from normal distribution. Its performance is equal to that of HQRNDNormal() State structure must be initialized with HQRNDRandomize() or HQRNDSeed(). -- ALGLIB -- Copyright 02.12.2009 by Bochkanov Sergey *************************************************************************/ public static void hqrndnormal2(hqrndstate state, ref double x1, ref double x2) { double u = 0; double v = 0; double s = 0; x1 = 0; x2 = 0; while( true ) { u = 2*hqrnduniformr(state)-1; v = 2*hqrnduniformr(state)-1; s = math.sqr(u)+math.sqr(v); if( (double)(s)>(double)(0) && (double)(s)<(double)(1) ) { // // two Sqrt's instead of one to // avoid overflow when S is too small // s = Math.Sqrt(-(2*Math.Log(s)))/Math.Sqrt(s); x1 = u*s; x2 = v*s; return; } } }
/************************************************************************* This function generates random number from discrete distribution given by finite sample X. INPUT PARAMETERS State - high quality random number generator, must be initialized with HQRNDRandomize() or HQRNDSeed(). X - finite sample N - number of elements to use, N>=1 RESULT this function returns one of the X[i] for random i=0..N-1 -- ALGLIB -- Copyright 08.11.2011 by Bochkanov Sergey *************************************************************************/ public static double hqrnddiscrete(hqrndstate state, double[] x, int n) { double result = 0; alglib.ap.assert(n>0, "HQRNDDiscrete: N<=0"); alglib.ap.assert(n<=alglib.ap.len(x), "HQRNDDiscrete: Length(X)<N"); result = x[hqrnduniformi(state, n)]; return result; }