Example #1
0
        /*************************************************************************
        *
        *  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);
        }
Example #2
0
        /*************************************************************************
        *  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;
                }
            }
        }
Example #3
0
        /*************************************************************************
        *  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);
        }
Example #4
0
 /*************************************************************************
 *  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;
 }
Example #5
0
        /*************************************************************************
        *  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);
        }
Example #6
0
        /*************************************************************************
        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;
        }
Example #7
0
        /*************************************************************************
        *  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);
        }
Example #8
0
        /*************************************************************************
        *  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;
        }
Example #9
0
        /*************************************************************************
        *  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;
    }
Example #15
0
 /*************************************************************************
 *  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;
    }
Example #22
0
        /*************************************************************************
        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);
        }
Example #23
0
        /*************************************************************************
        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;
        }
Example #24
0
        /*************************************************************************
        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;
    }
Example #26
0
 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;
    }
Example #28
0
        /*************************************************************************
        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;
    }
Example #30
0
        /*************************************************************************
        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);
        }
Example #32
0
        /*************************************************************************
        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;
        }