void add_projected_uniform(pcuniform u, pcclusteroperator ro, pcclusteroperator co, puniform unew) { amatrix tmp; pamatrix XS; if (u->rb == unew->rb) { if (u->cb == unew->cb) add_amatrix(1.0, false, &u->S, &unew->S); else { assert(co->krow == unew->cb->k); assert(co->kcol == u->cb->k); addmul_amatrix(1.0, false, &u->S, true, &co->C, &unew->S); } } else { if (u->cb == unew->cb) { assert(ro->krow == unew->rb->k); assert(ro->kcol == u->rb->k); addmul_amatrix(1.0, false, &ro->C, false, &u->S, &unew->S); } else { assert(ro->krow == unew->rb->k); assert(ro->kcol == u->rb->k); assert(co->krow == unew->cb->k); assert(co->kcol == u->cb->k); XS = init_amatrix(&tmp, unew->rb->k, u->cb->k); clear_amatrix(XS); addmul_amatrix(1.0, false, &ro->C, false, &u->S, XS); addmul_amatrix(1.0, false, XS, true, &co->C, &unew->S); uninit_amatrix(XS); } } }
static void check_triangularsolve(bool lower, bool unit, bool atrans, pcamatrix a, bool xtrans) { uint n = a->rows; amatrix xtmp, btmp; pamatrix x, b; avector xvtmp, bvtmp; pavector xv, bv; real error; assert(n == a->cols); /* * amatrix */ x = init_amatrix(&xtmp, n, n); random_amatrix(x); b = init_zero_amatrix(&btmp, n, n); if (xtrans) addmul_amatrix(1.0, false, x, !atrans, a, b); else addmul_amatrix(1.0, atrans, a, false, x, b); triangularsolve_amatrix(lower, unit, atrans, a, xtrans, b); add_amatrix(-1.0, false, x, b); error = norm2_amatrix(b) / norm2_amatrix(x); (void) printf("Checking amatrix triangularsolve\n" " (lower=%s, unit=%s, atrans=%s, xtrans=%s)\n" " Accuracy %g, %sokay\n", (lower ? "tr" : "fl"), (unit ? "tr" : "fl"), (atrans ? "tr" : "fl"), (xtrans ? "tr" : "fl"), error, (IS_IN_RANGE(0.0, error, 1.0e-14) ? "" : " NOT ")); if (!IS_IN_RANGE(0.0, error, 1.0e-14)) problems++; copy_amatrix(false, x, b); triangulareval_amatrix(lower, unit, atrans, a, xtrans, b); triangularsolve_amatrix(lower, unit, atrans, a, xtrans, b); add_amatrix(-1.0, false, x, b); error = norm2_amatrix(b) / norm2_amatrix(x); (void) printf("Checking amatrix triangulareval/triangularsolve\n" " (lower=%s, unit=%s, atrans=%s, xtrans=%s):\n" " Accuracy %g, %sokay\n", (lower ? "tr" : "fl"), (unit ? "tr" : "fl"), (atrans ? "tr" : "fl"), (xtrans ? "tr" : "fl"), error, (IS_IN_RANGE(0.0, error, 1.0e-14) ? "" : " NOT ")); if (!IS_IN_RANGE(0.0, error, 1.0e-14)) problems++; /* * avector */ xv = init_avector(&xvtmp, n); random_avector(xv); bv = init_avector(&bvtmp, n); clear_avector(bv); if (atrans) { addevaltrans_amatrix_avector(1.0, a, xv, bv); } else { addeval_amatrix_avector(1.0, a, xv, bv); } triangularsolve_amatrix_avector(lower, unit, atrans, a, bv); add_avector(-1.0, xv, bv); error = norm2_avector(bv) / norm2_avector(xv); (void) printf("Checking avector triangularsolve\n" " (lower=%s, unit=%s, atrans=%s)\n" " Accuracy %g, %sokay\n", (lower ? "tr" : "fl"), (unit ? "tr" : "fl"), (atrans ? "tr" : "fl"), error, (IS_IN_RANGE(0.0, error, 1.0e-14) ? "" : " NOT ")); if (!IS_IN_RANGE(0.0, error, 1.0e-14)) problems++; copy_avector(xv, bv); triangulareval_amatrix_avector(lower, unit, atrans, a, bv); triangularsolve_amatrix_avector(lower, unit, atrans, a, bv); add_avector(-1.0, xv, bv); error = norm2_avector(bv) / norm2_avector(xv); (void) printf("Checking avector triangulareval/triangularsolve\n" " (lower=%s, unit=%s, atrans=%s):\n" " Accuracy %g, %sokay\n", (lower ? "tr" : "fl"), (unit ? "tr" : "fl"), (atrans ? "tr" : "fl"), error, (IS_IN_RANGE(0.0, error, 1.0e-14) ? "" : " NOT ")); if (!IS_IN_RANGE(0.0, error, 1.0e-14)) problems++; uninit_amatrix(b); uninit_amatrix(x); uninit_avector(bv); uninit_avector(xv); }