X-Git-Url: https://ginac.de/CLN/cln.git//cln.git?a=blobdiff_plain;f=src%2Ffloat%2Ftranscendental%2Fcl_LF_ratsumseries_pqcd_aux.cc;h=91c0900beab50139910ad4f1171fa4b4ff32e53e;hb=8b3d91dec77438c0fe679b10869ab29e6cdeba58;hp=232214e75052aecededd849cc07ec51ed8bc312f;hpb=c84c6db5d56829d69083c819688a973867694a2a;p=cln.git diff --git a/src/float/transcendental/cl_LF_ratsumseries_pqcd_aux.cc b/src/float/transcendental/cl_LF_ratsumseries_pqcd_aux.cc index 232214e..91c0900 100644 --- a/src/float/transcendental/cl_LF_ratsumseries_pqcd_aux.cc +++ b/src/float/transcendental/cl_LF_ratsumseries_pqcd_aux.cc @@ -10,16 +10,17 @@ // Implementation. #include "cln/integer.h" -#include "cln/abort.h" +#include "cln/real.h" +#include "cln/exception.h" namespace cln { -void eval_pqcd_series_aux (uintC N, cl_pqcd_series_term* args, cl_pqcd_series_result& Z, cl_boolean rightmost) +void eval_pqcd_series_aux (uintC N, cl_pqcd_series_term* args, cl_pqcd_series_result& Z, bool rightmost) { // N = N2-N1 switch (N) { case 0: - cl_abort(); break; + throw runtime_exception(); break; case 1: if (!rightmost) { Z.P = args[0].p; } Z.Q = args[0].q; @@ -59,10 +60,10 @@ void eval_pqcd_series_aux (uintC N, cl_pqcd_series_term* args, cl_pqcd_series_re default: { var uintC Nm = N/2; // midpoint // Compute left part. - var cl_pqcd_series_result L; - eval_pqcd_series_aux(Nm,args+0,L,cl_false); + var cl_pqcd_series_result L; + eval_pqcd_series_aux(Nm,args+0,L,false); // Compute right part. - var cl_pqcd_series_result R; + var cl_pqcd_series_result R; eval_pqcd_series_aux(N-Nm,args+Nm,R,rightmost); // Put together partial results. if (!rightmost) { Z.P = L.P * R.P; } @@ -80,4 +81,160 @@ void eval_pqcd_series_aux (uintC N, cl_pqcd_series_term* args, cl_pqcd_series_re } } +void eval_pqcd_series_aux (uintC N, cl_pqcd_series_stream& args, cl_pqcd_series_result& Z, bool rightmost) +{ + // N = N2-N1 + switch (N) { + case 0: + throw runtime_exception(); break; + case 1: { + var cl_pqcd_series_term v0 = args.next(); // [N1] + if (!rightmost) { Z.P = v0.p; } + Z.Q = v0.q; + Z.T = v0.p; + if (!rightmost) { Z.C = v0.c; } + Z.D = v0.d; + Z.V = v0.c * v0.p; + break; + } + case 2: { + var cl_pqcd_series_term v0 = args.next(); // [N1] + var cl_pqcd_series_term v1 = args.next(); // [N1+1] + var cl_I p01 = v0.p * v1.p; + if (!rightmost) { Z.P = p01; } + Z.Q = v0.q * v1.q; + var cl_I p0q1 = v0.p * v1.q + p01; + Z.T = p0q1; + var cl_I c0d1 = v0.c * v1.d; + var cl_I c1d0 = v1.c * v0.d; + if (!rightmost) { Z.C = c0d1 + c1d0; } + Z.D = v0.d * v1.d; + Z.V = c0d1 * p0q1 + c1d0 * p01; + break; + } + case 3: { + var cl_pqcd_series_term v0 = args.next(); // [N1] + var cl_pqcd_series_term v1 = args.next(); // [N1+1] + var cl_pqcd_series_term v2 = args.next(); // [N1+2] + var cl_I p01 = v0.p * v1.p; + var cl_I p012 = p01 * v2.p; + if (!rightmost) { Z.P = p012; } + Z.Q = v0.q * v1.q * v2.q; + var cl_I p0q1 = v0.p * v1.q + p01; + Z.T = v2.q * p0q1 + p012; + var cl_I c0d1 = v0.c * v1.d; + var cl_I c1d0 = v1.c * v0.d; + var cl_I d01 = v0.d * v1.d; + if (!rightmost) { Z.C = (c0d1 + c1d0) * v2.d + v2.c * d01; } + Z.D = d01 * v2.d; + Z.V = v2.d * (v2.q * (c0d1 * p0q1 + c1d0 * p01) + (c0d1 + c1d0) * p012) + v2.c * d01 * p012; + break; + } + default: { + var uintC Nm = N/2; // midpoint + // Compute left part. + var cl_pqcd_series_result L; + eval_pqcd_series_aux(Nm,args,L,false); + // Compute right part. + var cl_pqcd_series_result R; + eval_pqcd_series_aux(N-Nm,args,R,rightmost); + // Put together partial results. + if (!rightmost) { Z.P = L.P * R.P; } + Z.Q = L.Q * R.Q; + // Z.S = L.S + L.P/L.Q*R.S; + var cl_I tmp = L.P * R.T; + Z.T = R.Q * L.T + tmp; + if (!rightmost) { Z.C = L.C * R.D + L.D * R.C; } + Z.D = L.D * R.D; + // Z.U = L.U + L.C/L.D * L.P/L.Q * R.S + L.P/L.Q * R.U; + // Z.V = R.D * R.Q * L.V + R.D * L.C * L.P * R.T + L.D * L.P * R.V; + Z.V = R.D * (R.Q * L.V + L.C * tmp) + L.D * L.P * R.V; + break; + } + } +} + +void eval_pqcd_series_aux (uintC N, cl_pqcd_series_stream& args, cl_pqcd_series_result& Z, uintC trunclen, bool rightmost) +{ + // N = N2-N1 + switch (N) { + case 0: + throw runtime_exception(); break; + case 1: { + var cl_pqcd_series_term v0 = args.next(); // [N1] + if (!rightmost) { Z.P = v0.p; } + Z.Q = v0.q; + Z.T = v0.p; + if (!rightmost) { Z.C = v0.c; } + Z.D = v0.d; + Z.V = v0.c * v0.p; + break; + } + case 2: { + var cl_pqcd_series_term v0 = args.next(); // [N1] + var cl_pqcd_series_term v1 = args.next(); // [N1+1] + var cl_I p01 = v0.p * v1.p; + if (!rightmost) { Z.P = p01; } + Z.Q = v0.q * v1.q; + var cl_I p0q1 = v0.p * v1.q + p01; + Z.T = p0q1; + var cl_I c0d1 = v0.c * v1.d; + var cl_I c1d0 = v1.c * v0.d; + if (!rightmost) { Z.C = c0d1 + c1d0; } + Z.D = v0.d * v1.d; + Z.V = c0d1 * p0q1 + c1d0 * p01; + break; + } + case 3: { + var cl_pqcd_series_term v0 = args.next(); // [N1] + var cl_pqcd_series_term v1 = args.next(); // [N1+1] + var cl_pqcd_series_term v2 = args.next(); // [N1+2] + var cl_I p01 = v0.p * v1.p; + var cl_I p012 = p01 * v2.p; + if (!rightmost) { Z.P = p012; } + Z.Q = v0.q * v1.q * v2.q; + var cl_I p0q1 = v0.p * v1.q + p01; + Z.T = v2.q * p0q1 + p012; + var cl_I c0d1 = v0.c * v1.d; + var cl_I c1d0 = v1.c * v0.d; + var cl_I d01 = v0.d * v1.d; + if (!rightmost) { Z.C = (c0d1 + c1d0) * v2.d + v2.c * d01; } + Z.D = d01 * v2.d; + Z.V = v2.d * (v2.q * (c0d1 * p0q1 + c1d0 * p01) + (c0d1 + c1d0) * p012) + v2.c * d01 * p012; + break; + } + default: { + var uintC Nm = N/2; // midpoint + // Compute left part. + var cl_pqcd_series_result L; + eval_pqcd_series_aux(Nm,args,L,trunclen,false); + // Compute right part. + var cl_pqcd_series_result R; + eval_pqcd_series_aux(N-Nm,args,R,trunclen,rightmost); + // Put together partial results. + if (!rightmost) { + Z.P = L.P * R.P; + truncate_precision(Z.P,trunclen); + } + Z.Q = L.Q * R.Q; + truncate_precision(Z.Q,trunclen); + // Z.S = L.S + L.P/L.Q*R.S; + var cl_R tmp = L.P * R.T; + Z.T = R.Q * L.T + tmp; + truncate_precision(Z.T,trunclen); + if (!rightmost) { + Z.C = L.C * R.D + L.D * R.C; + truncate_precision(Z.C,trunclen); + } + Z.D = L.D * R.D; + truncate_precision(Z.D,trunclen); + // Z.U = L.U + L.C/L.D * L.P/L.Q * R.S + L.P/L.Q * R.U; + // Z.V = R.D * R.Q * L.V + R.D * L.C * L.P * R.T + L.D * L.P * R.V; + Z.V = R.D * (R.Q * L.V + L.C * tmp) + L.D * L.P * R.V; + truncate_precision(Z.V,trunclen); + break; + } + } +} + } // namespace cln