X-Git-Url: https://ginac.de/CLN/cln.git//cln.git?a=blobdiff_plain;f=src%2Ffloat%2Ftranscendental%2Fcl_LF_eulerconst.cc;h=c5965af901a6986e670cb1e7d8347c7cf5f254ed;hb=8169a19b38c42588b39b21dae5bdb964e2f6b8c6;hp=1258f7566b56e30aba035e41a580944721f35300;hpb=c486b78a1a0613f07a10816d6f6ca9e485bc8290;p=cln.git diff --git a/src/float/transcendental/cl_LF_eulerconst.cc b/src/float/transcendental/cl_LF_eulerconst.cc index 1258f75..c5965af 100644 --- a/src/float/transcendental/cl_LF_eulerconst.cc +++ b/src/float/transcendental/cl_LF_eulerconst.cc @@ -1,19 +1,20 @@ // eulerconst(). // General includes. -#include "cl_sysdep.h" +#include "base/cl_sysdep.h" // Specification. -#include "cl_F_tran.h" +#include "float/transcendental/cl_F_tran.h" // Implementation. #include "cln/lfloat.h" -#include "cl_LF_tran.h" -#include "cl_LF.h" +#include "float/transcendental/cl_LF_tran.h" +#include "float/lfloat/cl_LF.h" #include "cln/integer.h" -#include "cl_alloca.h" +#include "cln/real.h" +#include "base/cl_alloca.h" namespace cln { @@ -70,7 +71,7 @@ const cl_LF compute_eulerconst_expintegral (uintC len) // If we computed this with floating-point numbers, we would have // to more than double the floating-point precision because of the large // extinction which takes place. But luckily we compute with integers. - var uintC actuallen = len+1; // 1 Schutz-Digit + var uintC actuallen = len+1; // 1 guard digit var uintC z = (uintC)(0.693148*intDsize*actuallen)+1; var uintC N = (uintC)(3.591121477*z); CL_ALLOCA_STACK; @@ -85,15 +86,15 @@ const cl_LF compute_eulerconst_expintegral (uintC len) } var cl_pqb_series series; series.bv = bv; - series.pv = pv; series.qv = qv; series.qsv = NULL; - var cl_LF fsum = eval_rational_series(N,series,actuallen); + series.pv = pv; series.qv = qv; + var cl_LF fsum = eval_rational_series(N,series,actuallen); for (n = 0; n < N; n++) { bv[n].~cl_I(); pv[n].~cl_I(); qv[n].~cl_I(); } fsum = fsum - ln(cl_I_to_LF(z,actuallen)); // log(z) subtrahieren - return shorten(fsum,len); // verkürzen und fertig + return shorten(fsum,len); // verkürzen und fertig } // Bit complexity (N = len): O(log(N)^2*M(N)). @@ -145,7 +146,7 @@ const cl_LF compute_eulerconst_expintegral1 (uintC len) // Finally we compute the sums of the series f(x) and g(x) with N terms // each. // We compute f(x) classically and g(x) using the partial sums of f(x). - var uintC actuallen = len+2; // 2 Schutz-Digits + var uintC actuallen = len+2; // 2 guard digits var uintC x = (uintC)(0.693148*intDsize*actuallen)+1; var uintC N = (uintC)(2.718281828*x); var cl_LF one = cl_I_to_LF(1,actuallen); @@ -173,7 +174,7 @@ const cl_LF compute_eulerconst_expintegral1 (uintC len) } } var cl_LF result = gsum/fsum - ln(cl_I_to_LF(x,actuallen)); - return shorten(result,len); // verkürzen und fertig + return shorten(result,len); // verkürzen und fertig } // Bit complexity (N = len): O(N^2). @@ -185,7 +186,7 @@ const cl_LF compute_eulerconst_expintegral1 (uintC len) // the sums. const cl_LF compute_eulerconst_expintegral2 (uintC len) { - var uintC actuallen = len+2; // 2 Schutz-Digits + var uintC actuallen = len+2; // 2 guard digits var uintC x = (uintC)(0.693148*intDsize*actuallen)+1; var uintC N = (uintC)(2.718281828*x); CL_ALLOCA_STACK; @@ -210,7 +211,7 @@ const cl_LF compute_eulerconst_expintegral2 (uintC len) args[n].q.~cl_I(); args[n].d.~cl_I(); } - return shorten(result,len); // verkürzen und fertig + return shorten(result,len); // verkürzen und fertig } // Bit complexity (N = len): O(log(N)^2*M(N)). @@ -275,7 +276,7 @@ const cl_LF compute_eulerconst_expintegral2 (uintC len) const cl_LF compute_eulerconst_besselintegral1 (uintC len) { // We compute f(x) classically and g(x) using the partial sums of f(x). - var uintC actuallen = len+1; // 1 Schutz-Digit + var uintC actuallen = len+1; // 1 guard digit var uintC sx = (uintC)(0.25*0.693148*intDsize*actuallen)+1; var uintC N = (uintC)(3.591121477*sx); var cl_I x = square((cl_I)sx); @@ -304,7 +305,7 @@ const cl_LF compute_eulerconst_besselintegral1 (uintC len) } } var cl_LF result = gsum/fsum - ln(cl_I_to_LF(sx,actuallen)); - return shorten(result,len); // verkürzen und fertig + return shorten(result,len); // verkürzen und fertig } // Bit complexity (N = len): O(N^2). @@ -325,7 +326,7 @@ const cl_LF compute_eulerconst_besselintegral2 (uintC len) // WARNING: The memory used by this algorithm grown quadratically in N. // (Because HD_n grows like exp(n), hence HN_n grows like exp(n) as // well, and we store all HN_n values in an array!) - var uintC actuallen = len+1; // 1 Schutz-Digit + var uintC actuallen = len+1; // 1 guard digit var uintC sx = (uintC)(0.25*0.693148*intDsize*actuallen)+1; var uintC N = (uintC)(3.591121477*sx); var cl_I x = square((cl_I)sx); @@ -342,8 +343,8 @@ const cl_LF compute_eulerconst_besselintegral2 (uintC len) init1(cl_I, qv[n]) ((cl_I)n*(cl_I)n); } var cl_pq_series fseries; - fseries.pv = pv; fseries.qv = qv; fseries.qsv = NULL; - var cl_LF fsum = eval_rational_series(N,fseries,actuallen); + fseries.pv = pv; fseries.qv = qv; + var cl_LF fsum = eval_rational_series(N,fseries,actuallen); for (n = 0; n < N; n++) { pv[n].~cl_I(); qv[n].~cl_I(); @@ -364,15 +365,15 @@ const cl_LF compute_eulerconst_besselintegral2 (uintC len) } var cl_pqa_series gseries; gseries.av = av; - gseries.pv = pv; gseries.qv = qv; gseries.qsv = NULL; - var cl_LF gsum = eval_rational_series(N,gseries,actuallen); + gseries.pv = pv; gseries.qv = qv; + var cl_LF gsum = eval_rational_series(N,gseries,actuallen); for (n = 0; n < N; n++) { av[n].~cl_I(); pv[n].~cl_I(); qv[n].~cl_I(); } var cl_LF result = gsum/fsum - ln(cl_I_to_LF(sx,actuallen)); - return shorten(result,len); // verkürzen und fertig + return shorten(result,len); // verkürzen und fertig } // Bit complexity (N = len): O(N^2). // Memory consumption: O(N^2). @@ -407,7 +408,7 @@ struct cl_rational_series_for_g : cl_pqa_series_stream { }; const cl_LF compute_eulerconst_besselintegral3 (uintC len) { - var uintC actuallen = len+1; // 1 Schutz-Digit + var uintC actuallen = len+1; // 1 guard digit var uintC sx = (uintC)(0.25*0.693148*intDsize*actuallen)+1; var uintC N = (uintC)(3.591121477*sx); var cl_I x = square((cl_I)sx); @@ -423,17 +424,17 @@ const cl_LF compute_eulerconst_besselintegral3 (uintC len) init1(cl_I, qv[n]) ((cl_I)n*(cl_I)n); } var cl_pq_series fseries; - fseries.pv = pv; fseries.qv = qv; fseries.qsv = NULL; - var cl_LF fsum = eval_rational_series(N,fseries,actuallen); + fseries.pv = pv; fseries.qv = qv; + var cl_LF fsum = eval_rational_series(N,fseries,actuallen); for (n = 0; n < N; n++) { pv[n].~cl_I(); qv[n].~cl_I(); } // Evaluate g(x). var cl_rational_series_for_g gseries = cl_rational_series_for_g(x); - var cl_LF gsum = eval_rational_series(N,gseries,actuallen); + var cl_LF gsum = eval_rational_series(N,gseries,actuallen); var cl_LF result = gsum/fsum - ln(cl_I_to_LF(sx,actuallen)); - return shorten(result,len); // verkürzen und fertig + return shorten(result,len); // verkürzen und fertig } // Bit complexity (N = len): O(N^2). @@ -443,33 +444,38 @@ const cl_LF compute_eulerconst_besselintegral3 (uintC len) // the sums. const cl_LF compute_eulerconst_besselintegral4 (uintC len) { - var uintC actuallen = len+2; // 2 Schutz-Digits + var uintC actuallen = len+2; // 2 guard digits var uintC sx = (uintC)(0.25*0.693148*intDsize*actuallen)+1; var uintC N = (uintC)(3.591121477*sx); - var cl_I x = square((cl_I)sx); - CL_ALLOCA_STACK; - var cl_pqd_series_term* args = (cl_pqd_series_term*) cl_alloca(N*sizeof(cl_pqd_series_term)); - var uintC n; - for (n = 0; n < N; n++) { - init1(cl_I, args[n].p) (x); - init1(cl_I, args[n].q) (square((cl_I)(n+1))); - init1(cl_I, args[n].d) (n+1); - } - var cl_pqd_series_result sums; - eval_pqd_series_aux(N,args,sums); + var cl_I x = square(cl_I(sx)); + struct rational_series_stream : cl_pqd_series_stream { + uintC n; + cl_I x; + static cl_pqd_series_term computenext (cl_pqd_series_stream& thisss) + { + var rational_series_stream& thiss = (rational_series_stream&)thisss; + var uintC n = thiss.n; + var cl_pqd_series_term result; + result.p = thiss.x; + result.q = square(cl_I(n+1)); + result.d = n+1; + thiss.n = n+1; + return result; + } + rational_series_stream (uintC n_, const cl_I& x_) + : cl_pqd_series_stream (rational_series_stream::computenext), + n (n_), x (x_) {} + } series(0,x); + var cl_pqd_series_result sums; + eval_pqd_series_aux(N,series,sums,actuallen); // Instead of computing fsum = 1 + T/Q and gsum = V/(D*Q) // and then dividing them, to compute gsum/fsum, we save two // divisions by computing V/(D*(Q+T)). var cl_LF result = - cl_I_to_LF(sums.V,actuallen) - / The(cl_LF)(sums.D * cl_I_to_LF(sums.Q+sums.T,actuallen)) - - ln(cl_I_to_LF(sx,actuallen)); - for (n = 0; n < N; n++) { - args[n].p.~cl_I(); - args[n].q.~cl_I(); - args[n].d.~cl_I(); - } - return shorten(result,len); // verkürzen und fertig + cl_R_to_LF(sums.V,actuallen) + / The(cl_LF)(sums.D * cl_R_to_LF(sums.Q+sums.T,actuallen)) + - ln(cl_R_to_LF(sx,actuallen)); + return shorten(result,len); // verkürzen und fertig } // Bit complexity (N = len): O(log(N)^2*M(N)). @@ -501,22 +507,22 @@ const cl_LF compute_eulerconst (uintC len) const cl_LF eulerconst (uintC len) { - var uintC oldlen = TheLfloat(cl_LF_eulerconst)->len; // vorhandene Länge + var uintC oldlen = TheLfloat(cl_LF_eulerconst())->len; // vorhandene Länge if (len < oldlen) - return shorten(cl_LF_eulerconst,len); + return shorten(cl_LF_eulerconst(),len); if (len == oldlen) - return cl_LF_eulerconst; + return cl_LF_eulerconst(); - // TheLfloat(cl_LF_eulerconst)->len um mindestens einen konstanten Faktor - // > 1 wachsen lassen, damit es nicht zu häufig nachberechnet wird: + // TheLfloat(cl_LF_eulerconst())->len um mindestens einen konstanten Faktor + // > 1 wachsen lassen, damit es nicht zu häufig nachberechnet wird: var uintC newlen = len; oldlen += floor(oldlen,2); // oldlen * 3/2 if (newlen < oldlen) newlen = oldlen; - // gewünschte > vorhandene Länge -> muß nachberechnen: - cl_LF_eulerconst = compute_eulerconst(newlen); - return (len < newlen ? shorten(cl_LF_eulerconst,len) : cl_LF_eulerconst); + // gewünschte > vorhandene Länge -> muß nachberechnen: + cl_LF_eulerconst() = compute_eulerconst(newlen); + return (len < newlen ? shorten(cl_LF_eulerconst(),len) : cl_LF_eulerconst()); } } // namespace cln