Esempio n. 1
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
*************************************************************************/
double hqrndnormal(hqrndstate& state)
{
    double result;
    double v1;
    double v2;

    hqrndnormal2(state, v1, v2);
    result = v1;
    return result;
}
Esempio n. 2
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
*************************************************************************/
void hqrndunit2(hqrndstate& state, double& x, double& y)
{
    double v;
    double mx;
    double mn;

    do
    {
        hqrndnormal2(state, x, y);
    }
    while(!(ap::fp_neq(x,0)||ap::fp_neq(y,0)));
    mx = ap::maxreal(fabs(x), fabs(y));
    mn = ap::minreal(fabs(x), fabs(y));
    v = mx*sqrt(1+ap::sqr(mn/mx));
    x = x/v;
    y = y/v;
}
Esempio n. 3
0
/*************************************************************************
Hermitian multiplication of NxN matrix by random Haar distributed
complex orthogonal matrix

INPUT PARAMETERS:
    A   -   matrix, array[0..N-1, 0..N-1]
    N   -   matrix size

OUTPUT PARAMETERS:
    A   -   Q^H*A*Q, where Q is random NxN orthogonal matrix

  -- ALGLIB routine --
     04.12.2009
     Bochkanov Sergey
*************************************************************************/
void hmatrixrndmultiply(ap::complex_2d_array& a, int n)
{
    ap::complex tau;
    ap::complex lambda;
    int s;
    int i;
    int j;
    double u1;
    double u2;
    ap::complex_1d_array w;
    ap::complex_1d_array v;
    double sm;
    hqrndstate state;
    int i_;

    
    //
    // General case.
    //
    w.setbounds(0, n-1);
    v.setbounds(1, n);
    hqrndrandomize(state);
    for(s = 2; s <= n; s++)
    {
        
        //
        // Prepare random normal v
        //
        do
        {
            for(i = 1; i <= s; i++)
            {
                hqrndnormal2(state, tau.x, tau.y);
                v(i) = tau;
            }
            lambda = 0.0;
            for(i_=1; i_<=s;i_++)
            {
                lambda += v(i_)*ap::conj(v(i_));
            }
        }
        while(lambda==0);
        
        //
        // Prepare and apply reflection
        //
        complexgeneratereflection(v, s, tau);
        v(1) = 1;
        complexapplyreflectionfromtheright(a, tau, v, 0, n-1, n-s, n-1, w);
        complexapplyreflectionfromtheleft(a, ap::conj(tau), v, n-s, n-1, 0, n-1, w);
    }
    
    //
    // Second pass.
    //
    for(i = 0; i <= n-1; i++)
    {
        hqrndunit2(state, tau.x, tau.y);
        for(i_=0; i_<=n-1;i_++)
        {
            a(i_,i) = tau*a(i_,i);
        }
        tau = ap::conj(tau);
        for(i_=0; i_<=n-1;i_++)
        {
            a(i,i_) = tau*a(i,i_);
        }
    }
}
Esempio n. 4
0
/*************************************************************************
Symmetric multiplication of NxN matrix by random Haar distributed
orthogonal  matrix

INPUT PARAMETERS:
    A   -   matrix, array[0..N-1, 0..N-1]
    N   -   matrix size

OUTPUT PARAMETERS:
    A   -   Q'*A*Q, where Q is random NxN orthogonal matrix

  -- ALGLIB routine --
     04.12.2009
     Bochkanov Sergey
*************************************************************************/
void smatrixrndmultiply(ap::real_2d_array& a, int n)
{
    double tau;
    double lambda;
    int s;
    int i;
    int j;
    double u1;
    double u2;
    ap::real_1d_array w;
    ap::real_1d_array v;
    double sm;
    hqrndstate state;

    
    //
    // General case.
    //
    w.setbounds(0, n-1);
    v.setbounds(1, n);
    hqrndrandomize(state);
    for(s = 2; s <= n; s++)
    {
        
        //
        // Prepare random normal v
        //
        do
        {
            i = 1;
            while(i<=s)
            {
                hqrndnormal2(state, u1, u2);
                v(i) = u1;
                if( i+1<=s )
                {
                    v(i+1) = u2;
                }
                i = i+2;
            }
            lambda = ap::vdotproduct(&v(1), &v(1), ap::vlen(1,s));
        }
        while(ap::fp_eq(lambda,0));
        
        //
        // Prepare and apply reflection
        //
        generatereflection(v, s, tau);
        v(1) = 1;
        applyreflectionfromtheright(a, tau, v, 0, n-1, n-s, n-1, w);
        applyreflectionfromtheleft(a, tau, v, n-s, n-1, 0, n-1, w);
    }
    
    //
    // Second pass.
    //
    for(i = 0; i <= n-1; i++)
    {
        tau = 2*ap::randominteger(2)-1;
        ap::vmul(a.getcolumn(i, 0, n-1), tau);
        ap::vmul(&a(i, 0), ap::vlen(0,n-1), tau);
    }
}
Esempio n. 5
0
/*************************************************************************
Multiplication of MxN complex matrix by MxM random Haar distributed
complex orthogonal matrix

INPUT PARAMETERS:
    A   -   matrix, array[0..M-1, 0..N-1]
    M, N-   matrix size

OUTPUT PARAMETERS:
    A   -   Q*A, where Q is random MxM orthogonal matrix

  -- ALGLIB routine --
     04.12.2009
     Bochkanov Sergey
*************************************************************************/
void cmatrixrndorthogonalfromtheleft(ap::complex_2d_array& a, int m, int n)
{
    ap::complex tau;
    ap::complex lambda;
    int s;
    int i;
    int j;
    double u1;
    double u2;
    ap::complex_1d_array w;
    ap::complex_1d_array v;
    double sm;
    hqrndstate state;
    int i_;

    ap::ap_error::make_assertion(n>=1&&m>=1, "CMatrixRndOrthogonalFromTheRight: N<1 or M<1!");
    if( m==1 )
    {
        
        //
        // special case
        //
        hqrndrandomize(state);
        hqrndunit2(state, tau.x, tau.y);
        for(j = 0; j <= n-1; j++)
        {
            a(0,j) = a(0,j)*tau;
        }
        return;
    }
    
    //
    // General case.
    // First pass.
    //
    w.setbounds(0, n-1);
    v.setbounds(1, m);
    hqrndrandomize(state);
    for(s = 2; s <= m; s++)
    {
        
        //
        // Prepare random normal v
        //
        do
        {
            for(i = 1; i <= s; i++)
            {
                hqrndnormal2(state, tau.x, tau.y);
                v(i) = tau;
            }
            lambda = 0.0;
            for(i_=1; i_<=s;i_++)
            {
                lambda += v(i_)*ap::conj(v(i_));
            }
        }
        while(lambda==0);
        
        //
        // Prepare and apply reflection
        //
        complexgeneratereflection(v, s, tau);
        v(1) = 1;
        complexapplyreflectionfromtheleft(a, tau, v, m-s, m-1, 0, n-1, w);
    }
    
    //
    // Second pass.
    //
    for(i = 0; i <= m-1; i++)
    {
        hqrndunit2(state, tau.x, tau.y);
        for(i_=0; i_<=n-1;i_++)
        {
            a(i,i_) = tau*a(i,i_);
        }
    }
}
Esempio n. 6
0
/*************************************************************************
Multiplication of MxN matrix by MxM random Haar distributed orthogonal matrix

INPUT PARAMETERS:
    A   -   matrix, array[0..M-1, 0..N-1]
    M, N-   matrix size

OUTPUT PARAMETERS:
    A   -   Q*A, where Q is random MxM orthogonal matrix

  -- ALGLIB routine --
     04.12.2009
     Bochkanov Sergey
*************************************************************************/
void rmatrixrndorthogonalfromtheleft(ap::real_2d_array& a, int m, int n)
{
    double tau;
    double lambda;
    int s;
    int i;
    int j;
    double u1;
    double u2;
    ap::real_1d_array w;
    ap::real_1d_array v;
    double sm;
    hqrndstate state;

    ap::ap_error::make_assertion(n>=1&&m>=1, "RMatrixRndOrthogonalFromTheRight: N<1 or M<1!");
    if( m==1 )
    {
        
        //
        // special case
        //
        tau = 2*ap::randominteger(2)-1;
        for(j = 0; j <= n-1; j++)
        {
            a(0,j) = a(0,j)*tau;
        }
        return;
    }
    
    //
    // General case.
    // First pass.
    //
    w.setbounds(0, n-1);
    v.setbounds(1, m);
    hqrndrandomize(state);
    for(s = 2; s <= m; s++)
    {
        
        //
        // Prepare random normal v
        //
        do
        {
            i = 1;
            while(i<=s)
            {
                hqrndnormal2(state, u1, u2);
                v(i) = u1;
                if( i+1<=s )
                {
                    v(i+1) = u2;
                }
                i = i+2;
            }
            lambda = ap::vdotproduct(&v(1), &v(1), ap::vlen(1,s));
        }
        while(ap::fp_eq(lambda,0));
        
        //
        // Prepare and apply reflection
        //
        generatereflection(v, s, tau);
        v(1) = 1;
        applyreflectionfromtheleft(a, tau, v, m-s, m-1, 0, n-1, w);
    }
    
    //
    // Second pass.
    //
    for(i = 0; i <= m-1; i++)
    {
        tau = 2*ap::randominteger(2)-1;
        ap::vmul(&a(i, 0), ap::vlen(0,n-1), tau);
    }
}
Esempio n. 7
0
bool testhqrnd(bool silent)
{
    bool result;
    bool waserrors;
    int samplesize;
    double sigmathreshold;
    int passcount;
    int n;
    int i;
    int pass;
    int s1;
    int s2;
    int i1;
    int i2;
    double r1;
    double r2;
    ap::real_1d_array x;
    double mean;
    double means;
    double stddev;
    double stddevs;
    double lambda;
    bool seederrors;
    bool urerrors;
    double ursigmaerr;
    bool uierrors;
    double uisigmaerr;
    bool normerrors;
    double normsigmaerr;
    bool experrors;
    double expsigmaerr;
    hqrndstate state;

    waserrors = false;
    sigmathreshold = 7;
    samplesize = 100000;
    passcount = 50;
    x.setbounds(0, samplesize-1);
    
    //
    // Test seed errors
    //
    seederrors = false;
    for(pass = 1; pass <= passcount; pass++)
    {
        s1 = 1+ap::randominteger(32000);
        s2 = 1+ap::randominteger(32000);
        unsetstate(state);
        hqrndseed(s1, s2, state);
        i1 = hqrnduniformi(100, state);
        unsetstate(state);
        hqrndseed(s1, s2, state);
        i2 = hqrnduniformi(100, state);
        seederrors = seederrors||i1!=i2;
        unsetstate(state);
        hqrndseed(s1, s2, state);
        r1 = hqrnduniformr(state);
        unsetstate(state);
        hqrndseed(s1, s2, state);
        r2 = hqrnduniformr(state);
        seederrors = seederrors||ap::fp_neq(r1,r2);
    }
    
    //
    // Test HQRNDRandomize() and real uniform generator
    //
    unsetstate(state);
    hqrndrandomize(state);
    urerrors = false;
    ursigmaerr = 0;
    for(i = 0; i <= samplesize-1; i++)
    {
        x(i) = hqrnduniformr(state);
    }
    for(i = 0; i <= samplesize-1; i++)
    {
        urerrors = urerrors||ap::fp_less_eq(x(i),0)||ap::fp_greater_eq(x(i),1);
    }
    calculatemv(x, samplesize, mean, means, stddev, stddevs);
    if( ap::fp_neq(means,0) )
    {
        ursigmaerr = ap::maxreal(ursigmaerr, fabs((mean-0.5)/means));
    }
    else
    {
        urerrors = true;
    }
    if( ap::fp_neq(stddevs,0) )
    {
        ursigmaerr = ap::maxreal(ursigmaerr, fabs((stddev-sqrt(double(1)/double(12)))/stddevs));
    }
    else
    {
        urerrors = true;
    }
    urerrors = urerrors||ap::fp_greater(ursigmaerr,sigmathreshold);
    
    //
    // Test HQRNDRandomize() and integer uniform
    //
    unsetstate(state);
    hqrndrandomize(state);
    uierrors = false;
    uisigmaerr = 0;
    for(n = 2; n <= 10; n++)
    {
        for(i = 0; i <= samplesize-1; i++)
        {
            x(i) = hqrnduniformi(n, state);
        }
        for(i = 0; i <= samplesize-1; i++)
        {
            uierrors = uierrors||ap::fp_less(x(i),0)||ap::fp_greater_eq(x(i),n);
        }
        calculatemv(x, samplesize, mean, means, stddev, stddevs);
        if( ap::fp_neq(means,0) )
        {
            uisigmaerr = ap::maxreal(uisigmaerr, fabs((mean-0.5*(n-1))/means));
        }
        else
        {
            uierrors = true;
        }
        if( ap::fp_neq(stddevs,0) )
        {
            uisigmaerr = ap::maxreal(uisigmaerr, fabs((stddev-sqrt((ap::sqr(double(n))-1)/12))/stddevs));
        }
        else
        {
            uierrors = true;
        }
    }
    uierrors = uierrors||ap::fp_greater(uisigmaerr,sigmathreshold);
    
    //
    // Special 'close-to-limit' test on uniformity of integers
    // (straightforward implementation like 'RND mod N' will return
    //  non-uniform numbers for N=2/3*LIMIT)
    //
    unsetstate(state);
    hqrndrandomize(state);
    uierrors = false;
    uisigmaerr = 0;
    n = ap::round(2.0/3.0*2147483563.0);
    for(i = 0; i <= samplesize-1; i++)
    {
        x(i) = hqrnduniformi(n, state);
    }
    for(i = 0; i <= samplesize-1; i++)
    {
        uierrors = uierrors||ap::fp_less(x(i),0)||ap::fp_greater_eq(x(i),n);
    }
    calculatemv(x, samplesize, mean, means, stddev, stddevs);
    if( ap::fp_neq(means,0) )
    {
        uisigmaerr = ap::maxreal(uisigmaerr, fabs((mean-0.5*(n-1))/means));
    }
    else
    {
        uierrors = true;
    }
    if( ap::fp_neq(stddevs,0) )
    {
        uisigmaerr = ap::maxreal(uisigmaerr, fabs((stddev-sqrt((ap::sqr(double(n))-1)/12))/stddevs));
    }
    else
    {
        uierrors = true;
    }
    uierrors = uierrors||ap::fp_greater(uisigmaerr,sigmathreshold);
    
    //
    // Test normal
    //
    unsetstate(state);
    hqrndrandomize(state);
    normerrors = false;
    normsigmaerr = 0;
    i = 0;
    while(i<samplesize)
    {
        hqrndnormal2(state, r1, r2);
        x(i) = r1;
        if( i+1<samplesize )
        {
            x(i+1) = r2;
        }
        i = i+2;
    }
    calculatemv(x, samplesize, mean, means, stddev, stddevs);
    if( ap::fp_neq(means,0) )
    {
        normsigmaerr = ap::maxreal(normsigmaerr, fabs((mean-0)/means));
    }
    else
    {
        normerrors = true;
    }
    if( ap::fp_neq(stddevs,0) )
    {
        normsigmaerr = ap::maxreal(normsigmaerr, fabs((stddev-1)/stddevs));
    }
    else
    {
        normerrors = true;
    }
    normerrors = normerrors||ap::fp_greater(normsigmaerr,sigmathreshold);
    
    //
    // Test exponential
    //
    unsetstate(state);
    hqrndrandomize(state);
    experrors = false;
    expsigmaerr = 0;
    lambda = 2+5*ap::randomreal();
    for(i = 0; i <= samplesize-1; i++)
    {
        x(i) = hqrndexponential(lambda, state);
    }
    for(i = 0; i <= samplesize-1; i++)
    {
        uierrors = uierrors||ap::fp_less(x(i),0);
    }
    calculatemv(x, samplesize, mean, means, stddev, stddevs);
    if( ap::fp_neq(means,0) )
    {
        expsigmaerr = ap::maxreal(expsigmaerr, fabs((mean-1.0/lambda)/means));
    }
    else
    {
        experrors = true;
    }
    if( ap::fp_neq(stddevs,0) )
    {
        expsigmaerr = ap::maxreal(expsigmaerr, fabs((stddev-1.0/lambda)/stddevs));
    }
    else
    {
        experrors = true;
    }
    experrors = experrors||ap::fp_greater(expsigmaerr,sigmathreshold);
    
    //
    // Final report
    //
    waserrors = seederrors||urerrors||uierrors||normerrors||experrors;
    if( !silent )
    {
        printf("RNG TEST\n");
        printf("SEED TEST:                               ");
        if( !seederrors )
        {
            printf("OK\n");
        }
        else
        {
            printf("FAILED\n");
        }
        printf("UNIFORM CONTINUOUS:                      ");
        if( !urerrors )
        {
            printf("OK\n");
        }
        else
        {
            printf("FAILED\n");
        }
        printf("UNIFORM INTEGER:                         ");
        if( !uierrors )
        {
            printf("OK\n");
        }
        else
        {
            printf("FAILED\n");
        }
        printf("NORMAL:                                  ");
        if( !normerrors )
        {
            printf("OK\n");
        }
        else
        {
            printf("FAILED\n");
        }
        printf("EXPONENTIAL:                             ");
        if( !experrors )
        {
            printf("OK\n");
        }
        else
        {
            printf("FAILED\n");
        }
        if( waserrors )
        {
            printf("TEST SUMMARY: FAILED\n");
        }
        else
        {
            printf("TEST SUMMARY: PASSED\n");
        }
        printf("\n\n");
    }
    result = !waserrors;
    return result;
}