ex-2: implement correct series estimation in fancier.c
This commit is contained in:
parent
49e9fbd5b7
commit
c8f34f1822
@ -146,20 +146,42 @@ void mpq_log2(mpq_t rop, size_t digits) {
|
|||||||
}
|
}
|
||||||
fprintf(stderr, "[mpq_log2] series terms: %ld\n", n);
|
fprintf(stderr, "[mpq_log2] series terms: %ld\n", n);
|
||||||
|
|
||||||
/* calculate series */
|
/* Compute the nth partial sum */
|
||||||
for (size_t i=1; i<n+1; i++) {
|
for (size_t i=1; i<=n; i++) {
|
||||||
mpq_set_ui(term, 1, 1);
|
mpq_set_ui(term, 1, 1);
|
||||||
mpz_ui_pow_ui(mpq_denref(term), 2, i);
|
mpz_ui_pow_ui(mpq_denref(term), 2, i);
|
||||||
mpz_mul_ui(mpq_denref(term), mpq_denref(term), i);
|
mpz_mul_ui(mpq_denref(term), mpq_denref(term), i);
|
||||||
mpq_add(sum, sum, term);
|
mpq_add(sum, sum, term);
|
||||||
}
|
}
|
||||||
mpq_fprintf(stderr, digits > 50 ? 50 : digits,
|
|
||||||
"[mpq_log2] log(2)=%q...\n", &sum);
|
|
||||||
|
|
||||||
|
/* Compute upper/lower bounds */
|
||||||
|
mpq_t upp, low;
|
||||||
|
mpq_inits(upp, low, NULL);
|
||||||
|
|
||||||
|
// upp = sum + term
|
||||||
|
mpq_add(upp, sum, term);
|
||||||
|
|
||||||
|
// low = sum + term * n/(n+2)
|
||||||
|
mpz_mul_ui(mpq_numref(low), mpq_numref(term), n);
|
||||||
|
mpz_mul_ui(mpq_denref(low), mpq_denref(term), n+2);
|
||||||
|
mpq_canonicalize(low);
|
||||||
|
mpq_add(low, sum, low);
|
||||||
|
|
||||||
|
/* Average the two bounds */
|
||||||
|
mpq_add(sum, upp, low);
|
||||||
|
mpz_mul_ui(mpq_denref(sum), mpq_denref(sum), 2);
|
||||||
|
mpq_canonicalize(sum);
|
||||||
|
|
||||||
|
size_t d = digits > 50 ? 50 : digits;
|
||||||
|
mpq_fprintf(stderr, d+2, "[mpq_log2] upper bound: %q...\n", &upp);
|
||||||
|
mpq_fprintf(stderr, d+2, "[mpq_log2] lower bound: %q...\n", &low);
|
||||||
|
mpq_fprintf(stderr, d, "[mpq_log2] log(2)=%q...\n", &sum);
|
||||||
|
|
||||||
|
// return sum
|
||||||
mpq_set(rop, sum);
|
mpq_set(rop, sum);
|
||||||
|
|
||||||
// free memory
|
// free memory
|
||||||
mpq_clears(sum, term, NULL);
|
mpq_clears(sum, term, upp, low, NULL);
|
||||||
mpz_clears(temp, prec, width, NULL);
|
mpz_clears(temp, prec, width, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +300,7 @@ void mpq_log_ui(mpq_t rop, size_t x, size_t digits) {
|
|||||||
fprintf(stderr, "[mpq_log_ui] decimal digits: %ld\n", digits);
|
fprintf(stderr, "[mpq_log_ui] decimal digits: %ld\n", digits);
|
||||||
|
|
||||||
|
|
||||||
/* calculate the series of
|
/* Compute the nth partial sum of
|
||||||
* log(A) = log((1+y)/(1-y)) = 2 Σ_{k=0} y^(2k+1)/(2k+1)
|
* log(A) = log((1+y)/(1-y)) = 2 Σ_{k=0} y^(2k+1)/(2k+1)
|
||||||
*/
|
*/
|
||||||
mpq_t sum, term; mpq_inits(sum, term, NULL);
|
mpq_t sum, term; mpq_inits(sum, term, NULL);
|
||||||
@ -299,6 +321,35 @@ void mpq_log_ui(mpq_t rop, size_t x, size_t digits) {
|
|||||||
mpq_add(sum, sum, term);
|
mpq_add(sum, sum, term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compute the upper and lower bounds */
|
||||||
|
mpq_t upp, low;
|
||||||
|
mpq_inits(upp, low, NULL);
|
||||||
|
|
||||||
|
// upp = sum + term * y2/(1-y2)
|
||||||
|
mpq_mul(upp, term, y2);
|
||||||
|
mpq_set_ui(temp, 1, 1);
|
||||||
|
mpq_sub(temp, temp, y2);
|
||||||
|
mpq_div(upp, upp, temp);
|
||||||
|
mpq_add(upp, sum, upp);
|
||||||
|
|
||||||
|
// low = sum + term / ((2*n + 3)/(2*n + 1)*y^-2 - 1)
|
||||||
|
mpq_set_ui(temp, 2*n + 3, 2*n + 1);
|
||||||
|
mpq_div(temp, temp, y2);
|
||||||
|
mpz_sub(mpq_numref(temp), mpq_numref(temp), mpq_denref(temp));
|
||||||
|
mpq_canonicalize(temp);
|
||||||
|
mpq_div(low, term, temp);
|
||||||
|
mpq_add(low, sum, low);
|
||||||
|
|
||||||
|
/* Average the two bounds */
|
||||||
|
mpq_add(sum, low, upp);
|
||||||
|
mpz_div_ui(mpq_numref(sum), mpq_numref(sum), 2);
|
||||||
|
mpq_canonicalize(sum);
|
||||||
|
|
||||||
|
size_t d = digits > 50 ? 50 : digits;
|
||||||
|
mpq_fprintf(stderr, d+2, "[mpq_log_ui] upper bound: %q...\n", upp);
|
||||||
|
mpq_fprintf(stderr, d+2, "[mpq_log_ui] lower bound: %q...\n", low);
|
||||||
|
mpq_fprintf(stderr, d, "[mpq_log_ui] series: %q...\n", sum);
|
||||||
|
|
||||||
// multiply by 2
|
// multiply by 2
|
||||||
mpz_mul_ui(mpq_numref(sum), mpq_numref(sum), 2);
|
mpz_mul_ui(mpq_numref(sum), mpq_numref(sum), 2);
|
||||||
mpq_canonicalize(sum);
|
mpq_canonicalize(sum);
|
||||||
|
Loading…
Reference in New Issue
Block a user