Пример #1
0
void
add_rkmatrix_uniform(pcrkmatrix r, puniform unew)
{
  amatrix   tmp1, tmp2, tmp3, tmp4;
  pamatrix  At, Bt, Ac, Bc;
  uint      k;

  assert(r->A.cols == r->B.cols);

  k = r->A.cols;

  At = init_amatrix(&tmp1, unew->rb->kbranch, k);
  compress_clusterbasis_amatrix(unew->rb, &r->A, At);

  Bt = init_amatrix(&tmp2, unew->cb->kbranch, k);
  compress_clusterbasis_amatrix(unew->cb, &r->B, Bt);

  Ac = init_sub_amatrix(&tmp3, At, unew->rb->k, 0, k, 0);
  Bc = init_sub_amatrix(&tmp4, Bt, unew->cb->k, 0, k, 0);

  addmul_amatrix(1.0, false, Ac, true, Bc, &unew->S);

  uninit_amatrix(Bc);
  uninit_amatrix(Ac);
  uninit_amatrix(Bt);
  uninit_amatrix(At);
}
Пример #2
0
void
basisproduct_clusteroperator(pcclusterbasis cb1, pcclusterbasis cb2,
			     pclusteroperator pr)
{
  pamatrix  X, Xt;
  amatrix   tmp1, tmp2;
  uint      i;

  assert(cb1->t == pr->t);
  assert(cb2->t == pr->t);

  resize_clusteroperator(pr, cb1->k, cb2->k);

  if (pr->sons > 0) {
    assert(cb1->sons == pr->sons);
    assert(cb2->sons == pr->sons);

    for (i = 0; i < pr->sons; i++)
      basisproduct_clusteroperator(cb1->son[i], cb2->son[i], pr->son[i]);

    clear_amatrix(&pr->C);
    for (i = 0; i < pr->sons; i++) {
      X = init_amatrix(&tmp1, cb1->son[i]->k, cb2->k);
      clear_amatrix(X);
      addmul_amatrix(1.0, false, &pr->son[i]->C, false, &cb2->son[i]->E, X);
      addmul_amatrix(1.0, true, &cb1->son[i]->E, false, X, &pr->C);
      uninit_amatrix(X);
    }
  }
  else {
    if (cb1->sons == 0) {
      if (cb2->sons == 0) {
	clear_amatrix(&pr->C);
	addmul_amatrix(1.0, true, &cb1->V, false, &cb2->V, &pr->C);
      }
      else {
	Xt = init_amatrix(&tmp1, cb2->kbranch, cb1->k);
	compress_clusterbasis_amatrix(cb2, &cb1->V, Xt);
	X = init_sub_amatrix(&tmp2, Xt, cb2->k, 0, cb1->k, 0);
	copy_amatrix(true, X, &pr->C);
	uninit_amatrix(X);
	uninit_amatrix(Xt);
      }
    }
    else {
      assert(cb2->sons == 0);	/* Could be generalized */

      Xt = init_amatrix(&tmp1, cb1->kbranch, cb2->k);
      compress_clusterbasis_amatrix(cb1, &cb2->V, Xt);
      X = init_sub_amatrix(&tmp2, Xt, cb1->k, 0, cb2->k, 0);
      copy_amatrix(false, X, &pr->C);
      uninit_amatrix(X);
      uninit_amatrix(Xt);
    }
  }
}
Пример #3
0
static void
check_uppereval(bool unit, bool atrans, pcamatrix a, bool xtrans)
{
    pamatrix  a2, x, b, b2;
    amatrix   a2tmp, xtmp, btmp;
    real      error;

    a2 = init_amatrix(&a2tmp, a->rows, a->cols);
    if (atrans)
        copy_lower_amatrix(a, unit, a2);
    else
        copy_upper_amatrix(a, unit, a2);

    x = (atrans ? init_amatrix(&xtmp, a->rows, a->rows) :
         init_amatrix(&xtmp, a->cols, a->cols));
    random_amatrix(x);

    b = (atrans ?
         (xtrans ? init_amatrix(&btmp, a->rows, UINT_MAX(a->cols, a->rows)) :
          init_amatrix(&btmp, UINT_MAX(a->rows, a->cols), a->rows)) :
         (xtrans ? init_amatrix(&btmp, a->cols, UINT_MAX(a->cols, a->rows)) :
          init_amatrix(&btmp, UINT_MAX(a->rows, a->cols), a->cols)));

    copy_sub_amatrix(false, x, b);
    triangulareval_amatrix(atrans, unit, atrans, a, xtrans, b);

    if (xtrans)
        addmul_amatrix(-1.0, false, x, !atrans, a2, b);
    else
        addmul_amatrix(-1.0, atrans, a2, false, x, b);

    uninit_amatrix(a2);
    b2 = (atrans ?
          (xtrans ? init_sub_amatrix(&a2tmp, b, b->rows, 0, a->cols, 0) :
           init_sub_amatrix(&a2tmp, b, a->cols, 0, b->cols, 0)) :
          (xtrans ? init_sub_amatrix(&a2tmp, b, b->rows, 0, a->rows, 0) :
           init_sub_amatrix(&a2tmp, b, a->rows, 0, b->cols, 0)));

    error = norm2_amatrix(b2) / norm2_amatrix(x);

    (void) printf("Checking uppereval(unit=%s, atrans=%s, xtrans=%s)\n"
                  "  Accuracy %g, %sokay\n", (unit ? "tr" : "fl"),
                  (atrans ? "tr" : "fl"), (xtrans ? "tr" : "fl"), error,
                  (error < tolerance ? "" : "    NOT "));
    if (error >= tolerance)
        problems++;

    uninit_amatrix(b2);
    uninit_amatrix(b);
    uninit_amatrix(x);
}
Пример #4
0
void
coarsen_hmatrix(phmatrix G, ptruncmode tm, real eps, bool recursive)
{
  uint      rsons = G->rsons;
  uint      csons = G->csons;

  phmatrix  son;
  prkmatrix R;
  pamatrix  A, B;
  amatrix   T, S;
  uint      i, j, leafs, ranksum, rankoffset, rowoffset, coloffset, rank;
  size_t    sizeold, sizenew;

  leafs = 0;

  /* recursion */
  if (rsons * csons > 0) {
    for (j = 0; j < csons; ++j) {
      for (i = 0; i < rsons; ++i) {
	son = G->son[i + j * rsons];
	if (recursive == true) {
	  coarsen_hmatrix(son, tm, eps, recursive);
	}
	leafs += son->rsons * son->csons;
      }
    }

    update_hmatrix(G);
  }
  else {
    /* matrix is a leaf -> northing to do */
    return;
  }

  if (leafs > 0) {
    /* matrix has sons which are not leafs  -> nothing to do */
    return;
  }
  else {
    if (G->rc == G->cc) {
      return;
    }

    /* determine ranksum and size of sons */
    ranksum = 0;
    sizeold = 0;
    for (j = 0; j < csons; ++j) {
      for (i = 0; i < rsons; ++i) {
	son = G->son[i + j * rsons];
	if (son->r) {
	  ranksum += son->r->k;
	  sizeold += getsize_rkmatrix(son->r);
	}
	else {
	  assert(son->f != NULL);
	  ranksum += son->f->cols;
	  sizeold += getsize_amatrix(son->f);
	}
      }
    }

    /* new rank-k-matrix */
    R = new_rkmatrix(G->rc->size, G->cc->size, ranksum);
    A = &R->A;
    B = &R->B;
    clear_amatrix(A);
    clear_amatrix(B);

    /* copy sons into a big rank-k-matrix */
    rankoffset = 0;
    coloffset = 0;
    for (j = 0; j < csons; ++j) {
      rowoffset = 0;
      for (i = 0; i < rsons; ++i) {
	son = G->son[i + j * rsons];
	rank = son->r ? son->r->k : son->f->cols;

	init_sub_amatrix(&T, A, son->rc->size, rowoffset, rank, rankoffset);
	init_sub_amatrix(&S, B, son->cc->size, coloffset, rank, rankoffset);

	if (son->r) {
	  copy_amatrix(false, &(son->r->A), &T);
	  copy_amatrix(false, &(son->r->B), &S);
	}
	else {
	  copy_amatrix(false, son->f, &T);
	  identity_amatrix(&S);
	}

	rankoffset += rank;
	rowoffset += son->rc->size;
	uninit_amatrix(&T);
	uninit_amatrix(&S);
      }
      coloffset += G->son[j * rsons]->cc->size;
    }

    /* compression */
    trunc_rkmatrix(tm, eps, R);

    sizenew = getsize_rkmatrix(R);

    /* use new rank-k-matrix or discard */
    if (sizenew < sizeold) {
      for (j = 0; j < csons; ++j) {
	for (i = 0; i < rsons; ++i) {
	  unref_hmatrix(G->son[i + j * rsons]);
	}
      }

      G->rsons = 0;
      G->csons = 0;
      freemem(G->son);
      G->son = NULL;
      G->f = NULL;
      G->r = R;
      G->desc = 1;
    }
    else {
      del_rkmatrix(R);
    }

  }
}