public densesolverlsreport(densesolver.densesolverlsreport obj) { _innerobj = obj; }
/************************************************************************* HPD test *************************************************************************/ private static void testhpdsolver(int maxn, int maxm, int passcount, double threshold, ref bool hpderrors, ref bool rfserrors) { complex[,] a = new complex[0,0]; complex[,] cha = new complex[0,0]; complex[,] atmp = new complex[0,0]; int[] p = new int[0]; complex[,] xe = new complex[0,0]; complex[,] b = new complex[0,0]; complex[] bv = new complex[0]; int i = 0; int j = 0; int k = 0; int n = 0; int m = 0; int pass = 0; int taskkind = 0; complex v = 0; bool isupper = new bool(); int info = 0; densesolver.densesolverreport rep = new densesolver.densesolverreport(); densesolver.densesolverlsreport repls = new densesolver.densesolverlsreport(); complex[,] x = new complex[0,0]; complex[] xv = new complex[0]; complex[] y = new complex[0]; complex[] tx = new complex[0]; int i_ = 0; // // General square matrices: // * test general solvers // * test least squares solver // for(pass=1; pass<=passcount; pass++) { for(n=1; n<=maxn; n++) { for(m=1; m<=maxm; m++) { // // ******************************************************** // WELL CONDITIONED TASKS // ability to find correct solution is tested // ******************************************************** // // 1. generate random well conditioned matrix A. // 2. generate random solution vector xe // 3. generate right part b=A*xe // 4. test different methods on original A // isupper = (double)(math.randomreal())>(double)(0.5); matgen.hpdmatrixrndcond(n, 1000, ref a); cmatrixmakeacopy(a, n, n, ref cha); if( !trfac.hpdmatrixcholesky(ref cha, n, isupper) ) { hpderrors = true; return; } xe = new complex[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { xe[i,j].x = 2*math.randomreal()-1; xe[i,j].y = 2*math.randomreal()-1; } } b = new complex[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { v = 0.0; for(i_=0; i_<=n-1;i_++) { v += a[i,i_]*xe[i_,j]; } b[i,j] = v; } } cmatrixdrophalf(ref a, n, isupper); cmatrixdrophalf(ref cha, n, isupper); // // Test solvers // info = 0; unsetrep(rep); cunset2d(ref x); densesolver.hpdmatrixsolvem(a, n, isupper, b, m, ref info, rep, ref x); hpderrors = hpderrors | !cmatrixchecksolutionm(xe, n, m, threshold, info, rep, x); info = 0; unsetrep(rep); cunset1d(ref xv); bv = new complex[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.hpdmatrixsolve(a, n, isupper, bv, ref info, rep, ref xv); hpderrors = hpderrors | !cmatrixchecksolution(xe, n, threshold, info, rep, xv); info = 0; unsetrep(rep); cunset2d(ref x); densesolver.hpdmatrixcholeskysolvem(cha, n, isupper, b, m, ref info, rep, ref x); hpderrors = hpderrors | !cmatrixchecksolutionm(xe, n, m, threshold, info, rep, x); info = 0; unsetrep(rep); cunset1d(ref xv); bv = new complex[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.hpdmatrixcholeskysolve(cha, n, isupper, bv, ref info, rep, ref xv); hpderrors = hpderrors | !cmatrixchecksolution(xe, n, threshold, info, rep, xv); // // ******************************************************** // EXACTLY SINGULAR MATRICES // ability to detect singularity is tested // ******************************************************** // // 1. generate different types of singular matrices: // * zero // * with zero columns // * with zero rows // * with equal rows/columns // 2. generate random solution vector xe // 3. generate right part b=A*xe // 4. test different methods // for(taskkind=0; taskkind<=3; taskkind++) { cunset2d(ref a); if( taskkind==0 ) { // // all zeros // a = new complex[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j] = 0; } } } if( taskkind==1 ) { // // there is zero column // a = new complex[n, n]; for(i=0; i<=n-1; i++) { for(j=i; j<=n-1; j++) { a[i,j].x = 2*math.randomreal()-1; a[i,j].y = 2*math.randomreal()-1; if( i==j ) { a[i,j].y = 0; } a[j,i] = a[i,j]; } } k = math.randominteger(n); for(i_=0; i_<=n-1;i_++) { a[i_,k] = 0*a[i_,k]; } for(i_=0; i_<=n-1;i_++) { a[k,i_] = 0*a[k,i_]; } } if( taskkind==2 ) { // // there is zero row // a = new complex[n, n]; for(i=0; i<=n-1; i++) { for(j=i; j<=n-1; j++) { a[i,j].x = 2*math.randomreal()-1; a[i,j].y = 2*math.randomreal()-1; if( i==j ) { a[i,j].y = 0; } a[j,i] = a[i,j]; } } k = math.randominteger(n); for(i_=0; i_<=n-1;i_++) { a[k,i_] = 0*a[k,i_]; } for(i_=0; i_<=n-1;i_++) { a[i_,k] = 0*a[i_,k]; } } if( taskkind==3 ) { // // equal columns/rows // if( n<2 ) { continue; } a = new complex[n, n]; for(i=0; i<=n-1; i++) { for(j=i; j<=n-1; j++) { a[i,j].x = 2*math.randomreal()-1; a[i,j].y = 2*math.randomreal()-1; if( i==j ) { a[i,j].y = 0; } a[j,i] = a[i,j]; } } k = 1+math.randominteger(n-1); for(i_=0; i_<=n-1;i_++) { a[i_,0] = a[i_,k]; } for(i_=0; i_<=n-1;i_++) { a[0,i_] = a[k,i_]; } } xe = new complex[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { xe[i,j] = 2*math.randomreal()-1; } } b = new complex[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { v = 0.0; for(i_=0; i_<=n-1;i_++) { v += a[i,i_]*xe[i_,j]; } b[i,j] = v; } } cmatrixmakeacopy(a, n, n, ref cha); cmatrixdrophalf(ref a, n, isupper); cmatrixdrophalf(ref cha, n, isupper); // // Test SPDMatrixSolveM() // info = 0; unsetrep(rep); cunset2d(ref x); densesolver.hpdmatrixsolvem(a, n, isupper, b, m, ref info, rep, ref x); hpderrors = hpderrors | !cmatrixchecksingularm(n, m, info, rep, x); // // Test SPDMatrixSolve() // info = 0; unsetrep(rep); cunset2d(ref x); bv = new complex[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.hpdmatrixsolve(a, n, isupper, bv, ref info, rep, ref xv); hpderrors = hpderrors | !cmatrixchecksingular(n, info, rep, xv); // // 'equal columns/rows' are degenerate, but // Cholesky matrix with equal columns/rows IS NOT degenerate, // so it is not used for testing purposes. // if( taskkind!=3 ) { // // Test SPDMatrixLUSolveM() // info = 0; unsetrep(rep); cunset2d(ref x); densesolver.hpdmatrixcholeskysolvem(cha, n, isupper, b, m, ref info, rep, ref x); hpderrors = hpderrors | !cmatrixchecksingularm(n, m, info, rep, x); // // Test SPDMatrixLUSolve() // info = 0; unsetrep(rep); cunset2d(ref x); bv = new complex[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.hpdmatrixcholeskysolve(cha, n, isupper, bv, ref info, rep, ref xv); hpderrors = hpderrors | !cmatrixchecksingular(n, info, rep, xv); } } } } } }
public densesolverlsreport() { _innerobj = new densesolver.densesolverlsreport(); }
/************************************************************************* Real test *************************************************************************/ private static void testcsolver(int maxn, int maxm, int passcount, double threshold, ref bool cerrors, ref bool rfserrors) { complex[,] a = new complex[0,0]; complex[,] lua = new complex[0,0]; complex[,] atmp = new complex[0,0]; int[] p = new int[0]; complex[,] xe = new complex[0,0]; complex[,] b = new complex[0,0]; complex[] bv = new complex[0]; int i = 0; int j = 0; int k = 0; int n = 0; int m = 0; int pass = 0; int taskkind = 0; double verr = 0; complex v = 0; int info = 0; densesolver.densesolverreport rep = new densesolver.densesolverreport(); densesolver.densesolverlsreport repls = new densesolver.densesolverlsreport(); complex[,] x = new complex[0,0]; complex[] xv = new complex[0]; complex[] y = new complex[0]; double[] tx = new double[0]; int i_ = 0; // // General square matrices: // * test general solvers // * test least squares solver // for(pass=1; pass<=passcount; pass++) { for(n=1; n<=maxn; n++) { for(m=1; m<=maxm; m++) { // // ******************************************************** // WELL CONDITIONED TASKS // ability to find correct solution is tested // ******************************************************** // // 1. generate random well conditioned matrix A. // 2. generate random solution vector xe // 3. generate right part b=A*xe // 4. test different methods on original A // matgen.cmatrixrndcond(n, 1000, ref a); cmatrixmakeacopy(a, n, n, ref lua); trfac.cmatrixlu(ref lua, n, n, ref p); xe = new complex[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { xe[i,j].x = 2*math.randomreal()-1; xe[i,j].y = 2*math.randomreal()-1; } } b = new complex[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { v = 0.0; for(i_=0; i_<=n-1;i_++) { v += a[i,i_]*xe[i_,j]; } b[i,j] = v; } } // // Test solvers // info = 0; unsetrep(rep); cunset2d(ref x); densesolver.cmatrixsolvem(a, n, b, m, (double)(math.randomreal())>(double)(0.5), ref info, rep, ref x); cerrors = cerrors | !cmatrixchecksolutionm(xe, n, m, threshold, info, rep, x); info = 0; unsetrep(rep); cunset1d(ref xv); bv = new complex[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.cmatrixsolve(a, n, bv, ref info, rep, ref xv); cerrors = cerrors | !cmatrixchecksolution(xe, n, threshold, info, rep, xv); info = 0; unsetrep(rep); cunset2d(ref x); densesolver.cmatrixlusolvem(lua, p, n, b, m, ref info, rep, ref x); cerrors = cerrors | !cmatrixchecksolutionm(xe, n, m, threshold, info, rep, x); info = 0; unsetrep(rep); cunset1d(ref xv); bv = new complex[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.cmatrixlusolve(lua, p, n, bv, ref info, rep, ref xv); cerrors = cerrors | !cmatrixchecksolution(xe, n, threshold, info, rep, xv); info = 0; unsetrep(rep); cunset2d(ref x); densesolver.cmatrixmixedsolvem(a, lua, p, n, b, m, ref info, rep, ref x); cerrors = cerrors | !cmatrixchecksolutionm(xe, n, m, threshold, info, rep, x); info = 0; unsetrep(rep); cunset1d(ref xv); bv = new complex[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.cmatrixmixedsolve(a, lua, p, n, bv, ref info, rep, ref xv); cerrors = cerrors | !cmatrixchecksolution(xe, n, threshold, info, rep, xv); // // ******************************************************** // EXACTLY SINGULAR MATRICES // ability to detect singularity is tested // ******************************************************** // // 1. generate different types of singular matrices: // * zero // * with zero columns // * with zero rows // * with equal rows/columns // 2. generate random solution vector xe // 3. generate right part b=A*xe // 4. test different methods // for(taskkind=0; taskkind<=4; taskkind++) { cunset2d(ref a); if( taskkind==0 ) { // // all zeros // a = new complex[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j] = 0; } } } if( taskkind==1 ) { // // there is zero column // a = new complex[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j].x = 2*math.randomreal()-1; a[i,j].y = 2*math.randomreal()-1; } } k = math.randominteger(n); for(i_=0; i_<=n-1;i_++) { a[i_,k] = 0*a[i_,k]; } } if( taskkind==2 ) { // // there is zero row // a = new complex[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j].x = 2*math.randomreal()-1; a[i,j].y = 2*math.randomreal()-1; } } k = math.randominteger(n); for(i_=0; i_<=n-1;i_++) { a[k,i_] = 0*a[k,i_]; } } if( taskkind==3 ) { // // equal columns // if( n<2 ) { continue; } a = new complex[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j].x = 2*math.randomreal()-1; a[i,j].y = 2*math.randomreal()-1; } } k = 1+math.randominteger(n-1); for(i_=0; i_<=n-1;i_++) { a[i_,0] = a[i_,k]; } } if( taskkind==4 ) { // // equal rows // if( n<2 ) { continue; } a = new complex[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j].x = 2*math.randomreal()-1; a[i,j].y = 2*math.randomreal()-1; } } k = 1+math.randominteger(n-1); for(i_=0; i_<=n-1;i_++) { a[0,i_] = a[k,i_]; } } xe = new complex[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { xe[i,j] = 2*math.randomreal()-1; } } b = new complex[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { v = 0.0; for(i_=0; i_<=n-1;i_++) { v += a[i,i_]*xe[i_,j]; } b[i,j] = v; } } cmatrixmakeacopy(a, n, n, ref lua); trfac.cmatrixlu(ref lua, n, n, ref p); // // Test CMatrixSolveM() // info = 0; unsetrep(rep); cunset2d(ref x); densesolver.cmatrixsolvem(a, n, b, m, (double)(math.randomreal())>(double)(0.5), ref info, rep, ref x); cerrors = cerrors | !cmatrixchecksingularm(n, m, info, rep, x); // // Test CMatrixSolve() // info = 0; unsetrep(rep); cunset2d(ref x); bv = new complex[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.cmatrixsolve(a, n, bv, ref info, rep, ref xv); cerrors = cerrors | !cmatrixchecksingular(n, info, rep, xv); // // Test CMatrixLUSolveM() // info = 0; unsetrep(rep); cunset2d(ref x); densesolver.cmatrixlusolvem(lua, p, n, b, m, ref info, rep, ref x); cerrors = cerrors | !cmatrixchecksingularm(n, m, info, rep, x); // // Test CMatrixLUSolve() // info = 0; unsetrep(rep); cunset2d(ref x); bv = new complex[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.cmatrixlusolve(lua, p, n, bv, ref info, rep, ref xv); cerrors = cerrors | !cmatrixchecksingular(n, info, rep, xv); // // Test CMatrixMixedSolveM() // info = 0; unsetrep(rep); cunset2d(ref x); densesolver.cmatrixmixedsolvem(a, lua, p, n, b, m, ref info, rep, ref x); cerrors = cerrors | !cmatrixchecksingularm(n, m, info, rep, x); // // Test CMatrixMixedSolve() // info = 0; unsetrep(rep); cunset2d(ref x); bv = new complex[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.cmatrixmixedsolve(a, lua, p, n, bv, ref info, rep, ref xv); cerrors = cerrors | !cmatrixchecksingular(n, info, rep, xv); } } } } // // test iterative improvement // for(pass=1; pass<=passcount; pass++) { // // Test iterative improvement matrices // // A matrix/right part are constructed such that both matrix // and solution components magnitudes are within (-1,+1). // Such matrix/right part have nice properties - system can // be solved using iterative improvement with |A*x-b| about // several ulps of max(1,|b|). // n = 100; a = new complex[n, n]; b = new complex[n, 1]; bv = new complex[n]; tx = new double[2*n]; xv = new complex[n]; y = new complex[n]; for(i=0; i<=n-1; i++) { xv[i].x = 2*math.randomreal()-1; xv[i].y = 2*math.randomreal()-1; } for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j].x = 2*math.randomreal()-1; a[i,j].y = 2*math.randomreal()-1; } for(i_=0; i_<=n-1;i_++) { y[i_] = a[i,i_]; } xblas.xcdot(y, xv, n, ref tx, ref v, ref verr); bv[i] = v; } for(i_=0; i_<=n-1;i_++) { b[i_,0] = bv[i_]; } // // Test CMatrixSolveM() // cunset2d(ref x); densesolver.cmatrixsolvem(a, n, b, 1, true, ref info, rep, ref x); if( info<=0 ) { rfserrors = true; } else { xv = new complex[n]; for(i_=0; i_<=n-1;i_++) { xv[i_] = x[i_,0]; } for(i=0; i<=n-1; i++) { for(i_=0; i_<=n-1;i_++) { y[i_] = a[i,i_]; } xblas.xcdot(y, xv, n, ref tx, ref v, ref verr); rfserrors = rfserrors | (double)(math.abscomplex(v-b[i,0]))>(double)(8*math.machineepsilon*Math.Max(1, math.abscomplex(b[i,0]))); } } // // Test CMatrixSolve() // cunset1d(ref xv); densesolver.cmatrixsolve(a, n, bv, ref info, rep, ref xv); if( info<=0 ) { rfserrors = true; } else { for(i=0; i<=n-1; i++) { for(i_=0; i_<=n-1;i_++) { y[i_] = a[i,i_]; } xblas.xcdot(y, xv, n, ref tx, ref v, ref verr); rfserrors = rfserrors | (double)(math.abscomplex(v-bv[i]))>(double)(8*math.machineepsilon*Math.Max(1, math.abscomplex(bv[i]))); } } // // TODO: Test LS-solver on the same matrix // } }
/************************************************************************* Real test *************************************************************************/ private static void testrsolver(int maxn, int maxm, int passcount, double threshold, ref bool rerrors, ref bool rfserrors) { double[,] a = new double[0,0]; double[,] lua = new double[0,0]; double[,] atmp = new double[0,0]; int[] p = new int[0]; double[,] xe = new double[0,0]; double[,] b = new double[0,0]; double[] bv = new double[0]; int i = 0; int j = 0; int k = 0; int n = 0; int m = 0; int pass = 0; int taskkind = 0; double v = 0; double verr = 0; int info = 0; densesolver.densesolverreport rep = new densesolver.densesolverreport(); densesolver.densesolverlsreport repls = new densesolver.densesolverlsreport(); double[,] x = new double[0,0]; double[] xv = new double[0]; double[] y = new double[0]; double[] tx = new double[0]; int i_ = 0; int i1_ = 0; // // General square matrices: // * test general solvers // * test least squares solver // for(pass=1; pass<=passcount; pass++) { for(n=1; n<=maxn; n++) { for(m=1; m<=maxm; m++) { // // ******************************************************** // WELL CONDITIONED TASKS // ability to find correct solution is tested // ******************************************************** // // 1. generate random well conditioned matrix A. // 2. generate random solution vector xe // 3. generate right part b=A*xe // 4. test different methods on original A // matgen.rmatrixrndcond(n, 1000, ref a); rmatrixmakeacopy(a, n, n, ref lua); trfac.rmatrixlu(ref lua, n, n, ref p); xe = new double[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { xe[i,j] = 2*math.randomreal()-1; } } b = new double[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { v = 0.0; for(i_=0; i_<=n-1;i_++) { v += a[i,i_]*xe[i_,j]; } b[i,j] = v; } } // // Test solvers // info = 0; unsetrep(rep); unset2d(ref x); densesolver.rmatrixsolvem(a, n, b, m, (double)(math.randomreal())>(double)(0.5), ref info, rep, ref x); rerrors = rerrors | !rmatrixchecksolutionm(xe, n, m, threshold, info, rep, x); info = 0; unsetrep(rep); unset1d(ref xv); bv = new double[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.rmatrixsolve(a, n, bv, ref info, rep, ref xv); rerrors = rerrors | !rmatrixchecksolution(xe, n, threshold, info, rep, xv); info = 0; unsetrep(rep); unset2d(ref x); densesolver.rmatrixlusolvem(lua, p, n, b, m, ref info, rep, ref x); rerrors = rerrors | !rmatrixchecksolutionm(xe, n, m, threshold, info, rep, x); info = 0; unsetrep(rep); unset1d(ref xv); bv = new double[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.rmatrixlusolve(lua, p, n, bv, ref info, rep, ref xv); rerrors = rerrors | !rmatrixchecksolution(xe, n, threshold, info, rep, xv); info = 0; unsetrep(rep); unset2d(ref x); densesolver.rmatrixmixedsolvem(a, lua, p, n, b, m, ref info, rep, ref x); rerrors = rerrors | !rmatrixchecksolutionm(xe, n, m, threshold, info, rep, x); info = 0; unsetrep(rep); unset1d(ref xv); bv = new double[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.rmatrixmixedsolve(a, lua, p, n, bv, ref info, rep, ref xv); rerrors = rerrors | !rmatrixchecksolution(xe, n, threshold, info, rep, xv); // // Test DenseSolverRLS(): // * test on original system A*x = b // * test on overdetermined system with the same solution: (A' A')'*x = (b' b')' // * test on underdetermined system with the same solution: (A 0 0 0 ) * z = b // info = 0; unsetlsrep(repls); unset1d(ref xv); bv = new double[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.rmatrixsolvels(a, n, n, bv, 0.0, ref info, repls, ref xv); if( info<=0 ) { rerrors = true; } else { rerrors = (rerrors | (double)(repls.r2)<(double)(100*math.machineepsilon)) | (double)(repls.r2)>(double)(1+1000*math.machineepsilon); rerrors = (rerrors | repls.n!=n) | repls.k!=0; for(i=0; i<=n-1; i++) { rerrors = rerrors | (double)(Math.Abs(xe[i,0]-xv[i]))>(double)(threshold); } } info = 0; unsetlsrep(repls); unset1d(ref xv); bv = new double[2*n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } i1_ = (0) - (n); for(i_=n; i_<=2*n-1;i_++) { bv[i_] = b[i_+i1_,0]; } atmp = new double[2*n, n]; blas.copymatrix(a, 0, n-1, 0, n-1, ref atmp, 0, n-1, 0, n-1); blas.copymatrix(a, 0, n-1, 0, n-1, ref atmp, n, 2*n-1, 0, n-1); densesolver.rmatrixsolvels(atmp, 2*n, n, bv, 0.0, ref info, repls, ref xv); if( info<=0 ) { rerrors = true; } else { rerrors = (rerrors | (double)(repls.r2)<(double)(100*math.machineepsilon)) | (double)(repls.r2)>(double)(1+1000*math.machineepsilon); rerrors = (rerrors | repls.n!=n) | repls.k!=0; for(i=0; i<=n-1; i++) { rerrors = rerrors | (double)(Math.Abs(xe[i,0]-xv[i]))>(double)(threshold); } } info = 0; unsetlsrep(repls); unset1d(ref xv); bv = new double[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } atmp = new double[n, 2*n]; blas.copymatrix(a, 0, n-1, 0, n-1, ref atmp, 0, n-1, 0, n-1); for(i=0; i<=n-1; i++) { for(j=n; j<=2*n-1; j++) { atmp[i,j] = 0; } } densesolver.rmatrixsolvels(atmp, n, 2*n, bv, 0.0, ref info, repls, ref xv); if( info<=0 ) { rerrors = true; } else { rerrors = rerrors | (double)(repls.r2)!=(double)(0); rerrors = (rerrors | repls.n!=2*n) | repls.k!=n; for(i=0; i<=n-1; i++) { rerrors = rerrors | (double)(Math.Abs(xe[i,0]-xv[i]))>(double)(threshold); } for(i=n; i<=2*n-1; i++) { rerrors = rerrors | (double)(Math.Abs(xv[i]))>(double)(threshold); } } // // ******************************************************** // EXACTLY SINGULAR MATRICES // ability to detect singularity is tested // ******************************************************** // // 1. generate different types of singular matrices: // * zero // * with zero columns // * with zero rows // * with equal rows/columns // 2. generate random solution vector xe // 3. generate right part b=A*xe // 4. test different methods // for(taskkind=0; taskkind<=4; taskkind++) { unset2d(ref a); if( taskkind==0 ) { // // all zeros // a = new double[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j] = 0; } } } if( taskkind==1 ) { // // there is zero column // a = new double[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j] = 2*math.randomreal()-1; } } k = math.randominteger(n); for(i_=0; i_<=n-1;i_++) { a[i_,k] = 0*a[i_,k]; } } if( taskkind==2 ) { // // there is zero row // a = new double[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j] = 2*math.randomreal()-1; } } k = math.randominteger(n); for(i_=0; i_<=n-1;i_++) { a[k,i_] = 0*a[k,i_]; } } if( taskkind==3 ) { // // equal columns // if( n<2 ) { continue; } a = new double[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j] = 2*math.randomreal()-1; } } k = 1+math.randominteger(n-1); for(i_=0; i_<=n-1;i_++) { a[i_,0] = a[i_,k]; } } if( taskkind==4 ) { // // equal rows // if( n<2 ) { continue; } a = new double[n, n]; for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j] = 2*math.randomreal()-1; } } k = 1+math.randominteger(n-1); for(i_=0; i_<=n-1;i_++) { a[0,i_] = a[k,i_]; } } xe = new double[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { xe[i,j] = 2*math.randomreal()-1; } } b = new double[n, m]; for(i=0; i<=n-1; i++) { for(j=0; j<=m-1; j++) { v = 0.0; for(i_=0; i_<=n-1;i_++) { v += a[i,i_]*xe[i_,j]; } b[i,j] = v; } } rmatrixmakeacopy(a, n, n, ref lua); trfac.rmatrixlu(ref lua, n, n, ref p); // // Test RMatrixSolveM() // info = 0; unsetrep(rep); unset2d(ref x); densesolver.rmatrixsolvem(a, n, b, m, (double)(math.randomreal())>(double)(0.5), ref info, rep, ref x); rerrors = rerrors | !rmatrixchecksingularm(n, m, info, rep, x); // // Test RMatrixSolve() // info = 0; unsetrep(rep); unset2d(ref x); bv = new double[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.rmatrixsolve(a, n, bv, ref info, rep, ref xv); rerrors = rerrors | !rmatrixchecksingular(n, info, rep, xv); // // Test RMatrixLUSolveM() // info = 0; unsetrep(rep); unset2d(ref x); densesolver.rmatrixlusolvem(lua, p, n, b, m, ref info, rep, ref x); rerrors = rerrors | !rmatrixchecksingularm(n, m, info, rep, x); // // Test RMatrixLUSolve() // info = 0; unsetrep(rep); unset2d(ref x); bv = new double[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.rmatrixlusolve(lua, p, n, bv, ref info, rep, ref xv); rerrors = rerrors | !rmatrixchecksingular(n, info, rep, xv); // // Test RMatrixMixedSolveM() // info = 0; unsetrep(rep); unset2d(ref x); densesolver.rmatrixmixedsolvem(a, lua, p, n, b, m, ref info, rep, ref x); rerrors = rerrors | !rmatrixchecksingularm(n, m, info, rep, x); // // Test RMatrixMixedSolve() // info = 0; unsetrep(rep); unset2d(ref x); bv = new double[n]; for(i_=0; i_<=n-1;i_++) { bv[i_] = b[i_,0]; } densesolver.rmatrixmixedsolve(a, lua, p, n, bv, ref info, rep, ref xv); rerrors = rerrors | !rmatrixchecksingular(n, info, rep, xv); } } } } // // test iterative improvement // for(pass=1; pass<=passcount; pass++) { // // Test iterative improvement matrices // // A matrix/right part are constructed such that both matrix // and solution components are within (-1,+1). Such matrix/right part // have nice properties - system can be solved using iterative // improvement with |A*x-b| about several ulps of max(1,|b|). // n = 100; a = new double[n, n]; b = new double[n, 1]; bv = new double[n]; tx = new double[n]; xv = new double[n]; y = new double[n]; for(i=0; i<=n-1; i++) { xv[i] = 2*math.randomreal()-1; } for(i=0; i<=n-1; i++) { for(j=0; j<=n-1; j++) { a[i,j] = 2*math.randomreal()-1; } for(i_=0; i_<=n-1;i_++) { y[i_] = a[i,i_]; } xblas.xdot(y, xv, n, ref tx, ref v, ref verr); bv[i] = v; } for(i_=0; i_<=n-1;i_++) { b[i_,0] = bv[i_]; } // // Test RMatrixSolveM() // unset2d(ref x); densesolver.rmatrixsolvem(a, n, b, 1, true, ref info, rep, ref x); if( info<=0 ) { rfserrors = true; } else { xv = new double[n]; for(i_=0; i_<=n-1;i_++) { xv[i_] = x[i_,0]; } for(i=0; i<=n-1; i++) { for(i_=0; i_<=n-1;i_++) { y[i_] = a[i,i_]; } xblas.xdot(y, xv, n, ref tx, ref v, ref verr); rfserrors = rfserrors | (double)(Math.Abs(v-b[i,0]))>(double)(8*math.machineepsilon*Math.Max(1, Math.Abs(b[i,0]))); } } // // Test RMatrixSolve() // unset1d(ref xv); densesolver.rmatrixsolve(a, n, bv, ref info, rep, ref xv); if( info<=0 ) { rfserrors = true; } else { for(i=0; i<=n-1; i++) { for(i_=0; i_<=n-1;i_++) { y[i_] = a[i,i_]; } xblas.xdot(y, xv, n, ref tx, ref v, ref verr); rfserrors = rfserrors | (double)(Math.Abs(v-bv[i]))>(double)(8*math.machineepsilon*Math.Max(1, Math.Abs(bv[i]))); } } // // Test LS-solver on the same matrix // densesolver.rmatrixsolvels(a, n, n, bv, 0.0, ref info, repls, ref xv); if( info<=0 ) { rfserrors = true; } else { for(i=0; i<=n-1; i++) { for(i_=0; i_<=n-1;i_++) { y[i_] = a[i,i_]; } xblas.xdot(y, xv, n, ref tx, ref v, ref verr); rfserrors = rfserrors | (double)(Math.Abs(v-bv[i]))>(double)(8*math.machineepsilon*Math.Max(1, Math.Abs(bv[i]))); } } } }
/************************************************************************* Linear least squares solver for small tasks. Works faster than standard ALGLIB solver in non-degenerate cases (due to absense of internal allocations and optimized row/colums). In degenerate cases it calls standard solver, which results in small performance penalty associated with preliminary steps. INPUT PARAMETERS: Y array[0..N-1] W array[0..N-1] FMatrix array[0..N-1,0..M], have additional column for temporary values Temp array[0..N] *************************************************************************/ private static void idwinternalsolver(ref double[] y, ref double[] w, ref double[,] fmatrix, ref double[] temp, int n, int m, ref int info, ref double[] x, ref double taskrcond) { int i = 0; int j = 0; double v = 0; double tau = 0; double[] b = new double[0]; densesolver.densesolverlsreport srep = new densesolver.densesolverlsreport(); int i_ = 0; int i1_ = 0; info = 0; // // set up info // info = 1; // // prepare matrix // for(i=0; i<=n-1; i++) { fmatrix[i,m] = y[i]; v = w[i]; for(i_=0; i_<=m;i_++) { fmatrix[i,i_] = v*fmatrix[i,i_]; } } // // use either fast algorithm or general algorithm // if( m<=n ) { // // QR decomposition // We assume that M<=N (we would have called LSFit() otherwise) // for(i=0; i<=m-1; i++) { if( i<n-1 ) { i1_ = (i) - (1); for(i_=1; i_<=n-i;i_++) { temp[i_] = fmatrix[i_+i1_,i]; } reflections.generatereflection(ref temp, n-i, ref tau); fmatrix[i,i] = temp[1]; temp[1] = 1; for(j=i+1; j<=m; j++) { i1_ = (1)-(i); v = 0.0; for(i_=i; i_<=n-1;i_++) { v += fmatrix[i_,j]*temp[i_+i1_]; } v = tau*v; i1_ = (1) - (i); for(i_=i; i_<=n-1;i_++) { fmatrix[i_,j] = fmatrix[i_,j] - v*temp[i_+i1_]; } } } } // // Check condition number // taskrcond = rcond.rmatrixtrrcondinf(fmatrix, m, true, false); // // use either fast algorithm for non-degenerate cases // or slow algorithm for degenerate cases // if( (double)(taskrcond)>(double)(10000*n*math.machineepsilon) ) { // // solve triangular system R*x = FMatrix[0:M-1,M] // using fast algorithm, then exit // x[m-1] = fmatrix[m-1,m]/fmatrix[m-1,m-1]; for(i=m-2; i>=0; i--) { v = 0.0; for(i_=i+1; i_<=m-1;i_++) { v += fmatrix[i,i_]*x[i_]; } x[i] = (fmatrix[i,m]-v)/fmatrix[i,i]; } } else { // // use more general algorithm // b = new double[m]; for(i=0; i<=m-1; i++) { for(j=0; j<=i-1; j++) { fmatrix[i,j] = 0.0; } b[i] = fmatrix[i,m]; } densesolver.rmatrixsolvels(fmatrix, m, m, b, 10000*math.machineepsilon, ref info, srep, ref x); } } else { // // use more general algorithm // b = new double[n]; for(i=0; i<=n-1; i++) { b[i] = fmatrix[i,m]; } densesolver.rmatrixsolvels(fmatrix, n, m, b, 10000*math.machineepsilon, ref info, srep, ref x); taskrcond = srep.r2; } }
/************************************************************************* * Linear least squares solver for small tasks. * * Works faster than standard ALGLIB solver in non-degenerate cases (due to * absense of internal allocations and optimized row/colums). In degenerate * cases it calls standard solver, which results in small performance penalty * associated with preliminary steps. * * INPUT PARAMETERS: * Y array[0..N-1] * W array[0..N-1] * FMatrix array[0..N-1,0..M], have additional column for temporary * values * Temp array[0..N] *************************************************************************/ private static void idwinternalsolver(ref double[] y, ref double[] w, ref double[,] fmatrix, ref double[] temp, int n, int m, ref int info, ref double[] x, ref double taskrcond) { int i = 0; int j = 0; double v = 0; double tau = 0; double[] b = new double[0]; densesolver.densesolverlsreport srep = new densesolver.densesolverlsreport(); int i_ = 0; int i1_ = 0; // // set up info // info = 1; // // prepare matrix // for (i = 0; i <= n - 1; i++) { fmatrix[i, m] = y[i]; v = w[i]; for (i_ = 0; i_ <= m; i_++) { fmatrix[i, i_] = v * fmatrix[i, i_]; } } // // use either fast algorithm or general algorithm // if (m <= n) { // // QR decomposition // We assume that M<=N (we would have called LSFit() otherwise) // for (i = 0; i <= m - 1; i++) { if (i < n - 1) { i1_ = (i) - (1); for (i_ = 1; i_ <= n - i; i_++) { temp[i_] = fmatrix[i_ + i1_, i]; } reflections.generatereflection(ref temp, n - i, ref tau); fmatrix[i, i] = temp[1]; temp[1] = 1; for (j = i + 1; j <= m; j++) { i1_ = (1) - (i); v = 0.0; for (i_ = i; i_ <= n - 1; i_++) { v += fmatrix[i_, j] * temp[i_ + i1_]; } v = tau * v; i1_ = (1) - (i); for (i_ = i; i_ <= n - 1; i_++) { fmatrix[i_, j] = fmatrix[i_, j] - v * temp[i_ + i1_]; } } } } // // Check condition number // taskrcond = rcond.rmatrixtrrcondinf(ref fmatrix, m, true, false); // // use either fast algorithm for non-degenerate cases // or slow algorithm for degenerate cases // if ((double)(taskrcond) > (double)(10000 * n * AP.Math.MachineEpsilon)) { // // solve triangular system R*x = FMatrix[0:M-1,M] // using fast algorithm, then exit // x[m - 1] = fmatrix[m - 1, m] / fmatrix[m - 1, m - 1]; for (i = m - 2; i >= 0; i--) { v = 0.0; for (i_ = i + 1; i_ <= m - 1; i_++) { v += fmatrix[i, i_] * x[i_]; } x[i] = (fmatrix[i, m] - v) / fmatrix[i, i]; } } else { // // use more general algorithm // b = new double[m]; for (i = 0; i <= m - 1; i++) { for (j = 0; j <= i - 1; j++) { fmatrix[i, j] = 0.0; } b[i] = fmatrix[i, m]; } densesolver.rmatrixsolvels(ref fmatrix, m, m, ref b, 10000 * AP.Math.MachineEpsilon, ref info, ref srep, ref x); } } else { // // use more general algorithm // b = new double[n]; for (i = 0; i <= n - 1; i++) { b[i] = fmatrix[i, m]; } densesolver.rmatrixsolvels(ref fmatrix, n, m, ref b, 10000 * AP.Math.MachineEpsilon, ref info, ref srep, ref x); taskrcond = srep.r2; } }
public static bool testdensesolver(bool silent) { bool result = new bool(); double[,] a = new double[0,0]; double[,] lua = new double[0,0]; double[,] atmp = new double[0,0]; int[] p = new int[0]; double[,] xe = new double[0,0]; double[,] b = new double[0,0]; double[] bv = new double[0]; int i = 0; int j = 0; int k = 0; int n = 0; int m = 0; int pass = 0; int taskkind = 0; double mx = 0; double v = 0; double verr = 0; int info = 0; densesolver.densesolverreport rep = new densesolver.densesolverreport(); densesolver.densesolverlsreport repls = new densesolver.densesolverlsreport(); double[,] x = new double[0,0]; double[] xv = new double[0]; double[] y = new double[0]; double[] tx = new double[0]; int maxn = 0; int maxm = 0; int passcount = 0; double threshold = 0; bool rerrors = new bool(); bool cerrors = new bool(); bool spderrors = new bool(); bool hpderrors = new bool(); bool rfserrors = new bool(); bool waserrors = new bool(); maxn = 10; maxm = 5; passcount = 5; threshold = 10000*math.machineepsilon; rfserrors = false; rerrors = false; cerrors = false; spderrors = false; hpderrors = false; testrsolver(maxn, maxm, passcount, threshold, ref rerrors, ref rfserrors); testspdsolver(maxn, maxm, passcount, threshold, ref spderrors, ref rfserrors); testcsolver(maxn, maxm, passcount, threshold, ref cerrors, ref rfserrors); testhpdsolver(maxn, maxm, passcount, threshold, ref hpderrors, ref rfserrors); waserrors = (((rerrors | cerrors) | spderrors) | hpderrors) | rfserrors; if( !silent ) { System.Console.Write("TESTING DENSE SOLVER"); System.Console.WriteLine(); System.Console.Write("* REAL: "); if( rerrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("* COMPLEX: "); if( cerrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("* SPD: "); if( spderrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("* HPD: "); if( hpderrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } System.Console.Write("* ITERATIVE IMPROVEMENT: "); if( rfserrors ) { System.Console.Write("FAILED"); System.Console.WriteLine(); } else { System.Console.Write("OK"); System.Console.WriteLine(); } if( waserrors ) { System.Console.Write("TEST FAILED"); System.Console.WriteLine(); } else { System.Console.Write("TEST PASSED"); System.Console.WriteLine(); } } result = !waserrors; return result; }