Beispiel #1
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);

}
Beispiel #2
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;
}