Esempio n. 1
0
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);
	}
}
Esempio n. 2
0
/* 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);

}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}