Example #1
0
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);
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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);
}
Example #6
0
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();
        }
    }
}
Example #7
0
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;
}
Example #8
0
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);
}