static void improve_root (mps_context * ctx, mps_polynomial * p, mps_approximation * root, long precision) { mpc_t newton_correction; rdpe_t corr_mod, epsilon; mpc_set_prec (root->mvalue, precision); mpc_init2 (newton_correction, precision); mps_polynomial_mnewton (ctx, p, root, newton_correction, mpc_get_prec (root->mvalue)); mpc_sub_eq (root->mvalue, newton_correction); mpc_rmod (corr_mod, newton_correction); rdpe_add_eq (root->drad, corr_mod); if (ctx->debug_level & MPS_DEBUG_IMPROVEMENT) MPS_DEBUG_MPC (ctx, 15, newton_correction, "Newton correction"); mpc_rmod (corr_mod, root->mvalue); rdpe_set_2dl (epsilon, 1.0, 2 - precision); rdpe_mul_eq (corr_mod, epsilon); rdpe_add_eq (root->drad, corr_mod); mpc_clear (newton_correction); }
static rdpe_t * evaluate_root_conditioning (mps_context * ctx, mps_polynomial * p, mps_approximation ** appr, int n) { int i; rdpe_t * root_conditioning = rdpe_valloc (n); for (i = 0; i < n; i++) { mpc_t value; rdpe_t error, module; mpc_init2 (value, appr[i]->wp); mps_polynomial_meval (ctx, p, appr[i]->mvalue, value, error); mpc_rmod (module, value); /* Get the relative error of this evaluation */ if (!rdpe_eq_zero (module)) rdpe_div_eq (error, module); else rdpe_set_d (error, DBL_EPSILON * p->degree); /* log2(error) + wp - log(n) is a good estimate of log(k) */ rdpe_set_d (root_conditioning[i], rdpe_log (error) / LOG2 + appr[i]->wp - log2 (n)); rdpe_exp_eq (root_conditioning[i]); rdpe_div_eq (root_conditioning[i], appr[i]->drad); mpc_clear (value); } return root_conditioning; }
static int get_approximated_bits (mps_approximation * appr) { rdpe_t module; mpc_rmod (module, appr->mvalue); return (rdpe_log (module) - rdpe_log (appr->drad)) / LOG2 - 1; }
mps_boolean mps_quadratic_poly_meval (mps_context * ctx, mps_polynomial * p, mpc_t x, mpc_t value, rdpe_t error) { int i; int m = (int) (log (p->degree + 1.0) / LOG2); rdpe_t ax, rtmp; mpc_t tmp; long int wp = mpc_get_prec (x); /* Correct the working precision in case of a limited precision polynomial (quite unlikely * in the quadratic case, but still. */ if (p->prec > 0 && p->prec < wp) wp = p->prec; if ((1 << m) <= p->degree) m++; mpc_init2 (tmp, wp); mpc_rmod (ax, x); mpc_set_ui (value, 1U, 0U); mpc_rmod (error, value); for (i = 1; i <= m; i++) { mpc_sqr (tmp, value); mpc_mul (value, x, tmp); mpc_add_eq_ui (value, 1U, 0U); rdpe_mul_eq (error, ax); mpc_rmod (rtmp, value); rdpe_add_eq (error, rtmp); } rdpe_set_2dl (rtmp, 1.0, -wp); rdpe_mul_eq (error, rtmp); mpc_clear (tmp); return true; }
END_TEST START_TEST (determinant_mhessenberg_example1) { /* Custom 8 by 8 example. The matrix is defined as: * A(i,j) = sin(i) * cos(j) + 1e-3 * i*j . * Its determinant should be*/ mpc_t *hessenberg_matrix = mps_newv (mpc_t, 64); mpc_t det, t; rdpe_t diff, mod, error; int i, j; mpc_vinit2 (hessenberg_matrix, 64, DBL_MANT_DIG); mpc_init2 (det, DBL_MANT_DIG); mpc_init2 (t, DBL_MANT_DIG); mps_context *ctx = mps_context_new (); for (i = 0; i < 8; i++) for (j = MAX (0, i - 1); j < 8; j++) { mpc_set_d (hessenberg_matrix[i * 8 + j], sin (1.0 * (i + 1)) * cos (1.0 * (j + 1)) + 1e-3 * (i + 1) * (j + 1), 0.0); } mps_mhessenberg_determinant (ctx, hessenberg_matrix, 8, det, error); mpc_vclear (hessenberg_matrix, 64); free (hessenberg_matrix); mpc_set_d (t, 6.14427105181099e-06, 0.0); mpc_sub_eq (det, t); mpc_rmod (diff, det); mpc_rmod (mod, t); fail_unless (rdpe_get_d (diff) < rdpe_get_d (mod) * 10.0 * 8 * DBL_EPSILON || rdpe_lt (diff, error), "The error on determinant_hessenberg_example1 is bigger than n * DBL_EPSILON"); mps_context_free (ctx); }
QVariant RootsModel::data(const QModelIndex &index, int role) const { int i = index.row(); if (role != Qt::DisplayRole && role < Qt::UserRole) return QVariant(); if (i < 0 || i > length) return QVariant(); else { rdpe_t root_module; mpc_rmod (root_module, m_roots.at(i)->value); int digits = (rdpe_Esp (root_module) - rdpe_Esp (m_roots.at(i)->radius)) / LOG2_10; char * buffer = NULL; switch (role) { case SHORT_APPROXIMATION: digits = 4; // fallthrough case Qt::DisplayRole: buffer = new char[2 * digits + 15]; if (m_roots[i]->get_imag_part() > 0) gmp_sprintf (buffer, "%.*Ff + %.*Ffi", digits, mpc_Re (m_roots[i]->value), digits, mpc_Im (m_roots[i]->value)); else gmp_sprintf (buffer, "%.*Ff %.*Ffi", digits, mpc_Re (m_roots[i]->value), digits, mpc_Im (m_roots[i]->value)); return QString(buffer); break; case STATUS: return QString(MPS_ROOT_STATUS_TO_STRING (m_roots[i]->status)); case RADIUS: return QString("%1").arg(m_roots[i]->get_radius()); case ROOT: return QVariant::fromValue((void*) m_roots[i]); default: qDebug() << "Invalid role"; return QVariant(); } } }
mps_boolean mps_chebyshev_poly_meval (mps_context * ctx, mps_polynomial * poly, mpc_t x, mpc_t value, rdpe_t error) { long int wp = mpc_get_prec (x); /* Lower the working precision in case of limited precision coefficients * in the input polynomial. */ if (poly->prec > 0 && poly->prec < wp) wp = poly->prec; mps_chebyshev_poly * cpoly = MPS_CHEBYSHEV_POLY (poly); int i; mpc_t t0, t1, ctmp, ctmp2; rdpe_t ax, rtmp, rtmp2; mpc_rmod (ax, x); rdpe_set (error, rdpe_zero); /* Make sure that we have sufficient precision to perform the computation */ mps_polynomial_raise_data (ctx, poly, wp); mpc_init2 (t0, wp); mpc_init2 (t1, wp); mpc_init2 (ctmp, wp); mpc_init2 (ctmp2, wp); mpc_set (value, cpoly->mfpc[0]); mpc_set_ui (t0, 1U, 0U); if (poly->degree == 0) { return true; } mpc_set (t1, x); mpc_mul (ctmp, cpoly->mfpc[1], x); mpc_add_eq (value, ctmp); mpc_rmod (rtmp, ctmp); rdpe_add_eq (error, rtmp); for (i = 2; i <= poly->degree; i++) { mpc_mul (ctmp, x, t1); mpc_mul_eq_ui (ctmp, 2U); mpc_rmod (rtmp, ctmp); mpc_sub_eq (ctmp, t0); mpc_rmod (rtmp2, t0); rdpe_add_eq (rtmp, rtmp2); mpc_mul (ctmp2, ctmp, cpoly->mfpc[i]); mpc_add_eq (value, ctmp2); rdpe_mul_eq (rtmp, ax); rdpe_add_eq (error, rtmp); mpc_set (t0, t1); mpc_set (t1, ctmp); } mpc_clear (t0); mpc_clear (t1); mpc_clear (ctmp); mpc_clear (ctmp2); rdpe_set_2dl (rtmp, 2.0, -wp); rdpe_mul_eq (error, rtmp); return true; }
END_TEST START_TEST (determinant_shifted_mhessenberg_example1) { /* Custom 8 by 8 example. The matrix is defined as: * A(i,j) = sin(i) * cos(j) + 1e-3 * i*j . * Its determinant should be*/ mpc_t *hessenberg_matrix = mps_newv (mpc_t, 64); mpc_t det, t; int i, j; mpc_t shifts[3]; mpc_t results[3]; mpc_vinit2 (hessenberg_matrix, 64, DBL_MANT_DIG); mpc_init2 (det, DBL_MANT_DIG); mpc_init2 (t, DBL_MANT_DIG); mpc_vinit2 (shifts, 3, DBL_MANT_DIG); mpc_vinit2 (results, 3, DBL_MANT_DIG); mpc_set_d (shifts[0], 0.403815598068559, 0.754480932782281); mpc_set_d (results[0], -0.2755152414594506, 0.0732925950505913); mpc_set_d (shifts[1], 0.0590780603923638, 0.9236523504901163); mpc_set_d (results[1], 0.5885575152394473, -0.0800261442305445); mpc_set_d (shifts[2], 0.0534877455734864, 0.1853972552409148); mpc_set_d (results[2], -4.28682106680713e-05, -4.18995301563591e-05); mps_context *ctx = mps_context_new (); for (i = 0; i < 8; i++) for (j = MAX (0, i - 1); j < 8; j++) { mpc_set_d (hessenberg_matrix[i * 8 + j], sin (1.0 * (i + 1)) * cos (1.0 * (j + 1)) + 1e-3 * (i + 1) * (j + 1), 0.0); } for (i = 0; i < 2; i++) { rdpe_t diff, mod, error; mps_mhessenberg_shifted_determinant (ctx, hessenberg_matrix, shifts[i], 8, det, error); mpc_sub_eq (det, results[i]); mpc_rmod (diff, det); mpc_rmod (mod, results[i]); printf ("%d: ", i); mpc_out_str_2 (stdout, 10, 15, 15, det); printf ("\n"); fail_unless (rdpe_get_d (diff) < rdpe_get_d (mod) * 10.0 * 8 * DBL_EPSILON || rdpe_lt (diff, error), "The error on shifted Hessenberg determinant example1 is bigger than n * DBL_EPSILON"); } mpc_vclear (shifts, 3); mpc_vclear (results, 3); mpc_vclear (hessenberg_matrix, 64); mpc_clear (t); mpc_clear (det); free (hessenberg_matrix); mps_context_free (ctx); }