void uninit_hmatrix(phmatrix hm) { int rsons = hm->rsons; int csons = hm->csons; assert(hm->refs == 0); if (hm->son) { for (int j=0;j<csons;j++) { for (int i=0;i<rsons;i++) { unref_hmatrix(hm->son[i+j*rsons]); } } delete [] hm->son; } if (hm->f) { del_amatrix(hm->f); } if (hm->r) { del_rkmatrix(hm->r); } }
/* Simple convenience wrapper for GMRES solver */ static void solve_gmres_bem3d(matrixtype type, void *A, pavector b, pavector x, real accuracy, uint steps) { addeval_t addevalA; pavector rhat, q, tau; pamatrix qr; uint i, j, n, kk, kmax; real norm; addevalA = (addeval_t) addeval_A; kmax = 500; n = b->dim; assert(x->dim == n); qr = new_zero_amatrix(n, kmax); rhat = new_avector(n); q = new_avector(n); tau = new_avector(kmax); clear_avector(x); init_gmres(addevalA, A, b, x, rhat, q, &kk, qr, tau); for (i = 0; i < steps; i += kmax) { for (j = 0; j < kmax && i + j < steps; ++j) { step_gmres(addevalA, A, b, x, rhat, q, &kk, qr, tau); norm = residualnorm_gmres(rhat, kk); #ifndef NDEBUG printf(" Residual: %.5e\t Iterations: %u\r", norm, j + i); fflush(stdout); #endif if (norm <= accuracy) { finish_gmres(addevalA, A, b, x, rhat, q, &kk, qr, tau); break; } } if (norm <= accuracy) { break; } else { finish_gmres(addevalA, A, b, x, rhat, q, &kk, qr, tau); } } printf("\n"); del_avector(rhat); del_avector(q); del_avector(tau); del_amatrix(qr); }
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(int argc, char **argv) { pcurve2d gr; pamatrix Vfull, KMfull; pbem2d bem_slp, bem_dlp; pcluster root; pblock block; phmatrix V, KM; pclusterbasis Vrb, Vcb, KMrb, KMcb; ph2matrix V2, KM2; uint n, q, clf, m, l; real eta, delta, eps_aca; init_h2lib(&argc, &argv); n = 579; q = 2; clf = 16; eta = 1.0; gr = new_circle_curve2d(n, 0.333); bem_slp = new_slp_laplace_bem2d(gr, q, BASIS_CONSTANT_BEM2D); bem_dlp = new_dlp_laplace_bem2d(gr, q, BASIS_CONSTANT_BEM2D, BASIS_CONSTANT_BEM2D, 0.5); root = build_bem2d_cluster(bem_slp, clf, BASIS_CONSTANT_BEM2D); block = build_nonstrict_block(root, root, &eta, admissible_max_cluster); Vfull = new_amatrix(n, n); KMfull = new_amatrix(n, n); bem_slp->nearfield(NULL, NULL, bem_slp, false, Vfull); bem_dlp->nearfield(NULL, NULL, bem_dlp, false, KMfull); V = build_from_block_hmatrix(block, 0); KM = build_from_block_hmatrix(block, 0); printf("----------------------------------------\n"); printf("Testing inner Boundary integral equations:\n"); printf("----------------------------------------\n\n"); /* * Test Interpolation */ m = 9; setup_hmatrix_aprx_inter_row_bem2d(bem_slp, root, root, block, m); setup_hmatrix_aprx_inter_row_bem2d(bem_dlp, root, root, block, m); test_hmatrix_system("Interpolation row", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false); setup_hmatrix_aprx_inter_col_bem2d(bem_slp, root, root, block, m); setup_hmatrix_aprx_inter_col_bem2d(bem_dlp, root, root, block, m); test_hmatrix_system("Interpolation column", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false); setup_hmatrix_aprx_inter_mixed_bem2d(bem_slp, root, root, block, m); setup_hmatrix_aprx_inter_mixed_bem2d(bem_dlp, root, root, block, m); test_hmatrix_system("Interpolation mixed", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false); /* * Test Green */ m = 10; l = 2; delta = 0.5; setup_hmatrix_aprx_green_row_bem2d(bem_slp, root, root, block, m, l, delta, build_bem2d_rect_quadpoints); setup_hmatrix_aprx_green_row_bem2d(bem_dlp, root, root, block, m, l, delta, build_bem2d_rect_quadpoints); test_hmatrix_system("Green row", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false); setup_hmatrix_aprx_green_col_bem2d(bem_slp, root, root, block, m, l, delta, build_bem2d_rect_quadpoints); setup_hmatrix_aprx_green_col_bem2d(bem_dlp, root, root, block, m, l, delta, build_bem2d_rect_quadpoints); test_hmatrix_system("Green column", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false); setup_hmatrix_aprx_green_mixed_bem2d(bem_slp, root, root, block, m, l, delta, build_bem2d_rect_quadpoints); setup_hmatrix_aprx_green_mixed_bem2d(bem_dlp, root, root, block, m, l, delta, build_bem2d_rect_quadpoints); test_hmatrix_system("Green mixed", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false); /* * Test Greenhybrid */ m = 3; l = 1; delta = 1.0; eps_aca = 1.0e-7; setup_hmatrix_aprx_greenhybrid_row_bem2d(bem_slp, root, root, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); setup_hmatrix_aprx_greenhybrid_row_bem2d(bem_dlp, root, root, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); test_hmatrix_system("Greenhybrid row", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false); setup_hmatrix_aprx_greenhybrid_col_bem2d(bem_slp, root, root, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); setup_hmatrix_aprx_greenhybrid_col_bem2d(bem_dlp, root, root, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); test_hmatrix_system("Greenhybrid column", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false); setup_hmatrix_aprx_greenhybrid_mixed_bem2d(bem_slp, root, root, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); setup_hmatrix_aprx_greenhybrid_mixed_bem2d(bem_dlp, root, root, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); test_hmatrix_system("Greenhybrid mixed", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false); /* * Test ACA / PACA / HCA */ m = 4; eps_aca = 1.0e-6; setup_hmatrix_aprx_aca_bem2d(bem_slp, root, root, block, eps_aca); setup_hmatrix_aprx_aca_bem2d(bem_dlp, root, root, block, eps_aca); test_hmatrix_system("ACA full pivoting", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false); setup_hmatrix_aprx_paca_bem2d(bem_slp, root, root, block, eps_aca); setup_hmatrix_aprx_paca_bem2d(bem_dlp, root, root, block, eps_aca); test_hmatrix_system("ACA partial pivoting", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false); setup_hmatrix_aprx_hca_bem2d(bem_slp, root, root, block, m, eps_aca); setup_hmatrix_aprx_hca_bem2d(bem_dlp, root, root, block, m, eps_aca); test_hmatrix_system("HCA2", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false); /* * H2-matrix */ del_hmatrix(V); del_hmatrix(KM); del_block(block); block = build_strict_block(root, root, &eta, admissible_max_cluster); Vrb = build_from_cluster_clusterbasis(root); Vcb = build_from_cluster_clusterbasis(root); KMrb = build_from_cluster_clusterbasis(root); KMcb = build_from_cluster_clusterbasis(root); V2 = build_from_block_h2matrix(block, Vrb, Vcb); KM2 = build_from_block_h2matrix(block, KMrb, KMcb); /* * Test Interpolation */ m = 9; setup_h2matrix_aprx_inter_bem2d(bem_slp, Vrb, Vcb, block, m); setup_h2matrix_aprx_inter_bem2d(bem_dlp, KMrb, KMcb, block, m); test_h2matrix_system("Interpolation", Vfull, KMfull, block, bem_slp, V2, bem_dlp, KM2, false); /* * Test Greenhybrid */ m = 3; l = 1; delta = 1.0; eps_aca = 1.0e-7; setup_h2matrix_aprx_greenhybrid_bem2d(bem_slp, Vrb, Vcb, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); setup_h2matrix_aprx_greenhybrid_bem2d(bem_dlp, KMrb, KMcb, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); test_h2matrix_system("Greenhybrid", Vfull, KMfull, block, bem_slp, V2, bem_dlp, KM2, false); setup_h2matrix_aprx_greenhybrid_ortho_bem2d(bem_slp, Vrb, Vcb, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); setup_h2matrix_aprx_greenhybrid_ortho_bem2d(bem_dlp, KMrb, KMcb, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); test_h2matrix_system("Greenhybrid ortho", Vfull, KMfull, block, bem_slp, V2, bem_dlp, KM2, false); del_h2matrix(V2); del_h2matrix(KM2); del_block(block); del_bem2d(bem_dlp); printf("----------------------------------------\n"); printf("Testing outer Boundary integral equations:\n"); printf("----------------------------------------\n\n"); bem_dlp = new_dlp_laplace_bem2d(gr, q, BASIS_CONSTANT_BEM2D, BASIS_CONSTANT_BEM2D, -0.5); block = build_nonstrict_block(root, root, &eta, admissible_max_cluster); bem_dlp->nearfield(NULL, NULL, bem_dlp, false, KMfull); V = build_from_block_hmatrix(block, 0); KM = build_from_block_hmatrix(block, 0); /* * Test Interpolation */ m = 9; setup_hmatrix_aprx_inter_row_bem2d(bem_slp, root, root, block, m); setup_hmatrix_aprx_inter_row_bem2d(bem_dlp, root, root, block, m); test_hmatrix_system("Interpolation row", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, true); setup_hmatrix_aprx_inter_col_bem2d(bem_slp, root, root, block, m); setup_hmatrix_aprx_inter_col_bem2d(bem_dlp, root, root, block, m); test_hmatrix_system("Interpolation column", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, true); setup_hmatrix_aprx_inter_mixed_bem2d(bem_slp, root, root, block, m); setup_hmatrix_aprx_inter_mixed_bem2d(bem_dlp, root, root, block, m); test_hmatrix_system("Interpolation mixed", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, true); /* * Test Green */ m = 10; l = 2; delta = 0.5; setup_hmatrix_aprx_green_row_bem2d(bem_slp, root, root, block, m, l, delta, build_bem2d_rect_quadpoints); setup_hmatrix_aprx_green_row_bem2d(bem_dlp, root, root, block, m, l, delta, build_bem2d_rect_quadpoints); test_hmatrix_system("Green row", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, true); setup_hmatrix_aprx_green_col_bem2d(bem_slp, root, root, block, m, l, delta, build_bem2d_rect_quadpoints); setup_hmatrix_aprx_green_col_bem2d(bem_dlp, root, root, block, m, l, delta, build_bem2d_rect_quadpoints); test_hmatrix_system("Green column", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, true); setup_hmatrix_aprx_green_mixed_bem2d(bem_slp, root, root, block, m, l, delta, build_bem2d_rect_quadpoints); setup_hmatrix_aprx_green_mixed_bem2d(bem_dlp, root, root, block, m, l, delta, build_bem2d_rect_quadpoints); test_hmatrix_system("Green mixed", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, true); /* * Test Greenhybrid */ m = 3; l = 1; delta = 1.0; eps_aca = 1.0e-7; setup_hmatrix_aprx_greenhybrid_row_bem2d(bem_slp, root, root, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); setup_hmatrix_aprx_greenhybrid_row_bem2d(bem_dlp, root, root, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); test_hmatrix_system("Greenhybrid row", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, true); setup_hmatrix_aprx_greenhybrid_col_bem2d(bem_slp, root, root, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); setup_hmatrix_aprx_greenhybrid_col_bem2d(bem_dlp, root, root, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); test_hmatrix_system("Greenhybrid column", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, true); setup_hmatrix_aprx_greenhybrid_mixed_bem2d(bem_slp, root, root, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); setup_hmatrix_aprx_greenhybrid_mixed_bem2d(bem_dlp, root, root, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); test_hmatrix_system("Greenhybrid mixed", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, true); /* * Test ACA / PACA / HCA */ m = 4; eps_aca = 1.0e-6; setup_hmatrix_aprx_aca_bem2d(bem_slp, root, root, block, eps_aca); setup_hmatrix_aprx_aca_bem2d(bem_dlp, root, root, block, eps_aca); test_hmatrix_system("ACA full pivoting", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, true); setup_hmatrix_aprx_paca_bem2d(bem_slp, root, root, block, eps_aca); setup_hmatrix_aprx_paca_bem2d(bem_dlp, root, root, block, eps_aca); test_hmatrix_system("ACA partial pivoting", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, true); setup_hmatrix_aprx_hca_bem2d(bem_slp, root, root, block, m, eps_aca); setup_hmatrix_aprx_hca_bem2d(bem_dlp, root, root, block, m, eps_aca); test_hmatrix_system("HCA2", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, true); /* * H2-matrix */ del_hmatrix(V); del_hmatrix(KM); del_block(block); block = build_strict_block(root, root, &eta, admissible_max_cluster); Vrb = build_from_cluster_clusterbasis(root); Vcb = build_from_cluster_clusterbasis(root); KMrb = build_from_cluster_clusterbasis(root); KMcb = build_from_cluster_clusterbasis(root); V2 = build_from_block_h2matrix(block, Vrb, Vcb); KM2 = build_from_block_h2matrix(block, KMrb, KMcb); /* * Test Interpolation */ m = 9; setup_h2matrix_aprx_inter_bem2d(bem_slp, Vrb, Vcb, block, m); setup_h2matrix_aprx_inter_bem2d(bem_dlp, KMrb, KMcb, block, m); test_h2matrix_system("Interpolation", Vfull, KMfull, block, bem_slp, V2, bem_dlp, KM2, true); /* * Test Greenhybrid */ m = 3; l = 1; delta = 1.0; eps_aca = 1.0e-7; setup_h2matrix_aprx_greenhybrid_bem2d(bem_slp, Vrb, Vcb, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); setup_h2matrix_aprx_greenhybrid_bem2d(bem_dlp, KMrb, KMcb, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); test_h2matrix_system("Greenhybrid", Vfull, KMfull, block, bem_slp, V2, bem_dlp, KM2, true); setup_h2matrix_aprx_greenhybrid_ortho_bem2d(bem_slp, Vrb, Vcb, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); setup_h2matrix_aprx_greenhybrid_ortho_bem2d(bem_dlp, KMrb, KMcb, block, m, l, delta, eps_aca, build_bem2d_rect_quadpoints); test_h2matrix_system("Greenhybrid Ortho", Vfull, KMfull, block, bem_slp, V2, bem_dlp, KM2, true); del_h2matrix(V2); del_h2matrix(KM2); del_block(block); freemem(root->idx); del_cluster(root); del_bem2d(bem_slp); del_bem2d(bem_dlp); del_amatrix(Vfull); del_amatrix(KMfull); del_curve2d(gr); (void) printf("----------------------------------------\n" " %u matrices and\n" " %u vectors still active\n" " %u errors found\n", getactives_amatrix(), getactives_avector(), problems); uninit_h2lib(); return problems; }
int main(int argc, char **argv) { pmacrosurface3d mg; psurface3d gr; pamatrix Vfull, KMfull; pbem3d bem_slp, bem_dlp; pcluster root; pblock block; phmatrix V, KM; pclusterbasis Vrb, Vcb, KMrb, KMcb; ph2matrix V2, KM2; uint n, q, clf, m, l; real eta, delta, eps_aca; field kvec[3]; cl_device_id *devices; cl_uint ndevices; uint *idx; uint i; init_h2lib(&argc, &argv); get_opencl_devices(&devices, &ndevices); ndevices = 1; set_opencl_devices(devices, ndevices, 2); kvec[0] = 2.0, kvec[1] = 0.0, kvec[2] = 0.0; n = 512; q = 2; clf = 16; eta = 1.0; mg = new_sphere_macrosurface3d(); gr = build_from_macrosurface3d_surface3d(mg, REAL_SQRT(n * 0.125)); n = gr->triangles; printf("Testing unit sphere with %d triangles\n", n); bem_slp = new_slp_helmholtz_ocl_bem3d(kvec, gr, q, q + 2, BASIS_CONSTANT_BEM3D); bem_dlp = new_dlp_helmholtz_ocl_bem3d(kvec, gr, q, q + 2, BASIS_CONSTANT_BEM3D, BASIS_CONSTANT_BEM3D, 0.5); root = build_bem3d_cluster(bem_slp, clf, BASIS_CONSTANT_BEM3D); block = build_nonstrict_block(root, root, &eta, admissible_max_cluster); max_pardepth = 0; Vfull = new_amatrix(n, n); KMfull = new_amatrix(n, n); idx = allocuint(n); for (i = 0; i < n; ++i) { idx[i] = i; } SCHEDULE_OPENCL(0, 1, bem_slp->nearfield, idx, idx, bem_slp, false, Vfull); SCHEDULE_OPENCL(0, 1, bem_dlp->nearfield, idx, idx, bem_dlp, false, KMfull); V = build_from_block_hmatrix(block, 0); KM = build_from_block_hmatrix(block, 0); printf("----------------------------------------\n"); printf("Testing outer Boundary integral equations:\n"); printf("----------------------------------------\n\n"); /* * Test Interpolation */ m = 4; setup_hmatrix_aprx_inter_row_bem3d(bem_slp, root, root, block, m); setup_hmatrix_aprx_inter_row_bem3d(bem_dlp, root, root, block, m); test_hmatrix_system("Interpolation row", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false, true, 1.0e-3, 2.0e-3); setup_hmatrix_aprx_inter_col_bem3d(bem_slp, root, root, block, m); setup_hmatrix_aprx_inter_col_bem3d(bem_dlp, root, root, block, m); test_hmatrix_system("Interpolation column", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false, true, 1.0e-3, 2.0e-3); setup_hmatrix_aprx_inter_mixed_bem3d(bem_slp, root, root, block, m); setup_hmatrix_aprx_inter_mixed_bem3d(bem_dlp, root, root, block, m); test_hmatrix_system("Interpolation mixed", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false, true, 1.0e-3, 2.0e-3); /* * Test Green */ m = 5; l = 1; delta = 0.5; setup_hmatrix_aprx_green_row_bem3d(bem_slp, root, root, block, m, l, delta, build_bem3d_cube_quadpoints); setup_hmatrix_aprx_green_row_bem3d(bem_dlp, root, root, block, m, l, delta, build_bem3d_cube_quadpoints); test_hmatrix_system("Green row", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false, true, 1.0e-3, 2.0e-3); setup_hmatrix_aprx_green_col_bem3d(bem_slp, root, root, block, m, l, delta, build_bem3d_cube_quadpoints); setup_hmatrix_aprx_green_col_bem3d(bem_dlp, root, root, block, m, l, delta, build_bem3d_cube_quadpoints); test_hmatrix_system("Green column", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false, true, 1.0e-3, 2.0e-3); setup_hmatrix_aprx_green_mixed_bem3d(bem_slp, root, root, block, m, l, delta, build_bem3d_cube_quadpoints); setup_hmatrix_aprx_green_mixed_bem3d(bem_dlp, root, root, block, m, l, delta, build_bem3d_cube_quadpoints); test_hmatrix_system("Green mixed", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false, true, 1.0e-3, 2.0e-3); /* * Test Greenhybrid */ m = 2; l = 1; delta = 1.0; eps_aca = 2.0e-2; setup_hmatrix_aprx_greenhybrid_row_bem3d(bem_slp, root, root, block, m, l, delta, eps_aca, build_bem3d_cube_quadpoints); setup_hmatrix_aprx_greenhybrid_row_bem3d(bem_dlp, root, root, block, m, l, delta, eps_aca, build_bem3d_cube_quadpoints); test_hmatrix_system("Greenhybrid row", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false, true, 1.0e-3, 2.0e-3); setup_hmatrix_aprx_greenhybrid_col_bem3d(bem_slp, root, root, block, m, l, delta, eps_aca, build_bem3d_cube_quadpoints); setup_hmatrix_aprx_greenhybrid_col_bem3d(bem_dlp, root, root, block, m, l, delta, eps_aca, build_bem3d_cube_quadpoints); test_hmatrix_system("Greenhybrid column", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false, true, 1.0e-3, 2.0e-3); setup_hmatrix_aprx_greenhybrid_mixed_bem3d(bem_slp, root, root, block, m, l, delta, eps_aca, build_bem3d_cube_quadpoints); setup_hmatrix_aprx_greenhybrid_mixed_bem3d(bem_dlp, root, root, block, m, l, delta, eps_aca, build_bem3d_cube_quadpoints); test_hmatrix_system("Greenhybrid mixed", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false, true, 1.0e-3, 2.0e-3); /* * Test ACA / PACA / HCA */ m = 2; eps_aca = 1.0e-2; /* Nearfield computation on GPU not applicable here yet! */ // setup_hmatrix_aprx_aca_bem3d(bem_slp, root, root, block, eps_aca); // setup_hmatrix_aprx_aca_bem3d(bem_dlp, root, root, block, eps_aca); // test_hmatrix_system("ACA full pivoting", Vfull, KMfull, block, bem_slp, V, // bem_dlp, KM, false, true, 1.0e-3, 2.0e-3); // // setup_hmatrix_aprx_paca_bem3d(bem_slp, root, root, block, eps_aca); // setup_hmatrix_aprx_paca_bem3d(bem_slp, root, root, block, eps_aca); // test_hmatrix_system("ACA partial pivoting", Vfull, KMfull, block, bem_slp, V, // bem_dlp, KM, false, true, 1.0e-3, 2.0e-3); setup_hmatrix_aprx_hca_bem3d(bem_slp, root, root, block, m, eps_aca); setup_hmatrix_aprx_hca_bem3d(bem_slp, root, root, block, m, eps_aca); test_hmatrix_system("HCA2", Vfull, KMfull, block, bem_slp, V, bem_dlp, KM, false, true, 1.0e-3, 2.0e-3); del_hmatrix(V); del_hmatrix(KM); del_block(block); /* * H2-matrix */ block = build_strict_block(root, root, &eta, admissible_max_cluster); Vrb = build_from_cluster_clusterbasis(root); Vcb = build_from_cluster_clusterbasis(root); KMrb = build_from_cluster_clusterbasis(root); KMcb = build_from_cluster_clusterbasis(root); V2 = build_from_block_h2matrix(block, Vrb, Vcb); KM2 = build_from_block_h2matrix(block, KMrb, KMcb); /* * Test Interpolation */ m = 3; setup_h2matrix_aprx_inter_bem3d(bem_slp, Vrb, Vcb, block, m); setup_h2matrix_aprx_inter_bem3d(bem_dlp, KMrb, KMcb, block, m); test_h2matrix_system("Interpolation", Vfull, KMfull, block, bem_slp, V2, bem_dlp, KM2, false, true, 1.0e-3, 2.0e-3); /* * Test Greenhybrid */ m = 2; l = 1; delta = 1.0; eps_aca = 2.0e-2; setup_h2matrix_aprx_greenhybrid_bem3d(bem_slp, Vrb, Vcb, block, m, l, delta, eps_aca, build_bem3d_cube_quadpoints); setup_h2matrix_aprx_greenhybrid_bem3d(bem_dlp, KMrb, KMcb, block, m, l, delta, eps_aca, build_bem3d_cube_quadpoints); test_h2matrix_system("Greenhybrid", Vfull, KMfull, block, bem_slp, V2, bem_dlp, KM2, false, true, 1.0e-3, 2.0e-3); /* Nearfield computation on GPU not applicable here yet! */ // setup_h2matrix_aprx_greenhybrid_ortho_bem3d(bem_slp, Vrb, Vcb, block, m, l, // delta, eps_aca, build_bem3d_cube_quadpoints); // setup_h2matrix_aprx_greenhybrid_ortho_bem3d(bem_dlp, KMrb, KMcb, block, m, l, // delta, eps_aca, build_bem3d_cube_quadpoints); // test_h2matrix_system("Greenhybrid ortho", Vfull, KMfull, block, bem_slp, V2, // bem_dlp, KM2, false, true, 1.0e-3, 2.0e-3); del_h2matrix(V2); del_h2matrix(KM2); del_block(block); freemem(root->idx); del_cluster(root); del_helmholtz_ocl_bem3d(bem_slp); del_helmholtz_ocl_bem3d(bem_dlp); del_amatrix(Vfull); del_amatrix(KMfull); del_surface3d(gr); del_macrosurface3d(mg); freemem(idx); (void) printf("----------------------------------------\n" " %u matrices and\n" " %u vectors still active\n" " %u errors found\n", getactives_amatrix(), getactives_avector(), problems); uninit_h2lib(); return problems; }
int main() { ptridiag T, Tcopy; pamatrix A, Acopy, Q, U, Vt; pavector work; prealavector sigma, lambda; real error; uint rows, cols, mid; uint i, n, iter; int info; /* ------------------------------------------------------------ * Testing symmetric tridiagonal eigenvalue solver * ------------------------------------------------------------ */ n = 6; /* Testing symmetric tridiagonal eigenvalue solver */ (void) printf("==================================================\n" "Testing symmetric tridiagonal eigenvalue solver\n" "==================================================\n" "Setting up %u x %u tridiagonal matrix\n", n, n); T = new_tridiag(n); for (i = 0; i < n; i++) T->d[i] = 2.0; for (i = 0; i < n - 1; i++) T->l[i] = T->u[i] = -1.0; Tcopy = new_tridiag(n); copy_tridiag(T, Tcopy); A = new_amatrix(n, n); clear_amatrix(A); for (i = 0; i < n; i++) A->a[i + i * A->ld] = T->d[i]; for (i = 0; i < n - 1; i++) { A->a[(i + 1) + i * A->ld] = T->l[i]; A->a[i + (i + 1) * A->ld] = T->u[i]; } Acopy = clone_amatrix(A); Q = new_identity_amatrix(n, n); U = new_amatrix(n, n); (void) printf("Performing self-made implicit QR iteration\n"); iter = sb_muleig_tridiag(T, Q, 8 * n); (void) printf(" %u iterations\n", iter); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, Q); (void) printf(" Orthogonality Q %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; copy_amatrix(false, Q, U); diageval_tridiag_amatrix(1.0, true, T, true, U); addmul_amatrix(-1.0, false, U, true, Q, A); error = normfrob_amatrix(A); (void) printf(" Accuracy %g. %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; (void) printf("Performing default implicit QR iteration\n"); identity_amatrix(Q); i = muleig_tridiag(Tcopy, Q); if (i == 0) (void) printf(" Success\n"); else { (void) printf(" Failure\n"); problems++; } (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, Q); (void) printf(" Orthogonality Q %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; copy_amatrix(false, Q, U); diageval_tridiag_amatrix(1.0, true, Tcopy, true, U); addmul_amatrix(-1.0, false, U, true, Q, Acopy); error = normfrob_amatrix(Acopy); (void) printf(" Accuracy %g. %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; del_amatrix(U); del_amatrix(Q); del_amatrix(Acopy); del_amatrix(A); del_tridiag(Tcopy); del_tridiag(T); (void) printf("--------------------------------------------------\n" "Setting up random %u x %u tridiagonal matrix\n", n, n); T = new_tridiag(n); for (i = 0; i < n; i++) T->d[i] = 2.0 * rand() / RAND_MAX - 1.0; for (i = 0; i < n - 1; i++) { T->l[i] = 2.0 * rand() / RAND_MAX - 1.0; T->u[i] = CONJ(T->l[i]); } A = new_amatrix(n, n); clear_amatrix(A); for (i = 0; i < n; i++) A->a[i + i * A->ld] = T->d[i]; for (i = 0; i < n - 1; i++) { A->a[(i + 1) + i * A->ld] = T->l[i]; A->a[i + (i + 1) * A->ld] = T->u[i]; } Tcopy = new_tridiag(n); copy_tridiag(T, Tcopy); Acopy = clone_amatrix(A); Q = new_identity_amatrix(n, n); U = new_amatrix(n, n); (void) printf("Performing implicit QR iteration\n"); iter = sb_muleig_tridiag(T, Q, 8 * n); (void) printf(" %u iterations\n", iter); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, Q); (void) printf(" Orthogonality Q %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; copy_amatrix(false, Q, U); diageval_tridiag_amatrix(1.0, true, T, true, U); addmul_amatrix(-1.0, false, U, true, Q, A); error = normfrob_amatrix(A); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; (void) printf("Using default eigenvalue solver\n"); identity_amatrix(Q); muleig_tridiag(Tcopy, Q); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, Q); (void) printf(" Orthogonality Q %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; copy_amatrix(false, Q, U); diageval_tridiag_amatrix(1.0, true, Tcopy, true, U); addmul_amatrix(-1.0, false, U, true, Q, Acopy); error = normfrob_amatrix(Acopy); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : " NOT ")); if (error >= tolerance) problems++; del_amatrix(U); del_amatrix(Q); del_amatrix(Acopy); del_amatrix(A); del_tridiag(Tcopy); del_tridiag(T); /* ------------------------------------------------------------ * Testing self-adjoint matrix eigenvalue solver * ------------------------------------------------------------ */ (void) printf("==================================================\n" "Testing self-adjoint matrix eigenvalue solver\n" "==================================================\n" "Setting up random %u x %u self-adjoint matrix\n", n, n); A = new_amatrix(n, n); random_selfadjoint_amatrix(A); Acopy = new_amatrix(n, n); copy_amatrix(false, A, Acopy); lambda = new_realavector(n); Q = new_identity_amatrix(n, n); (void) printf("Performing implicit QR iteration\n"); iter = sb_eig_amatrix(A, lambda, Q, 8 * n); (void) printf(" %u iterations\n", iter); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, Q); (void) printf(" Orthogonality Q %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; U = new_amatrix(n, n); copy_amatrix(false, Q, U); copy_amatrix(false, Acopy, A); diageval_realavector_amatrix(1.0, true, lambda, true, U); addmul_amatrix(-1.0, false, U, true, Q, A); error = normfrob_amatrix(A); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; (void) printf("Using default eigenvalue solver\n"); copy_amatrix(false, Acopy, A); info = eig_amatrix(A, lambda, Q); assert(info == 0); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, Q); (void) printf(" Orthogonality Q %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; copy_amatrix(false, Q, U); diageval_realavector_amatrix(1.0, true, lambda, true, U); addmul_amatrix(-1.0, false, U, true, Q, Acopy); error = normfrob_amatrix(Acopy); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; del_amatrix(U); del_amatrix(Q); del_realavector(lambda); del_amatrix(Acopy); del_amatrix(A); /* ------------------------------------------------------------ * Testing bidiagonal SVD solver * ------------------------------------------------------------ */ (void) printf("==================================================\n" "Testing bidiagonal SVD solver\n" "==================================================\n" "Setting up bidiagonal %u x %u matrix\n", n, n); T = new_tridiag(n); for (i = 0; i < n; i++) T->d[i] = i + 1.0; for (i = 0; i < n - 1; i++) { T->l[i] = 1.0; T->u[i] = 0.0; } A = new_amatrix(n, n); clear_amatrix(A); for (i = 0; i < n; i++) A->a[i + i * A->ld] = T->d[i]; for (i = 0; i < n - 1; i++) A->a[(i + 1) + i * A->ld] = T->l[i]; Tcopy = new_tridiag(n); copy_tridiag(T, Tcopy); Acopy = new_amatrix(n, n); copy_amatrix(false, A, Acopy); U = new_identity_amatrix(n, n); Vt = new_identity_amatrix(n, n); (void) printf("Performing self-made implicit SVD iteration\n"); iter = sb_mulsvd_tridiag(T, U, Vt, 8 * n); (void) printf(" %u iterations\n", iter); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; diageval_tridiag_amatrix(1.0, true, T, true, U); addmul_amatrix(-1.0, false, U, false, Vt, A); error = normfrob_amatrix(A); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; (void) printf("Using default SVD solver\n"); copy_tridiag(Tcopy, T); identity_amatrix(U); identity_amatrix(Vt); mulsvd_tridiag(T, U, Vt); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; copy_amatrix(false, Acopy, A); diageval_tridiag_amatrix(1.0, true, T, true, U); addmul_amatrix(-1.0, false, U, false, Vt, A); error = normfrob_amatrix(A); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; del_amatrix(Vt); del_amatrix(U); del_amatrix(Acopy); del_tridiag(Tcopy); del_amatrix(A); del_tridiag(T); (void) printf("--------------------------------------------------\n" "Setting up random bidiagonal %u x %u matrix\n", n, n); T = new_tridiag(n); for (i = 0; i < n; i++) { T->d[i] = 2.0 * rand() / RAND_MAX - 1.0; } for (i = 0; i < n - 1; i++) { T->l[i] = 2.0 * rand() / RAND_MAX - 1.0; T->u[i] = 0.0; } A = new_amatrix(n, n); clear_amatrix(A); for (i = 0; i < n; i++) A->a[i + i * A->ld] = T->d[i]; for (i = 0; i < n - 1; i++) A->a[(i + 1) + i * A->ld] = T->l[i]; Tcopy = new_tridiag(n); copy_tridiag(T, Tcopy); Acopy = clone_amatrix(A); U = new_identity_amatrix(n, n); Vt = new_identity_amatrix(n, n); (void) printf("Performing implicit SVD iteration\n"); iter = sb_mulsvd_tridiag(T, U, Vt, 8 * n); (void) printf(" %u iterations\n", iter); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; diageval_tridiag_amatrix(1.0, true, T, true, U); addmul_amatrix(-1.0, false, U, false, Vt, A); error = normfrob_amatrix(A); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; (void) printf("Using default SVD solver\n"); copy_tridiag(Tcopy, T); copy_amatrix(false, Acopy, A); identity_amatrix(U); identity_amatrix(Vt); mulsvd_tridiag(T, U, Vt); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; diageval_tridiag_amatrix(1.0, true, T, true, U); addmul_amatrix(-1.0, false, U, false, Vt, A); error = normfrob_amatrix(A); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; del_amatrix(Vt); del_amatrix(U); del_amatrix(Acopy); del_tridiag(Tcopy); del_amatrix(A); del_tridiag(T); /* ------------------------------------------------------------ * Testing Golub-Kahan bidiagonalization * ------------------------------------------------------------ */ rows = 10; cols = 7; mid = UINT_MIN(rows, cols); (void) printf("==================================================\n" "Testing Golub-Kahan bidiagonalization\n" "==================================================\n" "Setting up random %u x %u matrix\n", rows, cols); A = new_amatrix(rows, cols); random_amatrix(A); Acopy = new_amatrix(rows, cols); copy_amatrix(false, A, Acopy); U = new_amatrix(rows, mid); Vt = new_amatrix(mid, cols); T = new_tridiag(mid); (void) printf("Bidiagonalizing\n"); bidiagonalize_amatrix(A, T, U, Vt); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; lowereval_tridiag_amatrix(1.0, true, T, true, U); addmul_amatrix(-1.0, false, U, false, Vt, Acopy); error = normfrob_amatrix(Acopy); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; del_tridiag(T); del_amatrix(Vt); del_amatrix(U); del_amatrix(Acopy); del_amatrix(A); rows = 8; cols = 15; mid = UINT_MIN(rows, cols); (void) printf("--------------------------------------------------\n" "Setting up %u x %u matrix\n", rows, cols); A = new_amatrix(rows, cols); random_amatrix(A); Acopy = new_amatrix(rows, cols); copy_amatrix(false, A, Acopy); U = new_amatrix(rows, mid); Vt = new_amatrix(mid, cols); T = new_tridiag(mid); (void) printf("Bidiagonalizing\n"); bidiagonalize_amatrix(A, T, U, Vt); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; lowereval_tridiag_amatrix(1.0, true, T, true, U); addmul_amatrix(-1.0, false, U, false, Vt, Acopy); error = normfrob_amatrix(Acopy); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; del_tridiag(T); del_amatrix(Vt); del_amatrix(U); del_amatrix(Acopy); del_amatrix(A); /* ------------------------------------------------------------ * Testing general SVD solver * ------------------------------------------------------------ */ (void) printf("==================================================\n" "Testing general SVD solver\n" "==================================================\n" "Setting up 3 x 4 matrix\n"); A = new_amatrix(3, 4); setentry_amatrix(A, 0, 0, 1.0); setentry_amatrix(A, 1, 0, 2.0); setentry_amatrix(A, 2, 0, 3.0); setentry_amatrix(A, 0, 1, 2.0); setentry_amatrix(A, 1, 1, 4.0); setentry_amatrix(A, 2, 1, 6.0); setentry_amatrix(A, 0, 2, 2.0); setentry_amatrix(A, 1, 2, 5.0); setentry_amatrix(A, 2, 2, 8.0); setentry_amatrix(A, 0, 3, 1.0); setentry_amatrix(A, 1, 3, 4.0); setentry_amatrix(A, 2, 3, 7.0); Acopy = new_amatrix(A->rows, A->cols); copy_amatrix(false, A, Acopy); U = new_identity_amatrix(3, 3); Vt = new_identity_amatrix(3, 4); sigma = new_realavector(3); work = new_avector(3 * 3); (void) printf("Running self-made SVD solver\n"); iter = sb_svd_amatrix(A, sigma, U, Vt, 24); (void) printf(" %u iterations\n", iter); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; diageval_realavector_amatrix(1.0, true, sigma, true, U); addmul_amatrix(-1.0, false, U, false, Vt, Acopy); error = normfrob_amatrix(Acopy); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; del_avector(work); del_realavector(sigma); del_amatrix(Vt); del_amatrix(U); del_amatrix(Acopy); del_amatrix(A); (void) printf("--------------------------------------------------\n" "Setting up 4 x 3 matrix\n"); A = new_amatrix(4, 3); setentry_amatrix(A, 0, 0, 1.0); setentry_amatrix(A, 0, 1, 2.0); setentry_amatrix(A, 0, 2, 3.0); setentry_amatrix(A, 1, 0, 2.0); setentry_amatrix(A, 1, 1, 4.0); setentry_amatrix(A, 1, 2, 6.0); setentry_amatrix(A, 2, 0, 2.0); setentry_amatrix(A, 2, 1, 5.0); setentry_amatrix(A, 2, 2, 8.0); setentry_amatrix(A, 3, 0, 1.0); setentry_amatrix(A, 3, 1, 4.0); setentry_amatrix(A, 3, 2, 7.0); Acopy = new_amatrix(A->rows, A->cols); copy_amatrix(false, A, Acopy); U = new_amatrix(4, 3); Vt = new_amatrix(3, 3); sigma = new_realavector(3); work = new_avector(3 * 3); (void) printf("Running self-made SVD solver\n"); iter = sb_svd_amatrix(A, sigma, U, Vt, 24); (void) printf(" %u iterations\n", iter); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality V %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; diageval_realavector_amatrix(1.0, true, sigma, true, U); addmul_amatrix(-1.0, false, U, false, Vt, Acopy); error = normfrob_amatrix(Acopy); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; del_avector(work); del_realavector(sigma); del_amatrix(Vt); del_amatrix(U); del_amatrix(Acopy); del_amatrix(A); (void) printf("--------------------------------------------------\n" "Setting up 4 x 3 matrix\n"); A = new_amatrix(4, 3); setentry_amatrix(A, 0, 0, 1.0); setentry_amatrix(A, 0, 1, 2.0); setentry_amatrix(A, 0, 2, 3.0); setentry_amatrix(A, 1, 0, 2.0); setentry_amatrix(A, 1, 1, 4.0); setentry_amatrix(A, 1, 2, 6.0); setentry_amatrix(A, 2, 0, 2.0); setentry_amatrix(A, 2, 1, 5.0); setentry_amatrix(A, 2, 2, 8.0); setentry_amatrix(A, 3, 0, 1.0); setentry_amatrix(A, 3, 1, 4.0); setentry_amatrix(A, 3, 2, 7.0); Acopy = clone_amatrix(A); U = new_amatrix(4, 3); Vt = new_amatrix(3, 3); sigma = new_realavector(3); work = new_avector(3 * 3); (void) printf("Running self-made SVD solver\n"); iter = sb_svd_amatrix(A, sigma, U, Vt, 24); (void) printf(" %u iterations\n", iter); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; diageval_realavector_amatrix(1.0, true, sigma, true, U); addmul_amatrix(-1.0, false, U, false, Vt, Acopy); error = normfrob_amatrix(Acopy); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; del_avector(work); del_realavector(sigma); del_amatrix(Vt); del_amatrix(U); del_amatrix(Acopy); del_amatrix(A); rows = 9; cols = 7; mid = UINT_MIN(rows, cols); (void) printf("--------------------------------------------------\n" "Setting up random %u x %u matrix\n", rows, cols); A = new_amatrix(rows, cols); random_amatrix(A); Acopy = new_amatrix(A->rows, A->cols); copy_amatrix(false, A, Acopy); U = new_amatrix(rows, mid); Vt = new_amatrix(mid, cols); sigma = new_realavector(mid); work = new_avector(3 * mid); (void) printf("Running self-made SVD solver\n"); iter = sb_svd_amatrix(A, sigma, U, Vt, 10 * mid); (void) printf(" %u iterations\n", iter); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; diageval_realavector_amatrix(1.0, true, sigma, true, U); addmul_amatrix(-1.0, false, U, false, Vt, Acopy); error = normfrob_amatrix(Acopy); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; del_avector(work); del_realavector(sigma); del_amatrix(Vt); del_amatrix(U); del_amatrix(Acopy); del_amatrix(A); rows = 10; cols = 6; mid = UINT_MIN(rows, cols); (void) printf("--------------------------------------------------\n" "Setting up random %u x %u matrix\n", rows, cols); A = new_amatrix(rows, cols); random_amatrix(A); Acopy = new_amatrix(A->rows, A->cols); copy_amatrix(false, A, Acopy); U = new_amatrix(rows, mid); Vt = new_amatrix(mid, cols); sigma = new_realavector(mid); work = new_avector(3 * mid); (void) printf("Running self-made SVD solver\n"); iter = sb_svd_amatrix(A, sigma, U, Vt, 10 * mid); (void) printf(" %u iterations\n", iter); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; copy_amatrix(false, Acopy, A); diageval_realavector_amatrix(1.0, true, sigma, true, U); addmul_amatrix(-1.0, false, U, false, Vt, A); error = normfrob_amatrix(A); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; (void) printf("Running default SVD solver\n"); copy_amatrix(false, Acopy, A); svd_amatrix(A, sigma, U, Vt); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; copy_amatrix(false, Acopy, A); diageval_realavector_amatrix(1.0, true, sigma, true, U); addmul_amatrix(-1.0, false, U, false, Vt, A); error = normfrob_amatrix(A); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; del_avector(work); del_realavector(sigma); del_amatrix(Vt); del_amatrix(U); del_amatrix(Acopy); del_amatrix(A); rows = 7; cols = 13; mid = UINT_MIN(rows, cols); (void) printf("--------------------------------------------------\n" "Setting up random %u x %u matrix\n", rows, cols); A = new_amatrix(rows, cols); random_amatrix(A); Acopy = new_amatrix(A->rows, A->cols); copy_amatrix(false, A, Acopy); U = new_amatrix(rows, mid); Vt = new_amatrix(mid, cols); sigma = new_realavector(mid); work = new_avector(3 * mid); (void) printf("Running self-made SVD solver\n"); iter = sb_svd_amatrix(A, sigma, U, Vt, 10 * mid); (void) printf(" %u iterations\n", iter); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; copy_amatrix(false, Acopy, A); diageval_realavector_amatrix(1.0, true, sigma, true, U); addmul_amatrix(-1.0, false, U, false, Vt, A); error = normfrob_amatrix(A); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; (void) printf("Running default SVD solver\n"); copy_amatrix(false, Acopy, A); svd_amatrix(A, sigma, U, Vt); (void) printf("Checking accuracy\n"); error = check_ortho_amatrix(false, U); (void) printf(" Orthogonality U %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; error = check_ortho_amatrix(true, Vt); (void) printf(" Orthogonality Vt %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; copy_amatrix(false, Acopy, A); diageval_realavector_amatrix(1.0, true, sigma, true, U); addmul_amatrix(-1.0, false, U, false, Vt, A); error = normfrob_amatrix(A); (void) printf(" Accuracy %g, %sokay\n", error, (error < tolerance ? "" : "NOT ")); if (error >= tolerance) problems++; del_avector(work); del_realavector(sigma); del_amatrix(Vt); del_amatrix(U); del_amatrix(Acopy); del_amatrix(A); printf("----------------------------------------\n" " %u matrices and\n" " %u vectors still active\n" " %u errors found\n", getactives_amatrix(), getactives_avector(), problems); return problems; }
pcluster build_pca_cluster(pclustergeometry cf, uint size, uint * idx, uint clf) { const uint dim = cf->dim; pamatrix C, Q; pavector v; prealavector lambda; real *x, *y; real w; uint i, j, k, size0, size1; pcluster t; assert(size > 0); size0 = 0; size1 = 0; if (size > clf) { x = allocreal(dim); y = allocreal(dim); /* determine weight of current cluster */ w = 0.0; for (i = 0; i < size; ++i) { w += cf->w[idx[i]]; } w = 1.0 / w; for (j = 0; j < dim; ++j) { x[j] = 0.0; } /* determine center of mass */ for (i = 0; i < size; ++i) { for (j = 0; j < dim; ++j) { x[j] += cf->w[idx[i]] * cf->x[idx[i]][j]; } } for (j = 0; j < dim; ++j) { x[j] *= w; } C = new_zero_amatrix(dim, dim); Q = new_zero_amatrix(dim, dim); lambda = new_realavector(dim); /* setup covariance matrix */ for (i = 0; i < size; ++i) { for (j = 0; j < dim; ++j) { y[j] = cf->x[idx[i]][j] - x[j]; } for (j = 0; j < dim; ++j) { for (k = 0; k < dim; ++k) { C->a[j + k * C->ld] += cf->w[idx[i]] * y[j] * y[k]; } } } /* get eigenvalues and eigenvectors of covariance matrix */ eig_amatrix(C, lambda, Q); /* get eigenvector from largest eigenvalue */ v = new_avector(0); init_column_avector(v, Q, dim - 1); /* separate cluster with v as separation-plane */ for (i = 0; i < size; ++i) { /* x_i - X */ for (j = 0; j < dim; ++j) { y[j] = cf->x[idx[i]][j] - x[j]; } /* <y,v> */ w = 0.0; for (j = 0; j < dim; ++j) { w += y[j] * v->v[j]; } if (w >= 0.0) { j = idx[i]; idx[i] = idx[size0]; idx[size0] = j; size0++; } else { size1++; } } assert(size0 + size1 == size); del_amatrix(Q); del_amatrix(C); del_realavector(lambda); del_avector(v); freemem(x); freemem(y); /* recursion */ if (size0 > 0) { if (size1 > 0) { t = new_cluster(size, idx, 2, cf->dim); t->son[0] = build_pca_cluster(cf, size0, idx, clf); t->son[1] = build_pca_cluster(cf, size1, idx + size0, clf); update_bbox_cluster(t); } else { t = new_cluster(size, idx, 1, cf->dim); t->son[0] = build_pca_cluster(cf, size0, idx, clf); update_bbox_cluster(t); } } else { assert(size1 > 0); t = new_cluster(size, idx, 1, cf->dim); t->son[0] = build_pca_cluster(cf, size1, idx, clf); update_bbox_cluster(t); } } else { t = new_cluster(size, idx, 0, cf->dim); update_support_bbox_cluster(cf, t); } update_cluster(t); return t; }