void check_overflow () { mpfr_t max; mpfi_t a; mpz_t z; int inexact; mpz_init (z); mpfi_init2 (a, 53); mpfr_init2 (max, 53); mpz_set_ui (z, 4096); mpfr_set_ui (&(a->left), 1, MPFI_RNDD); mpfr_set_inf (max, +1); mpfr_nextbelow (max); mpfr_set (&(a->right), max, MPFI_RNDU); inexact = mpfi_mul_z (a, a, z); if (!mpfr_inf_p (&(a->right))) { printf ("Error: mpfi_mul_z does not correctly handle positive " "overflow.\n"); exit (1); } if (!MPFI_RIGHT_IS_INEXACT (inexact)) { printf ("Error: mpfi_mul_z does not return correct value when positive " "overflow.\n"); exit (1); } mpfr_set_inf (max, -1); mpfr_nextabove (max); mpfr_set (&(a->left), max, MPFI_RNDD); mpfr_set_ui (&(a->right), 1, MPFI_RNDU); inexact = mpfi_mul_z (a, a, z); if (!mpfr_inf_p (&(a->left))) { printf ("Error: mpfi_mul_z does not correctly handle negative " "overflow.\n"); exit (1); } if (!MPFI_LEFT_IS_INEXACT (inexact)) { printf ("Error: mpfi_mul_z does not return correct value when negative " "overflow.\n"); exit (1); } mpz_clear (z); mpfi_clear (a); mpfr_clear (max); }
/*Returns in chebCoeffs the coeffs of the finite Chebyshev basis expansion of the polynomial p of degree n-1, over [-1,1]; The coefficients in monomial basis of p are in *p This algorithm uses simply euclidean division. */ void getPolyCoeffsChebBasis(sollya_mpfi_t *chebCoeffs, sollya_mpfi_t *p, int n){ sollya_mpfi_t *pAux, temp; mpz_t *chebMatrix; int i,j; mp_prec_t prec; prec = sollya_mpfi_get_prec(chebCoeffs[0]); pAux=safeMalloc((n)*sizeof(sollya_mpfi_t)); for (i=0;i<n;i++){ sollya_mpfi_init2(pAux[i],prec); sollya_mpfi_set(pAux[i], p[i]); } chebMatrix=(mpz_t *)safeMalloc((n*n)*sizeof(mpz_t)); for (i=0;i<n*n;i++){ mpz_init2(chebMatrix[i],prec); } getChebPolyCoeffs(chebMatrix, n, prec); sollya_mpfi_init2(temp,prec); for(i=n-1; i>=0;i--){ mpfi_div_z(chebCoeffs[i],pAux[i],chebMatrix[i*n+i]); for(j=i-1;j>=0;j--){ mpfi_mul_z(temp,chebCoeffs[i],chebMatrix[i*n+j]); mpfi_sub(pAux[j],pAux[j],temp); } } for (i=0;i<n;i++){ sollya_mpfi_clear(pAux[i]); } safeFree(pAux); for (i=0;i<n*n;i++){ mpz_clear(chebMatrix[i]); } safeFree(chebMatrix); sollya_mpfi_clear(temp); }
/*Wrapper to get directly the coeffs in the monomial basis from a polynomial in the Chebyshev basis, over a given interval x*/ void getCoeffsFromChebPolynomial(sollya_mpfi_t**coeffs, sollya_mpfi_t *chebCoeffs, int n, sollya_mpfi_t x){ sollya_mpfi_t z1, z2, ui, vi, temp; int j,i; sollya_mpfi_t *c; mpfr_t u,v; mpz_t *chebMatrix; mp_prec_t prec; prec = sollya_mpfi_get_prec(chebCoeffs[0]); sollya_mpfi_init2(temp, prec); chebMatrix= (mpz_t *)safeMalloc((n*n)*sizeof(mpz_t)); for (i=0;i<n*n;i++){ mpz_init2(chebMatrix[i], prec); } getChebPolyCoeffs(chebMatrix, n,prec); *coeffs= (sollya_mpfi_t *)safeMalloc((n)*sizeof(sollya_mpfi_t)); c=(sollya_mpfi_t *)safeMalloc((n)*sizeof(sollya_mpfi_t)); for (i=0;i<n;i++){ sollya_mpfi_init2((*coeffs)[i],prec); sollya_mpfi_init2(c[i],prec); sollya_mpfi_set_ui(c[i],0); } for (j=0;j<n;j++){ for (i=j;i<n;i++){ mpfi_mul_z(temp, chebCoeffs[i], chebMatrix[i*n+j]); sollya_mpfi_add(c[j], c[j], temp); } } /*we have in c_i the values of the coefs of P(2/(b-a)x- (b+a)/(b-a)) = \sum c_i (2/(b-a)x- (b+a)/(b-a))^i*/ /*we need to the translation*/ /*we compute z1=2/(b-a); z2=-(b+a)/(b-a)*/ sollya_mpfi_init2(ui, prec); sollya_mpfi_init2(vi, prec); mpfr_init2(u, prec); mpfr_init2(v, prec); sollya_mpfi_init2(z1, prec); sollya_mpfi_init2(z2, prec); sollya_mpfi_get_left(u,x); sollya_mpfi_get_right(v,x); sollya_mpfi_set_fr(ui,u); sollya_mpfi_set_fr(vi,v); sollya_mpfi_sub(z2,vi,ui); sollya_mpfi_ui_div(z1,2,z2); sollya_mpfi_add(temp, ui, vi); sollya_mpfi_div(z2, temp, z2); sollya_mpfi_neg(z2, z2); getTranslatedPolyCoeffs((*coeffs), c, n, z1,z2); /*cleaning*/ sollya_mpfi_clear(z1); sollya_mpfi_clear(z2); sollya_mpfi_clear(ui); sollya_mpfi_clear(vi); sollya_mpfi_clear(temp); mpfr_clear(u); mpfr_clear(v); for (i=0;i<n*n;i++){ mpz_clear(chebMatrix[i]); } safeFree(chebMatrix); for (i=0;i<n;i++){ sollya_mpfi_clear(c[i]); } safeFree(c); }