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; }
/************************************************************************* Returns True for successful test, False - for failed test *************************************************************************/ static bool testrmatrixrcond(int maxn, int passcount) { bool result; ap::real_2d_array a; ap::real_2d_array lua; ap::integer_1d_array p; int n; int i; int j; int pass; bool err50; bool err90; bool errspec; bool errless; 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.setbounds(0, 3); q90.setbounds(0, 3); for(n = 1; n <= maxn; n++) { // // special test for zero matrix // rmatrixgenzero(a, n); rmatrixmakeacopy(a, n, n, lua); rmatrixlu(lua, n, n, p); errspec = errspec||ap::fp_neq(rmatrixrcond1(a, n),0); errspec = errspec||ap::fp_neq(rmatrixrcondinf(a, n),0); errspec = errspec||ap::fp_neq(rmatrixlurcond1(lua, n),0); errspec = errspec||ap::fp_neq(rmatrixlurcondinf(lua, n),0); // // general test // a.setbounds(0, n-1, 0, n-1); for(i = 0; i <= 3; i++) { q50(i) = 0; q90(i) = 0; } for(pass = 1; pass <= passcount; pass++) { rmatrixrndcond(n, exp(ap::randomreal()*log(double(1000))), a); rmatrixmakeacopy(a, n, n, lua); rmatrixlu(lua, n, n, p); rmatrixrefrcond(a, n, erc1, ercinf); // // 1-norm, normal // v = 1/rmatrixrcond1(a, n); 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); // // 1-norm, LU // v = 1/rmatrixlurcond1(lua, n); 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); // // Inf-norm, normal // v = 1/rmatrixrcondinf(a, n); if( ap::fp_greater_eq(v,threshold50*ercinf) ) { q50(2) = q50(2)+double(1)/double(passcount); } if( ap::fp_greater_eq(v,threshold90*ercinf) ) { q90(2) = q90(2)+double(1)/double(passcount); } errless = errless||ap::fp_greater(v,ercinf*1.001); // // Inf-norm, LU // v = 1/rmatrixlurcondinf(lua, n); if( ap::fp_greater_eq(v,threshold50*ercinf) ) { q50(3) = q50(3)+double(1)/double(passcount); } if( ap::fp_greater_eq(v,threshold90*ercinf) ) { q90(3) = q90(3)+double(1)/double(passcount); } errless = errless||ap::fp_greater(v,ercinf*1.001); } for(i = 0; i <= 3; 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(rmatrixrcond1(a, n),0); errspec = errspec||ap::fp_neq(rmatrixrcondinf(a, n),0); errspec = errspec||ap::fp_neq(rmatrixlurcond1(a, n),0); errspec = errspec||ap::fp_neq(rmatrixlurcondinf(a, n),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(rmatrixrcond1(a, n),0); errspec = errspec||ap::fp_neq(rmatrixrcondinf(a, n),0); errspec = errspec||ap::fp_neq(rmatrixlurcond1(a, n),0); errspec = errspec||ap::fp_neq(rmatrixlurcondinf(a, n),0); } } // // report // result = !(err50||err90||errless||errspec); return result; }