/** * @brief Print a float to stdout (or whatever the output stream is * atm) respecting the given options, and only with the significant * digits. * * @param s A pointer to the current mps_context. * @param f The float approximation that should be printed. * @param rad The current inclusion radius for that approximation. * @param out_digit The number of output digits required. * @param sign The sign of the approximation. */ MPS_PRIVATE void mps_outfloat (mps_context * s, mpf_t f, rdpe_t rad, long out_digit, mps_boolean sign) { mpf_t t; rdpe_t r, ro; double d; long l, digit, true_digit; if (s->output_config->format == MPS_OUTPUT_FORMAT_FULL) { mpf_init2 (t, mpf_get_prec (f)); mpf_set (t, f); mpf_out_str (s->outstr, 10, 0, t); mpf_clear (t); return; } mpf_init2 (t, s->output_config->prec); mpf_get_rdpe (ro, f); if (s->output_config->format == MPS_OUTPUT_FORMAT_GNUPLOT || s->output_config->format == MPS_OUTPUT_FORMAT_GNUPLOT_FULL) rdpe_out_str_u (s->outstr, ro); else { rdpe_abs_eq (ro); if (rdpe_ne (ro, rdpe_zero)) rdpe_div (r, rad, ro); else rdpe_set_d (r, 1.0e-10); digit = (long)(-rdpe_log10 (r) - 0.5); if (digit <= 0) { rdpe_get_dl (&d, &l, ro); fprintf (s->outstr, "0.e%ld", l); } else { true_digit = (long)(LOG10_2 * mpf_get_prec (f)); true_digit = MIN (digit, true_digit); true_digit = MIN (true_digit, out_digit); if (sign) mpf_set (t, f); else mpf_abs (t, f); mpf_out_str (s->outstr, 10, true_digit, t); } } mpf_clear (t); }
void gdpe_div (gdpe_t res, gdpe_t g1, gdpe_t g2) { rdpe_div (gdpe_Val (res), gdpe_Val (g1), gdpe_Val (g2)); if (gdpe_eq_zero (g1)) { rdpe_set (gdpe_Eps (res), rdpe_zero); return; } rdpe_add (gdpe_Rel (res), gdpe_Rel (g1), gdpe_Rel (g2)); gdpe_update_abs_from_rel (res); }
/** * @brief Check consistency of data and makes some basic adjustments. * * This routine check, for example, if there are zero roots in the polynomial * (i.e. no costant term) and deflates the polynomial if necessary (shifting * the coefficients). * * It sets the value of the parameter <code>which_case</code> to <code>'f'</code> * if a floating point phase is enough, or to <code>'d'</code> if * a <code>dpe</code> phase is needed. * * @param s The <code>mps_context</code> associated with the current computation. * @param which_case the address of the variable which_case; */ MPS_PRIVATE void mps_check_data (mps_context * s, char *which_case) { rdpe_t min_coeff, max_coeff, tmp; mps_monomial_poly *p = NULL; int i; /* case of user-defined polynomial */ if (! MPS_IS_MONOMIAL_POLY (s->active_poly)) { if (s->output_config->multiplicity) mps_error (s, "Multiplicity detection not yet implemented for user polynomial"); if (s->output_config->root_properties) mps_error (s, "Real/imaginary detection not yet implemented for user polynomial"); *which_case = 'd'; return; } else p = MPS_MONOMIAL_POLY (s->active_poly); /* Check consistency of input */ if (rdpe_eq (p->dap[s->n], rdpe_zero)) { mps_warn (s, "The leading coefficient is zero"); do (s->n)--; while (rdpe_eq (p->dap[s->n], rdpe_zero)); MPS_POLYNOMIAL (p)->degree = s->n; } /* Compute min_coeff */ if (rdpe_lt (p->dap[0], p->dap[s->n])) rdpe_set (min_coeff, p->dap[0]); else rdpe_set (min_coeff, p->dap[s->n]); /* Compute max_coeff and its logarithm */ rdpe_set (max_coeff, p->dap[0]); for (i = 1; i <= s->n; i++) if (rdpe_lt (max_coeff, p->dap[i])) rdpe_set (max_coeff, p->dap[i]); s->lmax_coeff = rdpe_log (max_coeff); /* Multiplicity and sep */ if (s->output_config->multiplicity) { if (MPS_STRUCTURE_IS_INTEGER (s->active_poly->structure)) { mps_compute_sep (s); } else if (MPS_STRUCTURE_IS_RATIONAL (s->active_poly->structure)) { mps_warn (s, "The multiplicity option has not been yet implemented"); s->sep = 0.0; } else { mps_warn (s, "The input polynomial has neither integer nor rational"); mps_warn (s, " coefficients: unable to compute multiplicities"); s->sep = 0.0; } } /* Real/Imaginary detection */ if (s->output_config->root_properties || s->output_config->search_set == MPS_SEARCH_SET_REAL || s->output_config->search_set == MPS_SEARCH_SET_IMAG) { if (MPS_STRUCTURE_IS_INTEGER (s->active_poly->structure)) { mps_compute_sep (s); } else if (MPS_STRUCTURE_IS_RATIONAL (s->active_poly->structure)) { mps_error (s, "The real/imaginary option has not been yet implemented for rational input"); return; } else { mps_error (s, "The input polynomial has neither integer nor rational " "coefficients: unable to perform real/imaginary options"); return; } } /* Select cases (dpe or floating point) * First normalize the polynomial (only the float version) */ rdpe_div (tmp, max_coeff, min_coeff); rdpe_mul_eq_d (tmp, (double)(s->n + 1)); rdpe_mul_eq (tmp, rdpe_mind); rdpe_div_eq (tmp, rdpe_maxd); if (rdpe_lt (tmp, rdpe_one)) { mpc_t m_min_coeff; cdpe_t c_min_coeff; /* if (n+1)*max_coeff/min_coeff < dhuge/dtiny - float case */ *which_case = 'f'; rdpe_mul_eq (min_coeff, max_coeff); rdpe_mul (tmp, rdpe_mind, rdpe_maxd); rdpe_div (min_coeff, tmp, min_coeff); rdpe_sqrt_eq (min_coeff); rdpe_set (cdpe_Re (c_min_coeff), min_coeff); rdpe_set (cdpe_Im (c_min_coeff), rdpe_zero); mpc_init2 (m_min_coeff, mpc_get_prec (p->mfpc[0])); mpc_set_cdpe (m_min_coeff, c_min_coeff); /* min_coeff = sqrt(dhuge*dtiny/(min_coeff*max_coeff)) * NOTE: This is enabled for floating point polynomials only * for the moment, but it may work nicely also for other representations. */ { for (i = 0; i <= s->n; i++) { /* Multiply the MP leading coefficient */ mpc_mul_eq (p->mfpc[i], m_min_coeff); rdpe_mul (tmp, p->dap[i], min_coeff); rdpe_set (p->dap[i], tmp); p->fap[i] = rdpe_get_d (tmp); mpc_get_cdpe (p->dpc[i], p->mfpc[i]); cdpe_get_x (p->fpc[i], p->dpc[i]); } } mpc_clear (m_min_coeff); } else *which_case = 'd'; }