]> www.ginac.de Git - cln.git/blobdiff - src/float/transcendental/cl_LF_eulerconst.cc
Use paths relative the `src' directory in the #include directives.
[cln.git] / src / float / transcendental / cl_LF_eulerconst.cc
index 1258f7566b56e30aba035e41a580944721f35300..c5965af901a6986e670cb1e7d8347c7cf5f254ed 100644 (file)
@@ -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<false>(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<false>(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<false>(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<false>(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<false>(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<cl_R> 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