real norm2chol_sparsematrix(pchmatrix LU, pcsparsematrix sp) { avector tmp1, tmp2; uint rows = LU->rc->size; uint cols = LU->cc->size; pavector x, y; real norm; uint j; assert(sp->rows == rows); assert(sp->cols == cols); x = init_avector(&tmp1, cols); y = init_avector(&tmp2, rows); random_avector(x); norm = norm2_avector(x); scale_avector(1.0 / norm, x); for (j = 0; j < NORM_STEPS; j++) { // printf("norm = %g \n", sqrt( norm)); clear_avector(y); mvm_sparsematrix_avector(1.0, false, sp, x, y); triangularsolve_hmatrix_avector(true, false, false, LU, y); triangularsolve_hmatrix_avector(true, false, true, LU, y); add_avector(-1.0, y, x); copy_avector(x, y); triangularsolve_hmatrix_avector(true, false, false, LU, y); triangularsolve_hmatrix_avector(true, false, true, LU, y); mvm_sparsematrix_avector(-1.0, true, sp, y, x); norm = norm2_avector(x); scale_avector(1.0 / norm, x); } uninit_avector(y); uninit_avector(x); return REAL_SQRT(norm); }
static void check_triangularsolve(bool lower, bool unit, bool atrans, pcamatrix a, bool xtrans) { uint n = a->rows; amatrix xtmp, btmp; pamatrix x, b; avector xvtmp, bvtmp; pavector xv, bv; real error; assert(n == a->cols); /* * amatrix */ x = init_amatrix(&xtmp, n, n); random_amatrix(x); b = init_zero_amatrix(&btmp, n, n); if (xtrans) addmul_amatrix(1.0, false, x, !atrans, a, b); else addmul_amatrix(1.0, atrans, a, false, x, b); triangularsolve_amatrix(lower, unit, atrans, a, xtrans, b); add_amatrix(-1.0, false, x, b); error = norm2_amatrix(b) / norm2_amatrix(x); (void) printf("Checking amatrix triangularsolve\n" " (lower=%s, unit=%s, atrans=%s, xtrans=%s)\n" " Accuracy %g, %sokay\n", (lower ? "tr" : "fl"), (unit ? "tr" : "fl"), (atrans ? "tr" : "fl"), (xtrans ? "tr" : "fl"), error, (IS_IN_RANGE(0.0, error, 1.0e-14) ? "" : " NOT ")); if (!IS_IN_RANGE(0.0, error, 1.0e-14)) problems++; copy_amatrix(false, x, b); triangulareval_amatrix(lower, unit, atrans, a, xtrans, b); triangularsolve_amatrix(lower, unit, atrans, a, xtrans, b); add_amatrix(-1.0, false, x, b); error = norm2_amatrix(b) / norm2_amatrix(x); (void) printf("Checking amatrix triangulareval/triangularsolve\n" " (lower=%s, unit=%s, atrans=%s, xtrans=%s):\n" " Accuracy %g, %sokay\n", (lower ? "tr" : "fl"), (unit ? "tr" : "fl"), (atrans ? "tr" : "fl"), (xtrans ? "tr" : "fl"), error, (IS_IN_RANGE(0.0, error, 1.0e-14) ? "" : " NOT ")); if (!IS_IN_RANGE(0.0, error, 1.0e-14)) problems++; /* * avector */ xv = init_avector(&xvtmp, n); random_avector(xv); bv = init_avector(&bvtmp, n); clear_avector(bv); if (atrans) { addevaltrans_amatrix_avector(1.0, a, xv, bv); } else { addeval_amatrix_avector(1.0, a, xv, bv); } triangularsolve_amatrix_avector(lower, unit, atrans, a, bv); add_avector(-1.0, xv, bv); error = norm2_avector(bv) / norm2_avector(xv); (void) printf("Checking avector triangularsolve\n" " (lower=%s, unit=%s, atrans=%s)\n" " Accuracy %g, %sokay\n", (lower ? "tr" : "fl"), (unit ? "tr" : "fl"), (atrans ? "tr" : "fl"), error, (IS_IN_RANGE(0.0, error, 1.0e-14) ? "" : " NOT ")); if (!IS_IN_RANGE(0.0, error, 1.0e-14)) problems++; copy_avector(xv, bv); triangulareval_amatrix_avector(lower, unit, atrans, a, bv); triangularsolve_amatrix_avector(lower, unit, atrans, a, bv); add_avector(-1.0, xv, bv); error = norm2_avector(bv) / norm2_avector(xv); (void) printf("Checking avector triangulareval/triangularsolve\n" " (lower=%s, unit=%s, atrans=%s):\n" " Accuracy %g, %sokay\n", (lower ? "tr" : "fl"), (unit ? "tr" : "fl"), (atrans ? "tr" : "fl"), error, (IS_IN_RANGE(0.0, error, 1.0e-14) ? "" : " NOT ")); if (!IS_IN_RANGE(0.0, error, 1.0e-14)) problems++; uninit_amatrix(b); uninit_amatrix(x); uninit_avector(bv); uninit_avector(xv); }
int main() { pamatrix a, acopy, l, ld, r, q, qr; pavector x, b, tau; uint rows, cols; real error; rows = 8; cols = 5; (void) printf("----------------------------------------\n" "Check random %u x %u Cholesky factorization\n", rows, rows); (void) printf("Creating random self-adjoint positive definite matrix\n"); a = new_amatrix(rows, rows); random_spd_amatrix(a, 1.0); (void) printf("Creating random solution and right-hand side\n"); x = new_avector(rows); random_avector(x); b = new_avector(rows); clear_avector(b); mvm_amatrix_avector(1.0, false, a, x, b); (void) printf("Copying matrix\n"); acopy = new_amatrix(rows, rows); copy_amatrix(false, a, acopy); (void) printf("Computing Cholesky factorization\n"); choldecomp_amatrix(a); (void) printf("Solving\n"); cholsolve_amatrix_avector(a, b); add_avector(-1.0, x, b); error = norm2_avector(b); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; (void) printf("Building triangular factor\n"); l = new_amatrix(rows, rows); copy_lower_amatrix(a, false, l); (void) printf("Checking factorization\n"); copy_amatrix(false, acopy, a); addmul_amatrix(-1.0, false, l, true, l, a); error = normfrob_amatrix(a); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; del_amatrix(l); del_amatrix(acopy); del_avector(b); del_avector(x); del_amatrix(a); (void) printf("----------------------------------------\n" "Check random %u x %u LDL^T factorization\n", rows, rows); (void) printf("Creating random self-adjoint positive definite matrix\n"); a = new_amatrix(rows, rows); random_spd_amatrix(a, 1.0); (void) printf("Creating random solution and right-hand side\n"); x = new_avector(rows); random_avector(x); b = new_avector(rows); clear_avector(b); mvm_amatrix_avector(1.0, false, a, x, b); (void) printf("Copying matrix\n"); acopy = new_amatrix(rows, rows); copy_amatrix(false, a, acopy); (void) printf("Computing LDL^T factorization\n"); ldltdecomp_amatrix(a); (void) printf("Solving\n"); ldltsolve_amatrix_avector(a, b); add_avector(-1.0, x, b); error = norm2_avector(b); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; (void) printf("Building triangular factor\n"); l = new_amatrix(rows, rows); copy_lower_amatrix(a, true, l); (void) printf("Multiplying by diagonal\n"); ld = new_amatrix(rows, rows); copy_amatrix(false, l, ld); diageval_amatrix(true, a, true, ld); (void) printf("Checking factorization\n"); copy_amatrix(false, acopy, a); addmul_amatrix(-1.0, false, ld, true, l, a); error = normfrob_amatrix(a); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; del_amatrix(ld); del_amatrix(l); del_amatrix(acopy); del_avector(b); del_avector(x); del_amatrix(a); (void) printf("----------------------------------------\n" "Check random %u x %u LR factorization\n", rows, rows); (void) printf("Creating random invertible matrix\n"); a = new_amatrix(rows, rows); random_invertible_amatrix(a, 1.0); (void) printf("Creating random solution and right-hand side\n"); x = new_avector(rows); random_avector(x); b = new_avector(rows); clear_avector(b); mvm_amatrix_avector(1.0, false, a, x, b); (void) printf("Copying matrix\n"); acopy = new_amatrix(rows, rows); copy_amatrix(false, a, acopy); (void) printf("Computing LR factorization\n"); lrdecomp_amatrix(a); (void) printf("Solving\n"); lrsolve_amatrix_avector(a, b); add_avector(-1.0, x, b); error = norm2_avector(b); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; (void) printf("Building triangular factors\n"); l = new_amatrix(rows, rows); r = new_amatrix(rows, rows); copy_lower_amatrix(a, true, l); copy_upper_amatrix(a, false, r); (void) printf("Checking factorization\n"); copy_amatrix(false, acopy, a); addmul_amatrix(-1.0, false, l, false, r, a); error = normfrob_amatrix(a); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; /* Check forward/backward substitution */ (void) printf("----------------------------------------\n"); check_triangularsolve(true, true, false, l, false); check_triangularsolve(true, true, false, l, true); check_triangularsolve(true, true, true, l, false); check_triangularsolve(true, true, true, l, true); check_triangularsolve(true, false, false, l, false); check_triangularsolve(true, false, false, l, true); check_triangularsolve(true, false, true, l, false); check_triangularsolve(true, false, true, l, true); check_triangularsolve(false, false, false, r, false); check_triangularsolve(false, false, false, r, true); check_triangularsolve(false, false, true, r, false); check_triangularsolve(false, false, true, r, true); set_unit(r); check_triangularsolve(false, true, false, r, false); check_triangularsolve(false, true, false, r, true); check_triangularsolve(false, true, true, r, false); check_triangularsolve(false, true, true, r, true); /* Intermediate clean-up */ (void) printf("Cleaning up\n"); del_amatrix(r); del_amatrix(l); /* Check triangular matrix multiplication */ (void) printf("----------------------------------------\n"); check_triangularaddmul(false, false, false, false); check_triangularaddmul(true, false, false, false); check_triangularaddmul(false, true, false, false); check_triangularaddmul(true, true, false, false); check_triangularaddmul(false, false, true, false); check_triangularaddmul(true, false, true, false); check_triangularaddmul(false, true, true, false); check_triangularaddmul(true, true, true, false); check_triangularaddmul(false, false, false, true); check_triangularaddmul(true, false, false, true); check_triangularaddmul(false, true, false, true); check_triangularaddmul(true, true, false, true); check_triangularaddmul(false, false, true, true); check_triangularaddmul(true, false, true, true); check_triangularaddmul(false, true, true, true); check_triangularaddmul(true, true, true, true); /* Checking QR factorization */ (void) printf("----------------------------------------\n" "Check square QR factorization\n"); copy_amatrix(false, acopy, a); random_avector(x); clear_avector(b); mvm_amatrix_avector(1.0, false, a, x, b); tau = new_avector(rows); qrdecomp_amatrix(a, tau); (void) printf("Solving\n"); qrsolve_amatrix_avector(a, tau, b); add_avector(-1.0, x, b); error = norm2_avector(b); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; q = new_amatrix(rows, rows); qrexpand_amatrix(a, tau, q); (void) printf("Checking factorization\n"); r = new_amatrix(rows, rows); copy_upper_amatrix(a, false, r); qr = new_amatrix(rows, rows); copy_amatrix(false, acopy, qr); addmul_amatrix(-1.0, false, q, false, r, qr); error = normfrob_amatrix(qr); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; (void) printf("Checking inverse\n"); copy_amatrix(false, acopy, a); qrinvert_amatrix(a); identity_amatrix(qr); addmul_amatrix(-1.0, false, acopy, false, a, qr); error = normfrob_amatrix(qr); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; /* Intermediate clean-up */ (void) printf("Cleaning up\n"); del_amatrix(qr); del_amatrix(r); del_amatrix(q); del_avector(tau); del_avector(b); del_avector(x); del_amatrix(acopy); del_amatrix(a); /* Check forward/backward evaluation */ (void) printf("----------------------------------------\n"); a = new_amatrix(rows, cols); random_amatrix(a); check_lowereval(false, false, a, false); check_lowereval(false, false, a, true); check_lowereval(false, true, a, false); check_lowereval(false, true, a, true); check_uppereval(false, false, a, false); check_uppereval(false, false, a, true); check_uppereval(false, true, a, false); check_uppereval(false, true, a, true); set_unit(a); check_lowereval(true, false, a, false); check_lowereval(true, false, a, true); check_lowereval(true, true, a, false); check_lowereval(true, true, a, true); check_uppereval(true, false, a, false); check_uppereval(true, false, a, true); check_uppereval(true, true, a, false); check_uppereval(true, true, a, true); (void) printf("Cleaning up\n"); del_amatrix(a); a = new_amatrix(cols, rows); random_amatrix(a); check_lowereval(false, false, a, false); check_lowereval(false, false, a, true); check_lowereval(false, true, a, false); check_lowereval(false, true, a, true); check_uppereval(false, false, a, false); check_uppereval(false, false, a, true); check_uppereval(false, true, a, false); check_uppereval(false, true, a, true); set_unit(a); check_lowereval(true, false, a, false); check_lowereval(true, false, a, true); check_lowereval(true, true, a, false); check_lowereval(true, true, a, true); check_uppereval(true, false, a, false); check_uppereval(true, false, a, true); check_uppereval(true, true, a, false); check_uppereval(true, true, a, true); (void) printf("Cleaning up\n"); del_amatrix(a); /* Test random QR factorizations */ (void) printf("----------------------------------------\n" "Check full rectangular QR factorization\n"); a = new_amatrix(rows, cols); random_amatrix(a); acopy = new_amatrix(rows, cols); copy_amatrix(false, a, acopy); tau = new_avector(rows); qrdecomp_amatrix(a, tau); q = new_amatrix(rows, rows); r = new_amatrix(rows, cols); qrexpand_amatrix(a, tau, q); copy_upper_amatrix(a, false, r); qr = new_amatrix(rows, cols); copy_amatrix(false, acopy, qr); addmul_amatrix(-1.0, false, q, false, r, qr); error = normfrob_amatrix(qr); printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; del_amatrix(r); del_amatrix(q); (void) printf("Check skinny QR factorization\n"); q = new_amatrix(rows, cols); r = new_amatrix(cols, cols); qrexpand_amatrix(a, tau, q); copy_upper_amatrix(a, false, r); copy_amatrix(false, acopy, qr); addmul_amatrix(-1.0, false, q, false, r, qr); error = normfrob_amatrix(qr); printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; /* Final clean-up */ (void) printf("Cleaning up\n"); del_amatrix(qr); del_amatrix(r); del_amatrix(q); del_avector(tau); del_amatrix(acopy); del_amatrix(a); (void) printf("----------------------------------------\n" " %u matrices and\n" " %u vectors still active\n" " %u errors found\n", getactives_amatrix(), getactives_avector(), problems); return problems; }
int main() { ph2matrix h2, h2copy, L, R; pclusterbasis rb, cb, rbcopy, cbcopy, rblow, cblow, rbup, cbup; pclusteroperator rwf, cwf, rwflow, cwflow, rwfup, cwfup, rwfh2, cwfh2; ptruncmode tm; pavector x, b; uint n; real error; pcurve2d gr2; pbem2d bem2; pcluster root2; pblock block2; uint clf, m; real tol, eta, delta, eps_aca; n = 579; tol = 1.0e-13; clf = 16; eta = 1.0; m = 4; delta = 1.0; eps_aca = 1.0e-13; gr2 = new_circle_curve2d(n, 0.333); bem2 = new_slp_laplace_bem2d(gr2, 2, BASIS_CONSTANT_BEM2D); root2 = build_bem2d_cluster(bem2, clf, BASIS_CONSTANT_BEM2D); block2 = build_strict_block(root2, root2, &eta, admissible_max_cluster); rb = build_from_cluster_clusterbasis(root2); cb = build_from_cluster_clusterbasis(root2); setup_h2matrix_aprx_greenhybrid_bem2d(bem2, rb, cb, block2, m, 1, delta, eps_aca, build_bem2d_rect_quadpoints); (void) printf("----------------------------------------\n" "Check %u x %u Cholesky factorization\n", n, n); (void) printf("Creating laplacebem2d SLP matrix\n"); assemble_bem2d_h2matrix_row_clusterbasis(bem2, rb); assemble_bem2d_h2matrix_col_clusterbasis(bem2, cb); h2 = build_from_block_h2matrix(block2, rb, cb); assemble_bem2d_h2matrix(bem2, block2, h2); (void) printf("Creating random solution and right-hand side\n"); x = new_avector(n); random_avector(x); b = new_avector(n); clear_avector(b); mvm_h2matrix_avector(1.0, false, h2, x, b); (void) printf("Copying matrix\n"); rbcopy = clone_clusterbasis(h2->rb); cbcopy = clone_clusterbasis(h2->cb); h2copy = clone_h2matrix(h2, rbcopy, cbcopy); (void) printf("Computing Cholesky factorization\n"); tm = new_releucl_truncmode(); rblow = build_from_cluster_clusterbasis(root2); cblow = build_from_cluster_clusterbasis(root2); L = build_from_block_lower_h2matrix(block2, rblow, cblow); rwflow = prepare_row_clusteroperator(L->rb, L->cb, tm); cwflow = prepare_col_clusteroperator(L->rb, L->cb, tm); rwf = NULL; cwf = NULL; init_cholesky_h2matrix(h2, &rwf, &cwf, tm); choldecomp_h2matrix(h2, rwf, cwf, L, rwflow, cwflow, tm, tol); (void) printf("Solving\n"); cholsolve_h2matrix_avector(L, b); add_avector(-1.0, x, b); error = norm2_avector(b) / norm2_avector(x); (void) printf(" Accuracy %g, %sokay\n", error, IS_IN_RANGE(2.0e-13, error, 3.0e-12) ? "" : " NOT "); if (!IS_IN_RANGE(2.0e-13, error, 3.0e-12)) problems++; rwfh2 = prepare_row_clusteroperator(h2copy->rb, h2copy->cb, tm); cwfh2 = prepare_col_clusteroperator(h2copy->rb, h2copy->cb, tm); (void) printf("Checking factorization\n"); error = norm2_h2matrix(h2copy); addmul_h2matrix(-1.0, L, true, L, h2copy, rwfh2, cwfh2, tm, tol); error = norm2_h2matrix(h2copy) / error; (void) printf(" Accuracy %g, %sokay\n", error, IS_IN_RANGE(4.0e-15, error, 4.0e-14) ? "" : " NOT "); if (!IS_IN_RANGE(4.0e-15, error, 4.0e-14)) problems++; del_h2matrix(h2copy); del_h2matrix(h2); del_h2matrix(L); del_avector(b); del_avector(x); del_truncmode(tm); del_clusteroperator(rwflow); del_clusteroperator(cwflow); del_clusteroperator(rwf); del_clusteroperator(cwf); del_clusteroperator(rwfh2); del_clusteroperator(cwfh2); rb = build_from_cluster_clusterbasis(root2); cb = build_from_cluster_clusterbasis(root2); setup_h2matrix_aprx_greenhybrid_bem2d(bem2, rb, cb, block2, m, 1, delta, eps_aca, build_bem2d_rect_quadpoints); (void) printf("----------------------------------------\n" "Check %u x %u LR factorization\n", n, n); (void) printf("Creating laplacebem2d SLP matrix\n"); assemble_bem2d_h2matrix_row_clusterbasis(bem2, rb); assemble_bem2d_h2matrix_col_clusterbasis(bem2, cb); h2 = build_from_block_h2matrix(block2, rb, cb); assemble_bem2d_h2matrix(bem2, block2, h2); (void) printf("Creating random solution and right-hand side\n"); x = new_avector(n); random_avector(x); b = new_avector(n); clear_avector(b); mvm_h2matrix_avector(1.0, false, h2, x, b); (void) printf("Copying matrix\n"); rbcopy = clone_clusterbasis(h2->rb); cbcopy = clone_clusterbasis(h2->cb); h2copy = clone_h2matrix(h2, rbcopy, cbcopy); (void) printf("Computing LR factorization\n"); rblow = build_from_cluster_clusterbasis(root2); cblow = build_from_cluster_clusterbasis(root2); L = build_from_block_lower_h2matrix(block2, rblow, cblow); rbup = build_from_cluster_clusterbasis(root2); cbup = build_from_cluster_clusterbasis(root2); R = build_from_block_upper_h2matrix(block2, rbup, cbup); tm = new_releucl_truncmode(); rwf = prepare_row_clusteroperator(h2->rb, h2->cb, tm); cwf = prepare_col_clusteroperator(h2->rb, h2->cb, tm); rwflow = prepare_row_clusteroperator(L->rb, L->cb, tm); cwflow = prepare_col_clusteroperator(L->rb, L->cb, tm); rwfup = prepare_row_clusteroperator(R->rb, R->cb, tm); cwfup = prepare_col_clusteroperator(R->rb, R->cb, tm); lrdecomp_h2matrix(h2, rwf, cwf, L, rwflow, cwflow, R, rwfup, cwfup, tm, tol); (void) printf("Solving\n"); lrsolve_h2matrix_avector(L, R, b); add_avector(-1.0, x, b); error = norm2_avector(b) / norm2_avector(x); (void) printf(" Accuracy %g, %sokay\n", error, IS_IN_RANGE(2e-13, error, 2e-12) ? "" : " NOT "); if (!IS_IN_RANGE(2e-13, error, 2e-12)) problems++; rwfh2 = prepare_row_clusteroperator(h2copy->rb, h2copy->cb, tm); cwfh2 = prepare_col_clusteroperator(h2copy->rb, h2copy->cb, tm); (void) printf("Checking factorization\n"); error = norm2_h2matrix(h2copy); addmul_h2matrix(-1.0, L, false, R, h2copy, rwfh2, cwfh2, tm, tol); error = norm2_h2matrix(h2copy) / error; (void) printf(" Accuracy %g, %sokay\n", error, IS_IN_RANGE(4.0e-15, error, 5.0e-14) ? "" : " NOT "); if (!IS_IN_RANGE(4.0e-15, error, 5.0e-14)) problems++; /* Final clean-up */ (void) printf("Cleaning up\n"); del_h2matrix(h2); del_h2matrix(h2copy); del_h2matrix(L); del_h2matrix(R); del_clusteroperator(rwf); del_clusteroperator(cwf); del_clusteroperator(rwflow); del_clusteroperator(cwflow); del_clusteroperator(rwfup); del_clusteroperator(cwfup); del_clusteroperator(rwfh2); del_clusteroperator(cwfh2); del_avector(b); del_avector(x); del_truncmode(tm); freemem(root2->idx); del_bem2d(bem2); del_block(block2); del_cluster(root2); del_curve2d(gr2); (void) printf("----------------------------------------\n" " %u matrices and\n" " %u vectors still active\n" " %u errors found\n", getactives_amatrix(), getactives_avector(), problems); return problems; }