void cdpe_div_d (cdpe_t rc, const cdpe_t c, double d) /* rc = c / d */ { cdpe_Move (rc, c); rdpe_Mnt (cdpe_Re (rc)) /= d; rdpe_Mnt (cdpe_Im (rc)) /= d; cdpe_Norm (rc); }
void cdpe_mul_d (cdpe_t rc, const cdpe_t c, double d) /* rc = c * d */ { cdpe_Move (rc, c); rdpe_Mnt (cdpe_Re (rc)) *= d; rdpe_Mnt (cdpe_Im (rc)) *= d; cdpe_Norm (rc); }
void cdpe_div (cdpe_t rc, const cdpe_t c1, const cdpe_t c2) /* rc = c1 / c2 */ { cdpe_t t; /* needed when rc=c1 or rc=c2 */ rdpe_t e1, e2, e3; cdpe_smod (e1, c2); cdpe_div_e (t, c2, e1); rdpe_Mnt (cdpe_Im (t)) = -rdpe_Mnt (cdpe_Im (t)); rdpe_mul (e1, cdpe_Re (c1), cdpe_Re (t)); rdpe_mul (e2, cdpe_Im (c1), cdpe_Im (t)); rdpe_sub (e3, e1, e2); rdpe_mul (e1, cdpe_Im (c1), cdpe_Re (t)); rdpe_mul (e2, cdpe_Re (c1), cdpe_Im (t)); rdpe_Move (cdpe_Re (rc), e3); rdpe_add (cdpe_Im (rc), e1, e2); }
void cdpe_set_d (cdpe_t c, double dr, double di) /* c = dr + I di */ { cdpe_set (c, cdpe_zero); rdpe_Mnt (cdpe_Re (c)) = dr; rdpe_Mnt (cdpe_Im (c)) = di; cdpe_Norm (c); }
void cdpe_set_x (cdpe_t c, const cplx_t x) /* c = (cdpe_t) x */ { cdpe_Move (c, cdpe_zero); rdpe_Mnt (cdpe_Re (c)) = cplx_Re (x); rdpe_Mnt (cdpe_Im (c)) = cplx_Im (x); cdpe_Norm (c); }
void cdpe_smod (rdpe_t e, const cdpe_t c) /* e = |c|^2 */ { rdpe_t t; rdpe_sqr (e, cdpe_Re (c)); rdpe_sqr (t, cdpe_Im (c)); rdpe_add_eq (e, t); }
void cdpe_inv_eq (cdpe_t c) /* c = 1 / c */ { rdpe_t e; cdpe_smod (e, c); rdpe_inv_eq (e); rdpe_Mnt (cdpe_Im (c)) = -rdpe_Mnt (cdpe_Im (c)); rdpe_mul_eq (cdpe_Re (c), e); rdpe_mul_eq (cdpe_Im (c), e); }
void cdpe_inv (cdpe_t rc, const cdpe_t c) /* rc = 1 / c */ { rdpe_t e; cdpe_smod (e, c); rdpe_inv_eq (e); cdpe_Move (rc, c); rdpe_Mnt (cdpe_Im (rc)) = -rdpe_Mnt (cdpe_Im (rc)); rdpe_mul_eq (cdpe_Re (rc), e); rdpe_mul_eq (cdpe_Im (rc), e); }
int cdpe_out_str_u (FILE * f, const cdpe_t c) /* output as mant e exp mant e exp */ { if (f == NULL) f = stdout; if (rdpe_out_str_u (f, cdpe_Re (c)) < 0) return -1; if (fprintf (f, " ") < 0) return -1; if (rdpe_out_str_u (f, cdpe_Im (c)) < 0) return -1; return 0; }
char * cdpe_get_str (char *s, const cdpe_t c) /* output to string as (re , im) */ { double dr, di; long int lr, li; if (s == NULL && (s = (char*)mps_malloc (DEF_STR_SIZE)) == NULL) return NULL; rdpe_get_dl (&dr, &lr, cdpe_Re (c)); rdpe_get_dl (&di, &li, cdpe_Im (c)); sprintf (s, CDPE_OUT_FMT, dr, lr, di, li); return s; }
int cdpe_inp_str (cdpe_t c, FILE * f) /* input from file as (mant x exp , mant x exp) */ { double dr, di; long int lr, li; if (f == NULL) f = stdin; if (fscanf (f, CDPE_INP_FMT, &dr, &lr, &di, &li) != 4) return 0; rdpe_set_dl (cdpe_Re (c), dr, lr); rdpe_set_dl (cdpe_Im (c), di, li); return 1; }
int cdpe_out_str (FILE * f, const cdpe_t c) /* output as (mant x exp , mant x exp) */ { if (f == NULL) f = stdout; if (fputc ('(', f) == EOF) return -1; if (rdpe_out_str (f, cdpe_Re (c)) < 0) return -1; if (fprintf (f, ", ") < 0) return -1; if (rdpe_out_str (f, cdpe_Im (c)) < 0) return -1; return fputc (')', f); }
/** * @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'; }
/** * @brief Setup vectors and variables */ MPS_PRIVATE void mps_setup (mps_context * s) { int i; mps_polynomial *p = s->active_poly; mpf_t mptemp; mpc_t mptempc; if (s->DOLOG) { /* fprintf (s->logstr, "Goal = %5s\n", s->goal); */ /* fprintf (s->logstr, "Data type = %3s\n", s->data_type); */ fprintf (s->logstr, "Degree = %d\n", s->n); fprintf (s->logstr, "Input prec. = %ld digits\n", (long)(s->active_poly->prec * LOG10_2)); fprintf (s->logstr, "Output prec. = %ld digits\n", (long)(s->output_config->prec * LOG10_2)); } /* setup temporary vectors */ if (MPS_IS_MONOMIAL_POLY (p) && MPS_DENSITY_IS_SPARSE (s->active_poly->density)) { mps_monomial_poly *mp = MPS_MONOMIAL_POLY (p); for (i = 0; i <= p->degree; i++) { mp->fap[i] = 0.0; mp->fpr[i] = 0.0; rdpe_set (mp->dap[i], rdpe_zero); cplx_set (mp->fpc[i], cplx_zero); rdpe_set (mp->dpr[i], rdpe_zero); cdpe_set (mp->dpc[i], cdpe_zero); } } /* Indexes of the first (and only) cluster start from * 0 and reach n */ mps_cluster_reset (s); /* set input and output epsilon */ rdpe_set_2dl (s->eps_in, 1.0, 1 - s->active_poly->prec); rdpe_set_2dl (s->eps_out, 1.0, 1 - s->output_config->prec); /* precision of each root */ for (i = 0; i < s->n; i++) s->root[i]->wp = 53; /* output order info */ for (i = 0; i < s->n; i++) s->order[i] = i; /* reset root counts */ s->count[0] = s->count[1] = s->count[2] = 0; /* compute DPE approximations */ if (MPS_IS_MONOMIAL_POLY (p)) { mps_monomial_poly *mp = MPS_MONOMIAL_POLY (p); /* init temporary mp variables */ mpf_init2 (mptemp, DBL_MANT_DIG); mpc_init2 (mptempc, DBL_MANT_DIG); /* main loop */ s->skip_float = false; for (i = 0; i <= s->n; i++) { if (MPS_DENSITY_IS_SPARSE (s->active_poly->density) && !mp->spar[i]) continue; if (MPS_STRUCTURE_IS_REAL (s->active_poly->structure)) { if (MPS_STRUCTURE_IS_RATIONAL (s->active_poly->structure) || MPS_STRUCTURE_IS_INTEGER (s->active_poly->structure)) { mpf_set_q (mptemp, mp->initial_mqp_r[i]); mpf_get_rdpe (mp->dpr[i], mptemp); /*#G GMP 2.0.2 bug begin */ if (rdpe_sgn (mp->dpr[i]) != mpq_sgn (mp->initial_mqp_r[i])) rdpe_neg_eq (mp->dpr[i]); /*#G GMP bug end */ } if (MPS_STRUCTURE_IS_FP (s->active_poly->structure)) mpf_get_rdpe (mp->dpr[i], mpc_Re (mp->mfpc[i])); cdpe_set_e (mp->dpc[i], mp->dpr[i], rdpe_zero); /* compute dap[i] and check for float phase */ rdpe_abs (mp->dap[i], mp->dpr[i]); rdpe_abs (mp->dap[i], mp->dpr[i]); if (rdpe_gt (mp->dap[i], rdpe_maxd) || rdpe_lt (mp->dap[i], rdpe_mind)) s->skip_float = true; } else if (MPS_STRUCTURE_IS_COMPLEX (s->active_poly->structure)) { if (MPS_STRUCTURE_IS_RATIONAL (s->active_poly->structure) || MPS_STRUCTURE_IS_INTEGER (s->active_poly->structure)) { mpc_set_q (mptempc, mp->initial_mqp_r[i], mp->initial_mqp_i[i]); mpc_get_cdpe (mp->dpc[i], mptempc); /*#G GMP 2.0.2 bug begin */ if (rdpe_sgn (cdpe_Re (mp->dpc[i])) != mpq_sgn (mp->initial_mqp_r[i])) rdpe_neg_eq (cdpe_Re (mp->dpc[i])); if (rdpe_sgn (cdpe_Im (mp->dpc[i])) != mpq_sgn (mp->initial_mqp_i[i])) rdpe_neg_eq (cdpe_Im (mp->dpc[i])); /*#G GMP bug end */ } else if (MPS_STRUCTURE_IS_FP (s->active_poly->structure)) mpc_get_cdpe (mp->dpc[i], mp->mfpc[i]); /* compute dap[i] */ cdpe_mod (mp->dap[i], mp->dpc[i]); if (rdpe_gt (mp->dap[i], rdpe_maxd) || rdpe_lt (mp->dap[i], rdpe_mind)) s->skip_float = true; } } /* free temporary mp variables */ mpf_clear (mptemp); mpc_clear (mptempc); /* adjust input data type */ if (MPS_STRUCTURE_IS_FP (s->active_poly->structure) && s->skip_float) s->active_poly->structure = MPS_STRUCTURE_IS_REAL (s->active_poly->structure) ? MPS_STRUCTURE_REAL_BIGFLOAT : MPS_STRUCTURE_COMPLEX_BIGFLOAT; /* prepare floating point vectors */ if (!s->skip_float) for (i = 0; i <= MPS_POLYNOMIAL (p)->degree; i++) { if (MPS_DENSITY_IS_SPARSE (s->active_poly->density) || !mp->spar[i]) continue; if (MPS_STRUCTURE_IS_REAL (s->active_poly->structure)) { mp->fpr[i] = rdpe_get_d (mp->dpr[i]); mp->fap[i] = fabs (mp->fpr[i]); cplx_set_d (mp->fpc[i], mp->fpr[i], 0.0); } else { cdpe_get_x (mp->fpc[i], mp->dpc[i]); mp->fap[i] = cplx_mod (mp->fpc[i]); } } } }