Ejemplo n.º 1
0
bool testmatgen(bool silent)
{
    bool result;
    ap::real_2d_array a;
    ap::real_2d_array b;
    ap::real_2d_array u;
    ap::real_2d_array v;
    ap::complex_2d_array ca;
    ap::complex_2d_array cb;
    ap::real_2d_array r1;
    ap::real_2d_array r2;
    ap::complex_2d_array c1;
    ap::complex_2d_array c2;
    ap::real_1d_array w;
    int n;
    int maxn;
    int i;
    int j;
    int pass;
    int passcount;
    bool waserrors;
    double cond;
    double threshold;
    double vt;
    ap::complex ct;
    double minw;
    double maxw;
    bool serr;
    bool herr;
    bool spderr;
    bool hpderr;
    bool rerr;
    bool cerr;
    int i_;

    rerr = false;
    cerr = false;
    serr = false;
    herr = false;
    spderr = false;
    hpderr = false;
    waserrors = false;
    maxn = 20;
    passcount = 15;
    threshold = 1000*ap::machineepsilon;
    
    //
    // Testing orthogonal
    //
    for(n = 1; n <= maxn; n++)
    {
        for(pass = 1; pass <= passcount; pass++)
        {
            r1.setbounds(0, n-1, 0, 2*n-1);
            r2.setbounds(0, 2*n-1, 0, n-1);
            c1.setbounds(0, n-1, 0, 2*n-1);
            c2.setbounds(0, 2*n-1, 0, n-1);
            
            //
            // Random orthogonal, real
            //
            unset2d(a);
            unset2d(b);
            rmatrixrndorthogonal(n, a);
            rmatrixrndorthogonal(n, b);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    
                    //
                    // orthogonality test
                    //
                    vt = ap::vdotproduct(&a(i, 0), &a(j, 0), ap::vlen(0,n-1));
                    if( i==j )
                    {
                        rerr = rerr||ap::fp_greater(fabs(vt-1),threshold);
                    }
                    else
                    {
                        rerr = rerr||ap::fp_greater(fabs(vt),threshold);
                    }
                    vt = ap::vdotproduct(&b(i, 0), &b(j, 0), ap::vlen(0,n-1));
                    if( i==j )
                    {
                        rerr = rerr||ap::fp_greater(fabs(vt-1),threshold);
                    }
                    else
                    {
                        rerr = rerr||ap::fp_greater(fabs(vt),threshold);
                    }
                    
                    //
                    // test for difference in A and B
                    //
                    if( n>=2 )
                    {
                        rerr = rerr||ap::fp_eq(a(i,j),b(i,j));
                    }
                }
            }
            
            //
            // Random orthogonal, complex
            //
            unset2dc(ca);
            unset2dc(cb);
            cmatrixrndorthogonal(n, ca);
            cmatrixrndorthogonal(n, cb);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    
                    //
                    // orthogonality test
                    //
                    ct = 0.0;
                    for(i_=0; i_<=n-1;i_++)
                    {
                        ct += ca(i,i_)*ap::conj(ca(j,i_));
                    }
                    if( i==j )
                    {
                        cerr = cerr||ap::fp_greater(ap::abscomplex(ct-1),threshold);
                    }
                    else
                    {
                        cerr = cerr||ap::fp_greater(ap::abscomplex(ct),threshold);
                    }
                    ct = 0.0;
                    for(i_=0; i_<=n-1;i_++)
                    {
                        ct += cb(i,i_)*ap::conj(cb(j,i_));
                    }
                    if( i==j )
                    {
                        cerr = cerr||ap::fp_greater(ap::abscomplex(ct-1),threshold);
                    }
                    else
                    {
                        cerr = cerr||ap::fp_greater(ap::abscomplex(ct),threshold);
                    }
                    
                    //
                    // test for difference in A and B
                    //
                    if( n>=2 )
                    {
                        cerr = cerr||ca(i,j)==cb(i,j);
                    }
                }
            }
            
            //
            // From the right real tests:
            // 1. E*Q is orthogonal
            // 2. Q1<>Q2 (routine result is changing)
            // 3. (E E)'*Q = (Q' Q')' (correct handling of non-square matrices)
            //
            unset2d(a);
            unset2d(b);
            a.setbounds(0, n-1, 0, n-1);
            b.setbounds(0, n-1, 0, n-1);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    a(i,j) = 0;
                    b(i,j) = 0;
                }
                a(i,i) = 1;
                b(i,i) = 1;
            }
            rmatrixrndorthogonalfromtheright(a, n, n);
            rmatrixrndorthogonalfromtheright(b, n, n);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    
                    //
                    // orthogonality test
                    //
                    vt = ap::vdotproduct(&a(i, 0), &a(j, 0), ap::vlen(0,n-1));
                    if( i==j )
                    {
                        rerr = rerr||ap::fp_greater(fabs(vt-1),threshold);
                    }
                    else
                    {
                        rerr = rerr||ap::fp_greater(fabs(vt),threshold);
                    }
                    vt = ap::vdotproduct(&b(i, 0), &b(j, 0), ap::vlen(0,n-1));
                    if( i==j )
                    {
                        rerr = rerr||ap::fp_greater(fabs(vt-1),threshold);
                    }
                    else
                    {
                        rerr = rerr||ap::fp_greater(fabs(vt),threshold);
                    }
                    
                    //
                    // test for difference in A and B
                    //
                    if( n>=2 )
                    {
                        rerr = rerr||ap::fp_eq(a(i,j),b(i,j));
                    }
                }
            }
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    r2(i,j) = 2*ap::randomreal()-1;
                    r2(i+n,j) = r2(i,j);
                }
            }
            rmatrixrndorthogonalfromtheright(r2, 2*n, n);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    rerr = rerr||ap::fp_greater(fabs(r2(i+n,j)-r2(i,j)),threshold);
                }
            }
            
            //
            // From the left real tests:
            // 1. Q*E is orthogonal
            // 2. Q1<>Q2 (routine result is changing)
            // 3. Q*(E E) = (Q Q) (correct handling of non-square matrices)
            //
            unset2d(a);
            unset2d(b);
            a.setbounds(0, n-1, 0, n-1);
            b.setbounds(0, n-1, 0, n-1);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    a(i,j) = 0;
                    b(i,j) = 0;
                }
                a(i,i) = 1;
                b(i,i) = 1;
            }
            rmatrixrndorthogonalfromtheleft(a, n, n);
            rmatrixrndorthogonalfromtheleft(b, n, n);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    
                    //
                    // orthogonality test
                    //
                    vt = ap::vdotproduct(&a(i, 0), &a(j, 0), ap::vlen(0,n-1));
                    if( i==j )
                    {
                        rerr = rerr||ap::fp_greater(fabs(vt-1),threshold);
                    }
                    else
                    {
                        rerr = rerr||ap::fp_greater(fabs(vt),threshold);
                    }
                    vt = ap::vdotproduct(&b(i, 0), &b(j, 0), ap::vlen(0,n-1));
                    if( i==j )
                    {
                        rerr = rerr||ap::fp_greater(fabs(vt-1),threshold);
                    }
                    else
                    {
                        rerr = rerr||ap::fp_greater(fabs(vt),threshold);
                    }
                    
                    //
                    // test for difference in A and B
                    //
                    if( n>=2 )
                    {
                        rerr = rerr||ap::fp_eq(a(i,j),b(i,j));
                    }
                }
            }
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    r1(i,j) = 2*ap::randomreal()-1;
                    r1(i,j+n) = r1(i,j);
                }
            }
            rmatrixrndorthogonalfromtheleft(r1, n, 2*n);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    rerr = rerr||ap::fp_greater(fabs(r1(i,j)-r1(i,j+n)),threshold);
                }
            }
            
            //
            // From the right complex tests:
            // 1. E*Q is orthogonal
            // 2. Q1<>Q2 (routine result is changing)
            // 3. (E E)'*Q = (Q' Q')' (correct handling of non-square matrices)
            //
            unset2dc(ca);
            unset2dc(cb);
            ca.setbounds(0, n-1, 0, n-1);
            cb.setbounds(0, n-1, 0, n-1);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    ca(i,j) = 0;
                    cb(i,j) = 0;
                }
                ca(i,i) = 1;
                cb(i,i) = 1;
            }
            cmatrixrndorthogonalfromtheright(ca, n, n);
            cmatrixrndorthogonalfromtheright(cb, n, n);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    
                    //
                    // orthogonality test
                    //
                    ct = 0.0;
                    for(i_=0; i_<=n-1;i_++)
                    {
                        ct += ca(i,i_)*ap::conj(ca(j,i_));
                    }
                    if( i==j )
                    {
                        cerr = cerr||ap::fp_greater(ap::abscomplex(ct-1),threshold);
                    }
                    else
                    {
                        cerr = cerr||ap::fp_greater(ap::abscomplex(ct),threshold);
                    }
                    ct = 0.0;
                    for(i_=0; i_<=n-1;i_++)
                    {
                        ct += cb(i,i_)*ap::conj(cb(j,i_));
                    }
                    if( i==j )
                    {
                        cerr = cerr||ap::fp_greater(ap::abscomplex(ct-1),threshold);
                    }
                    else
                    {
                        cerr = cerr||ap::fp_greater(ap::abscomplex(ct),threshold);
                    }
                    
                    //
                    // test for difference in A and B
                    //
                    cerr = cerr||ca(i,j)==cb(i,j);
                }
            }
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    c2(i,j) = 2*ap::randomreal()-1;
                    c2(i+n,j) = c2(i,j);
                }
            }
            cmatrixrndorthogonalfromtheright(c2, 2*n, n);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    cerr = cerr||ap::fp_greater(ap::abscomplex(c2(i+n,j)-c2(i,j)),threshold);
                }
            }
            
            //
            // From the left complex tests:
            // 1. Q*E is orthogonal
            // 2. Q1<>Q2 (routine result is changing)
            // 3. Q*(E E) = (Q Q) (correct handling of non-square matrices)
            //
            unset2dc(ca);
            unset2dc(cb);
            ca.setbounds(0, n-1, 0, n-1);
            cb.setbounds(0, n-1, 0, n-1);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    ca(i,j) = 0;
                    cb(i,j) = 0;
                }
                ca(i,i) = 1;
                cb(i,i) = 1;
            }
            cmatrixrndorthogonalfromtheleft(ca, n, n);
            cmatrixrndorthogonalfromtheleft(cb, n, n);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    
                    //
                    // orthogonality test
                    //
                    ct = 0.0;
                    for(i_=0; i_<=n-1;i_++)
                    {
                        ct += ca(i,i_)*ap::conj(ca(j,i_));
                    }
                    if( i==j )
                    {
                        cerr = cerr||ap::fp_greater(ap::abscomplex(ct-1),threshold);
                    }
                    else
                    {
                        cerr = cerr||ap::fp_greater(ap::abscomplex(ct),threshold);
                    }
                    ct = 0.0;
                    for(i_=0; i_<=n-1;i_++)
                    {
                        ct += cb(i,i_)*ap::conj(cb(j,i_));
                    }
                    if( i==j )
                    {
                        cerr = cerr||ap::fp_greater(ap::abscomplex(ct-1),threshold);
                    }
                    else
                    {
                        cerr = cerr||ap::fp_greater(ap::abscomplex(ct),threshold);
                    }
                    
                    //
                    // test for difference in A and B
                    //
                    cerr = cerr||ca(i,j)==cb(i,j);
                }
            }
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    c1(i,j) = 2*ap::randomreal()-1;
                    c1(i,j+n) = c1(i,j);
                }
            }
            cmatrixrndorthogonalfromtheleft(c1, n, 2*n);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    cerr = cerr||ap::fp_greater(ap::abscomplex(c1(i,j)-c1(i,j+n)),threshold);
                }
            }
        }
    }
    
    //
    // Testing GCond
    //
    for(n = 2; n <= maxn; n++)
    {
        for(pass = 1; pass <= passcount; pass++)
        {
            
            //
            // real test
            //
            unset2d(a);
            cond = exp(log(double(1000))*ap::randomreal());
            rmatrixrndcond(n, cond, a);
            b.setbounds(1, n, 1, n);
            for(i = 1; i <= n; i++)
            {
                for(j = 1; j <= n; j++)
                {
                    b(i,j) = a(i-1,j-1);
                }
            }
            if( obsoletesvddecomposition(b, n, n, w, v) )
            {
                maxw = w(1);
                minw = w(1);
                for(i = 2; i <= n; i++)
                {
                    if( ap::fp_greater(w(i),maxw) )
                    {
                        maxw = w(i);
                    }
                    if( ap::fp_less(w(i),minw) )
                    {
                        minw = w(i);
                    }
                }
                vt = maxw/minw/cond;
                if( ap::fp_greater(fabs(log(vt)),log(1+threshold)) )
                {
                    rerr = true;
                }
            }
        }
    }
    
    //
    // Symmetric/SPD
    // N = 2 .. 30
    //
    for(n = 2; n <= maxn; n++)
    {
        
        //
        // SPD matrices
        //
        for(pass = 1; pass <= passcount; pass++)
        {
            
            //
            // Generate A
            //
            unset2d(a);
            cond = exp(log(double(1000))*ap::randomreal());
            spdmatrixrndcond(n, cond, a);
            
            //
            // test condition number
            //
            spderr = spderr||ap::fp_greater(svdcond(a, n)/cond-1,threshold);
            
            //
            // test SPD
            //
            spderr = spderr||!isspd(a, n, true);
            
            //
            // test that A is symmetic
            //
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    spderr = spderr||ap::fp_greater(fabs(a(i,j)-a(j,i)),threshold);
                }
            }
            
            //
            // test for difference between A and B (subsequent matrix)
            //
            unset2d(b);
            spdmatrixrndcond(n, cond, b);
            if( n>=2 )
            {
                for(i = 0; i <= n-1; i++)
                {
                    for(j = 0; j <= n-1; j++)
                    {
                        spderr = spderr||ap::fp_eq(a(i,j),b(i,j));
                    }
                }
            }
        }
        
        //
        // HPD matrices
        //
        for(pass = 1; pass <= passcount; pass++)
        {
            
            //
            // Generate A
            //
            unset2dc(ca);
            cond = exp(log(double(1000))*ap::randomreal());
            hpdmatrixrndcond(n, cond, ca);
            
            //
            // test HPD
            //
            hpderr = hpderr||!ishpd(ca, n);
            
            //
            // test that A is Hermitian
            //
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    hpderr = hpderr||ap::fp_greater(ap::abscomplex(ca(i,j)-ap::conj(ca(j,i))),threshold);
                }
            }
            
            //
            // test for difference between A and B (subsequent matrix)
            //
            unset2dc(cb);
            hpdmatrixrndcond(n, cond, cb);
            if( n>=2 )
            {
                for(i = 0; i <= n-1; i++)
                {
                    for(j = 0; j <= n-1; j++)
                    {
                        hpderr = hpderr||ca(i,j)==cb(i,j);
                    }
                }
            }
        }
        
        //
        // Symmetric matrices
        //
        for(pass = 1; pass <= passcount; pass++)
        {
            
            //
            // test condition number
            //
            unset2d(a);
            cond = exp(log(double(1000))*ap::randomreal());
            smatrixrndcond(n, cond, a);
            serr = serr||ap::fp_greater(svdcond(a, n)/cond-1,threshold);
            
            //
            // test for difference between A and B
            //
            unset2d(b);
            smatrixrndcond(n, cond, b);
            if( n>=2 )
            {
                for(i = 0; i <= n-1; i++)
                {
                    for(j = 0; j <= n-1; j++)
                    {
                        serr = serr||ap::fp_eq(a(i,j),b(i,j));
                    }
                }
            }
        }
        
        //
        // Hermitian matrices
        //
        for(pass = 1; pass <= passcount; pass++)
        {
            
            //
            // Generate A
            //
            unset2dc(ca);
            cond = exp(log(double(1000))*ap::randomreal());
            hmatrixrndcond(n, cond, ca);
            
            //
            // test that A is Hermitian
            //
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    herr = herr||ap::fp_greater(ap::abscomplex(ca(i,j)-ap::conj(ca(j,i))),threshold);
                }
            }
            
            //
            // test for difference between A and B (subsequent matrix)
            //
            unset2dc(cb);
            hmatrixrndcond(n, cond, cb);
            if( n>=2 )
            {
                for(i = 0; i <= n-1; i++)
                {
                    for(j = 0; j <= n-1; j++)
                    {
                        herr = herr||ca(i,j)==cb(i,j);
                    }
                }
            }
        }
    }
    
    //
    // report
    //
    waserrors = rerr||cerr||serr||spderr||herr||hpderr;
    if( !silent )
    {
        printf("TESTING MATRIX GENERATOR\n");
        printf("REAL TEST:                               ");
        if( !rerr )
        {
            printf("OK\n");
        }
        else
        {
            printf("FAILED\n");
        }
        printf("COMPLEX TEST:                            ");
        if( !cerr )
        {
            printf("OK\n");
        }
        else
        {
            printf("FAILED\n");
        }
        printf("SYMMETRIC TEST:                          ");
        if( !serr )
        {
            printf("OK\n");
        }
        else
        {
            printf("FAILED\n");
        }
        printf("HERMITIAN TEST:                          ");
        if( !herr )
        {
            printf("OK\n");
        }
        else
        {
            printf("FAILED\n");
        }
        printf("SPD TEST:                                ");
        if( !spderr )
        {
            printf("OK\n");
        }
        else
        {
            printf("FAILED\n");
        }
        printf("HPD TEST:                                ");
        if( !hpderr )
        {
            printf("OK\n");
        }
        else
        {
            printf("FAILED\n");
        }
        if( waserrors )
        {
            printf("TEST FAILED\n");
        }
        else
        {
            printf("TEST PASSED\n");
        }
        printf("\n\n");
    }
    result = !waserrors;
    return result;
}
Ejemplo n.º 2
0
/*************************************************************************
Returns True for successful test, False - for failed test
*************************************************************************/
static bool testspdmatrixrcond(int maxn, int passcount)
{
    bool result;
    ap::real_2d_array a;
    ap::real_2d_array cha;
    ap::integer_1d_array p;
    int n;
    int i;
    int j;
    int pass;
    bool err50;
    bool err90;
    bool errspec;
    bool errless;
    bool isupper;
    double erc1;
    double ercinf;
    ap::real_1d_array q50;
    ap::real_1d_array q90;
    double v;

    err50 = false;
    err90 = false;
    errless = false;
    errspec = false;
    q50.setlength(2);
    q90.setlength(2);
    for(n = 1; n <= maxn; n++)
    {
        isupper = ap::fp_greater(ap::randomreal(),0.5);
        
        //
        // general test
        //
        a.setlength(n, n);
        for(i = 0; i <= 1; i++)
        {
            q50(i) = 0;
            q90(i) = 0;
        }
        for(pass = 1; pass <= passcount; pass++)
        {
            spdmatrixrndcond(n, exp(ap::randomreal()*log(double(1000))), a);
            rmatrixrefrcond(a, n, erc1, ercinf);
            rmatrixdrophalf(a, n, isupper);
            rmatrixmakeacopy(a, n, n, cha);
            spdmatrixcholesky(cha, n, isupper);
            
            //
            // normal
            //
            v = 1/spdmatrixrcond(a, n, isupper);
            if( ap::fp_greater_eq(v,threshold50*erc1) )
            {
                q50(0) = q50(0)+double(1)/double(passcount);
            }
            if( ap::fp_greater_eq(v,threshold90*erc1) )
            {
                q90(0) = q90(0)+double(1)/double(passcount);
            }
            errless = errless||ap::fp_greater(v,erc1*1.001);
            
            //
            // Cholesky
            //
            v = 1/spdmatrixcholeskyrcond(cha, n, isupper);
            if( ap::fp_greater_eq(v,threshold50*erc1) )
            {
                q50(1) = q50(1)+double(1)/double(passcount);
            }
            if( ap::fp_greater_eq(v,threshold90*erc1) )
            {
                q90(1) = q90(1)+double(1)/double(passcount);
            }
            errless = errless||ap::fp_greater(v,erc1*1.001);
        }
        for(i = 0; i <= 1; i++)
        {
            err50 = err50||ap::fp_less(q50(i),0.50);
            err90 = err90||ap::fp_less(q90(i),0.90);
        }
        
        //
        // degenerate matrix test
        //
        if( n>=3 )
        {
            a.setlength(n, n);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    a(i,j) = 0.0;
                }
            }
            a(0,0) = 1;
            a(n-1,n-1) = 1;
            errspec = errspec||ap::fp_neq(spdmatrixrcond(a, n, isupper),-1);
            errspec = errspec||ap::fp_neq(spdmatrixcholeskyrcond(a, n, isupper),0);
        }
        
        //
        // near-degenerate matrix test
        //
        if( n>=2 )
        {
            a.setlength(n, n);
            for(i = 0; i <= n-1; i++)
            {
                for(j = 0; j <= n-1; j++)
                {
                    a(i,j) = 0.0;
                }
            }
            for(i = 0; i <= n-1; i++)
            {
                a(i,i) = 1;
            }
            i = ap::randominteger(n);
            a(i,i) = 0.1*ap::maxrealnumber;
            errspec = errspec||ap::fp_neq(spdmatrixrcond(a, n, isupper),0);
            errspec = errspec||ap::fp_neq(spdmatrixcholeskyrcond(a, n, isupper),0);
        }
    }
    
    //
    // report
    //
    result = !(err50||err90||errless||errspec);
    return result;
}