// compute ||A - Q*T*Q.T|| int test_mult_trd(int M, int N, int lb, int verbose, int flags) { armas_x_dense_t A0, A1, tau0, T0, T1, e1, e2, d1, d2; armas_conf_t conf = *armas_conf_default(); int ok; DTYPE nrm; char *uplo = flags & ARMAS_UPPER ? "UPPER" : "LOWER"; armas_x_init(&A0, N, N); armas_x_init(&A1, N, N); armas_x_init(&T0, N, N); armas_x_init(&T1, N, N); armas_x_init(&tau0, N, 1); // set source data armas_x_set_values(&A0, unitrand, flags); armas_x_mcopy(&A1, &A0); conf.lb = lb; armas_x_trdreduce(&A0, &tau0, flags, &conf); // make tridiagonal matrix T0 armas_x_diag(&d1, &A0, 0); armas_x_diag(&d2, &T0, 0); armas_x_mcopy(&d2, &d1); if (flags & ARMAS_UPPER) { armas_x_diag(&e1, &A0, 1); } else { armas_x_diag(&e1, &A0, -1); } // copy off-diagonals armas_x_diag(&e2, &T0, 1); armas_x_mcopy(&e2, &e1); armas_x_diag(&e2, &T0, -1); armas_x_mcopy(&e2, &e1); // compute Q*T*Q.T armas_x_trdmult(&T0, &A0, &tau0, flags|ARMAS_LEFT, &conf); armas_x_trdmult(&T0, &A0, &tau0, flags|ARMAS_RIGHT|ARMAS_TRANS, &conf); // make result triangular (original matrix) armas_x_make_trm(&T0, flags); nrm = rel_error((DTYPE *)0, &T0, &A1, ARMAS_NORM_ONE, ARMAS_NONE, &conf); ok = isFINE(nrm, N*__ERROR); printf("%s: [%s] Q*T*Q.T == A\n", PASS(ok), uplo); if (verbose > 0) { printf(" || rel error ||: %e [%d]\n", nrm, ndigits(nrm)); } armas_x_release(&A0); armas_x_release(&A1); armas_x_release(&tau0); armas_x_release(&T0); armas_x_release(&T1); return ok; }
int test_reduce(int M, int N, int lb, int verbose, int flags) { armas_x_dense_t A0, A1, tau0, tau1; armas_conf_t conf = *armas_conf_default(); int ok; char uplo = flags & ARMAS_LOWER ? 'L' : 'U'; DTYPE n0, n1; armas_x_init(&A0, N, N); armas_x_init(&A1, N, N); armas_x_init(&tau0, N, 1); armas_x_init(&tau1, N, 1); // set source data armas_x_set_values(&A0, unitrand, flags); armas_x_mcopy(&A1, &A0); conf.lb = 0; armas_x_trdreduce(&A0, &tau0, flags, &conf); conf.lb = lb; armas_x_trdreduce(&A1, &tau1, flags, &conf); n0 = rel_error((DTYPE *)0, &A0, &A1, ARMAS_NORM_ONE, ARMAS_NONE, &conf); n1 = rel_error((DTYPE *)0, &tau0, &tau1, ARMAS_NORM_TWO, ARMAS_NONE, &conf); ok = isFINE(n0, N*__ERROR); printf("%s: unblk.TRD(A,%c) == blk.TRD(A,%c)\n", PASS(ok), uplo, uplo); if (verbose > 0) { printf(" || error.TRD(A,%c)||: %e [%d]\n", uplo, n0, ndigits(n0)); printf(" || error.tau|| : %e [%d]\n", n1, ndigits(n1)); } armas_x_release(&A0); armas_x_release(&A1); armas_x_release(&tau0); armas_x_release(&tau1); return ok; }
void page_rank(double *r, double *r_pre, int *num_out_links, int *num_in_links, int nodecount, node_t *nodehead, double damp_const) { int iterationcount = 0; do { ++iterationcount; vec_cp(r, r_pre, nodecount); for (int i = 0; i < nodecount; ++i) { r[i] = 0; for (int j = 0; j < nodehead[i].num_in_links; ++j) { r[i] += r_pre[nodehead[i].inlinks[j]] / num_out_links[nodehead[i].inlinks[j]]; } r[i] *= DAMPING_FACTOR; r[i] += damp_const; } } while(rel_error(r, r_pre, nodecount) >= EPSILON); }
/* ----------------------------------------------------------------------------------- * Test 5: unblk.Q(rq(A)) == blk.Q(rq(A)) * OK: ||unblk.Q(rq(A)) - blk.Q(rq(A))||_1 ~~ n*eps */ int test_build(int M, int N, int K, int lb, int verbose) { char ct = N == K ? 'N' : 'K'; armas_x_dense_t A0, A1, tau0; int ok; DTYPE n0; armas_conf_t conf = *armas_conf_default(); armas_x_init(&A0, M, N); armas_x_init(&A1, M, N); armas_x_init(&tau0, imin(M, N), 1); // set source data armas_x_set_values(&A0, unitrand, ARMAS_ANY); // factorize conf.lb = lb; armas_x_rqfactor(&A0, &tau0, &conf); armas_x_mcopy(&A1, &A0); // compute Q = buildQ(rq(A)) conf.lb = 0; armas_x_rqbuild(&A0, &tau0, K, &conf); conf.lb = lb; armas_x_rqbuild(&A1, &tau0, K, &conf); // ||A1 - A0||/||A0|| n0 = rel_error((DTYPE *)0, &A1, &A0, ARMAS_NORM_ONE, ARMAS_NONE, &conf); ok = isOK(n0, N); printf("%s: unblk.Q(rq(A),%c) == blk.Q(rq(A),%c)\n", PASS(ok), ct, ct); if (verbose > 0) { printf(" || rel_error ||_1: %e [%d]\n", n0, ndigits(n0)); } armas_x_release(&A0); armas_x_release(&A1); armas_x_release(&tau0); return ok; }
int main(int argc, char **argv) { armas_conf_t conf; armas_x_dense_t B0, A, B; int ok, opt; int N = 301; int verbose = 1; int fails = 0; DTYPE alpha = 1.0; DTYPE n0, n1; while ((opt = getopt(argc, argv, "vC:")) != -1) { switch (opt) { case 'v': verbose++; break; case 'C': Aconstant = STRTOF(optarg); break; default: fprintf(stderr, "usage: trsm [-P nproc] [size]\n"); exit(1); } } if (optind < argc) N = atoi(argv[optind]); conf = *armas_conf_default(); armas_x_init(&A, N, N); armas_x_init(&B, N, N); armas_x_init(&B0, N, N); // Upper triangular matrix armas_x_set_values(&A, one, ARMAS_UPPER); if (N < 10) { printf("A:\n"); armas_x_printf(stdout, "%8.1e", &A); } armas_x_set_values(&B, one, ARMAS_NULL); armas_x_mcopy(&B0, &B); armas_x_mult_trm(&B, alpha, &A, ARMAS_UPPER|ARMAS_LEFT, &conf); if (N < 10) { printf("A*B:\n"); armas_x_printf(stdout, "%8.1e", &B); } armas_x_solve_trm(&B, alpha, &A, ARMAS_UPPER|ARMAS_LEFT, &conf); if (N < 10) { printf("A.-1*B:\n"); armas_x_printf(stdout, "%8.1e", &B); } n0 = rel_error(&n1, &B, &B0, ARMAS_NORM_ONE, ARMAS_NONE, &conf); ok = n0 == 0.0 || isOK(n0, N) ? 1 : 0; printf("%6s: B = solve_trm(mult_trm(B, A, L|U|N), A, L|U|N)\n", PASS(ok)); if (verbose > 0) { printf(" || rel error || : %e, [%d]\n", n0, ndigits(n0)); } fails += 1 - ok; armas_x_set_values(&B, one, ARMAS_NULL); armas_x_mcopy(&B0, &B); armas_x_mult_trm(&B, alpha, &A, ARMAS_UPPER|ARMAS_RIGHT, &conf); armas_x_solve_trm(&B, alpha, &A, ARMAS_UPPER|ARMAS_RIGHT, &conf); n0 = rel_error(&n1, &B, &B0, ARMAS_NORM_ONE, ARMAS_NONE, &conf); ok = n0 == 0.0 || isOK(n0, N) ? 1 : 0; printf("%6s: B = solve_trm(mult_trm(B, A, R|U|N), A, R|U|N)\n", PASS(ok)); if (verbose > 0) { printf(" || rel error || : %e, [%d]\n", n0, ndigits(n0)); } fails += 1 - ok; armas_x_set_values(&B, one, ARMAS_NULL); armas_x_mcopy(&B0, &B); armas_x_mult_trm(&B, alpha, &A, ARMAS_UPPER|ARMAS_LEFT|ARMAS_TRANSA, &conf); armas_x_solve_trm(&B, alpha, &A, ARMAS_UPPER|ARMAS_LEFT|ARMAS_TRANSA, &conf); n0 = rel_error(&n1, &B, &B0, ARMAS_NORM_ONE, ARMAS_NONE, &conf); ok = n0 == 0.0 || isOK(n0, N) ? 1 : 0; printf("%6s: B = solve_trm(mult_trm(B, A, L|U|T), A, L|U|T)\n", PASS(ok)); if (verbose > 0) { printf(" || rel error || : %e, [%d]\n", n0, ndigits(n0)); } fails += 1 - ok; armas_x_set_values(&B, one, ARMAS_NULL); armas_x_mcopy(&B0, &B); armas_x_mult_trm(&B, alpha, &A, ARMAS_UPPER|ARMAS_RIGHT|ARMAS_TRANSA, &conf); armas_x_solve_trm(&B, alpha, &A, ARMAS_UPPER|ARMAS_RIGHT|ARMAS_TRANSA, &conf); n0 = rel_error(&n1, &B, &B0, ARMAS_NORM_ONE, ARMAS_NONE, &conf); ok = n0 == 0.0 || isOK(n0, N) ? 1 : 0; printf("%6s: B = solve_trm(mult_trm(B, A, R|U|T), A, R|U|T)\n", PASS(ok)); if (verbose > 0) { printf(" || rel error || : %e, [%d]\n", n0, ndigits(n0)); } fails += 1 - ok; // Lower triangular matrix armas_x_set_values(&A, one, ARMAS_LOWER); armas_x_set_values(&B, one, ARMAS_NULL); armas_x_mcopy(&B0, &B); armas_x_mult_trm(&B, alpha, &A, ARMAS_LOWER|ARMAS_LEFT, &conf); armas_x_solve_trm(&B, alpha, &A, ARMAS_LOWER|ARMAS_LEFT, &conf); n0 = rel_error(&n1, &B, &B0, ARMAS_NORM_ONE, ARMAS_NONE, &conf); ok = n0 == 0.0 || isOK(n0, N) ? 1 : 0; printf("%6s: B = solve_trm(mult_trm(B, A, L|L|N), A, L|L|N)\n", PASS(ok)); if (verbose > 0) { printf(" || rel error || : %e, [%d]\n", n0, ndigits(n0)); } fails += 1 - ok; armas_x_set_values(&B, one, ARMAS_NULL); armas_x_mcopy(&B0, &B); armas_x_mult_trm(&B, alpha, &A, ARMAS_LOWER|ARMAS_RIGHT, &conf); armas_x_solve_trm(&B, alpha, &A, ARMAS_LOWER|ARMAS_RIGHT, &conf); n0 = rel_error(&n1, &B, &B0, ARMAS_NORM_ONE, ARMAS_NONE, &conf); ok = n0 == 0.0 || isOK(n0, N) ? 1 : 0; printf("%6s: B = solve_trm(mult_trm(B, A, R|L|N), A, R|L|N)\n", PASS(ok)); if (verbose > 0) { printf(" || rel error || : %e, [%d]\n", n0, ndigits(n0)); } fails += 1 - ok; armas_x_set_values(&B, one, ARMAS_NULL); armas_x_mcopy(&B0, &B); armas_x_mult_trm(&B, alpha, &A, ARMAS_LOWER|ARMAS_LEFT|ARMAS_TRANSA, &conf); armas_x_solve_trm(&B, alpha, &A, ARMAS_LOWER|ARMAS_LEFT|ARMAS_TRANSA, &conf); n0 = rel_error(&n1, &B, &B0, ARMAS_NORM_ONE, ARMAS_NONE, &conf); ok = n0 == 0.0 || isOK(n0, N) ? 1 : 0; printf("%6s: B = solve_trm(mult_trm(B, A, L|L|T), A, L|L|T)\n", PASS(ok)); if (verbose > 0) { printf(" || rel error || : %e, [%d]\n", n0, ndigits(n0)); } fails += 1 - ok; armas_x_set_values(&B, one, ARMAS_NULL); armas_x_mcopy(&B0, &B); armas_x_mult_trm(&B, alpha, &A, ARMAS_LOWER|ARMAS_RIGHT|ARMAS_TRANSA, &conf); armas_x_solve_trm(&B, alpha, &A, ARMAS_LOWER|ARMAS_RIGHT|ARMAS_TRANSA, &conf); n0 = rel_error(&n1, &B, &B0, ARMAS_NORM_ONE, ARMAS_NONE, &conf); ok = n0 == 0.0 || isOK(n0, N) ? 1 : 0; printf("%6s: B = solve_trm(mult_trm(B, A, R|L|T), A, R|L|T)\n", PASS(ok)); if (verbose > 0) { printf(" || rel error || : %e, [%d]\n", n0, ndigits(n0)); } fails += 1 - ok; test_left_right(N, verbose); exit(fails); }
bool test_one_case (RealType unrounded ,RealType expected ) { RealType observed = roundFDL(unrounded); max_prec_real abs_error = detail::perform_fabs(observed - expected); // Nonstandardly define relative error in terms of // o(bserved) and e(xpected) as // |(o-e)/e| if e nonzero, else // |(o-e)/o| if o nonzero, else // zero // in order to avoid division by zero. max_prec_real rel_error(0.0); if(max_prec_real(0.0) != expected) { rel_error = detail::perform_fabs ( (observed - max_prec_real(expected)) / expected ); } else if(max_prec_real(0.0) != observed) { rel_error = detail::perform_fabs ( (observed - max_prec_real(expected)) / observed ); } // In general, we can't hope for the relative error to be less than // epsilon for the floating-point type being rounded. Suppose a // variable gets its value from a floating literal; 2.13.3/1 says // "If the scaled value is in the range of representable values // for its type, the result is the scaled value if representable, // else the larger or smaller representable value nearest the // scaled value, chosen in an implementation-defined manner." // The compiler might map a literal like .005 to some value at // compile time, but at run time, the result of even a simple store // operation may yield a different value depending on the rounding // direction, as can an expression like '5.0 / 1000.0'. C99 (but // not C++) requires evaluation of non-static floating-point // constants as if at runtime [F.7.4/1]. max_prec_real tolerance = std::numeric_limits<RealType>::epsilon(); // All tests pass even with a tolerance of zero, for // - candidate libmingwex as 20080603Z, and // - glibc for amd64, as reported here: // http://lists.nongnu.org/archive/html/lmi/2008-06/msg00019.html // Code to support a more liberal tolerance is retained in case // it someday proves useful on some other platform. // bool error_is_within_tolerance = rel_error <= tolerance; bool error_is_within_tolerance = observed == expected; if(!error_is_within_tolerance) { std::cout << '\n'; // Use enough precision to map the base-ten scientific // representation back to binary without loss of accuracy. // Cf. C99 5.2.4.2.2/8 (DECIMAL_DIG). int nbits = std::numeric_limits<RealType>::digits; std::streamsize old_precision = std::cout.precision (1 + static_cast<int>(std::ceil(std::log10(std::pow(2.0, nbits)))) ); std::ios_base::fmtflags old_flags = std::cout.flags(); std::cout << "Rounding " << get_name_of_float_type<RealType>() << unrounded ; std::cout << '\n'; std::cout << " "; print_hex_val(unrounded, "input "); std::cout << " "; print_hex_val(expected, "expected"); std::cout << " "; print_hex_val(observed, "observed"); std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield); std::cout << "\n fixed:" << "\n input " << unrounded << "\n expected " << expected << "\n observed " << observed << "\n abs error " << abs_error << "\n rel error " << rel_error << "\n tolerance " << tolerance ; std::cout.setf(std::ios_base::scientific, std::ios_base::floatfield); std::cout << "\n scientific:" << "\n input " << unrounded << "\n expected " << expected << "\n observed " << observed << "\n abs error " << abs_error << "\n rel error " << rel_error << "\n tolerance " << tolerance ; std::cout.setf(old_flags); std::cout.precision(old_precision); std::cout << std::endl; } return error_is_within_tolerance; }