|
Go to the documentation of this file.
33#include <clooptools.h>
42constexpr double EPSTOL = 1.0e-11;
43constexpr double TOL = 1e-4;
45constexpr double dabs( double a) noexcept { return a >= 0. ? a : -a; }
46constexpr double sqr( double a) noexcept { return a*a; }
47constexpr double pow3( double a) noexcept { return a*a*a; }
48constexpr double pow6( double a) noexcept { return sqr(pow3(a)); }
50constexpr bool is_zero( double m, double tol) noexcept
52 const double am = dabs(m);
53 const double mtol = tol * am;
55 if (mtol == 0.0 && am != 0.0 && tol != 0.0)
61constexpr bool is_close( double m1, double m2, double tol) noexcept
63 const double mmax = std::max( dabs(m1), dabs(m2));
64 const double mmin = std::min( dabs(m1), dabs(m2));
65 const double max_tol = tol * mmax;
67 if (max_tol == 0.0 && mmax != 0.0 && tol != 0.0)
68 return mmax - mmin <= tol;
70 return mmax - mmin <= max_tol;
73double sign( double x) noexcept
75 return x >= 0.0 ? 1.0 : -1.0;
79double fB( const std::complex<double>& x) noexcept
83 const double re = std::real(x);
84 const double im = std::imag(x);
86 if ((std::abs(re) == 0.0 || std::abs(re) == 1.0) && im == 0.0) {
90 return std::real(-1.0 + fast_log(1.0 - x) - x*fast_log(1.0 - 1.0/x));
94double fB( const std::complex<double>& xp, const std::complex<double>& xm) noexcept
98 const double rep = std::real(xp);
99 const double imp = std::imag(xp);
101 if ((std::abs(rep) == 0.0 || std::abs(rep) == 1.0) && imp == 0.0) {
102 return -1.0 + fB(xm);
105 const double rem = std::real(xm);
106 const double imm = std::imag(xm);
108 if ((std::abs(rem) == 0.0 || std::abs(rem) == 1.0) && imm == 0.0) {
109 return -1.0 + fB(xp);
112 return std::real(-2.0 + fast_log((1.0 - xp)*(1.0 - xm))
113 - xp*fast_log(1.0 - 1.0/xp) - xm*fast_log(1.0 - 1.0/xm));
125double a0( double m, double q) noexcept
127 return rea0(m*m, q*q);
139double rea0( double x, double q) noexcept
142 return std::numeric_limits<double>::quiet_NaN();
149 return x * (1 - 2*std::log(std::sqrt(std::abs(x/q))));
152double ffn( double p, double m1, double m2, double q) noexcept {
153 return a0(m1, q) - 2.0 * a0(m2, q) -
154 (2.0 * sqr(p) + 2.0 * sqr(m1) - sqr(m2)) *
158double gfn( double p, double m1, double m2, double q) noexcept {
159 return (sqr(p) - sqr(m1) - sqr(m2)) * b0(p, m1, m2, q) - a0(m1, q)
163double hfn( double p, double m1, double m2, double q) noexcept {
164 return 4.0 * b22(p, m1, m2, q) + gfn(p, m1, m2, q);
167double b22bar( double p, double m1, double m2, double q) noexcept {
168 return b22(p, m1, m2, q) - 0.25 * a0(m1, q) - 0.25 * a0(m2, q);
174double b0( double p, double m1, double m2, double q) noexcept
178 double b0l = B0(p*p, m1*m1, m2*m2).real();
192 if (is_zero(p, EPSTOL) && is_zero(m1, EPSTOL) && is_zero(m2, EPSTOL)) {
197 if (p > 1.0e-5 * m2) {
198 const double m12 = sqr(m1), m22 = sqr(m2), p2 = sqr(p);
199 const double s = p2 - m22 + m12;
200 const std::complex<double> imin(m12, -EPSTOL);
201 const std::complex<double> x = std::sqrt(sqr(s) - 4.0 * p2 * imin);
202 const std::complex<double> xp = (s + sign(s)*x) / (2*p2);
203 const std::complex<double> xm = imin / (xp*p2);
205 return -2.0*std::log(p/q) - fB(xp, xm);
208 if (is_close(m1, m2, EPSTOL)) {
209 return -2.0*std::log(m1/q);
213 return 1.0 - 2.0*std::log(m2/q);
216 const double m12 = sqr(m1), m22 = sqr(m2);
218 return 1.0 - 2.0 * std::log(m2/q)
219 + 2.0 * m12 * std::log(m2/m1) / (m12 - m22);
233double db0( double , double x, double y) noexcept
235 if ((std::abs(x) < 0.0001) != (std::abs(y) < 0.0001)) {
236 return (x + y)/(2*sqr(x - y));
237 } else if ((std::abs(x) < 0.0001) && (std::abs(y) < 0.0001)) {
239 } else if (std::abs(y - x) < 0.001) {
240 return (1./12*(1 - y/x) + 1./6)/x;
242 return ((x - y)*(x + y) + 2*x*y*std::log(y/x))/(2*pow3(x - y));
246double b1( double p, double m1, double m2, double q) noexcept
250 double b1l = -B1(p*p, m1*m1, m2*m2).real();
255 if (is_zero(p, EPSTOL) && is_zero(m1, EPSTOL) && is_zero(m2, EPSTOL))
258 const double p2 = sqr(p), m12 = sqr(m1), m22 = sqr(m2), q2 = sqr(q);
261 const double pTolerance = 1.0e-4;
263 if (p2 > pTolerance * std::max(m12, m22)) {
264 return ( a0(m2, q) - a0(m1, q) + (p2 + m12 - m22)
265 * b0(p, m1, m2, q)) / (2.0 * p2);
268 if (std::abs(m1) > 1.0e-15 && std::abs(m2) > 1.0e-15) {
269 const double m14 = sqr(m12), m24 = sqr(m22);
270 const double m16 = m12*m14 , m26 = m22*m24;
271 const double m18 = sqr(m14), m28 = sqr(m24);
272 const double p4 = sqr(p2);
273 const double diff = m12 - m22;
275 if (std::abs(diff) < pTolerance * std::max(m12, m22)) {
277 - 0.5*std::log(m22/q2)
278 + 1.0/12.0*p2/m22 + 1.0/120.0*p4/m24
279 + diff*(-1.0/6.0/m22 - 1.0/30.0*p2/m24 - 1.0/140.0*p4/m26)
280 + sqr(diff)*(1.0/24.0/m24 + 1.0/60.0*p2/m26 + 3.0/560.0*p4/m28);
283 const double l12 = std::log(m12/m22);
285 return (3*m14 - 4*m12*m22 + m24 - 2*m14*l12)/(4.*sqr(diff))
287 (2*m14 + 5*m12*m22 - m24) +
288 (3*m18 + 44*m16*m22 - 36*m14*m24 - 12*m12*m26 + m28)*p2
289 - 12*m14*m22*(2*sqr(diff) + (2*m12 + 3*m22)*p2)*l12))/
290 (24.*pow6(diff)) - 0.5*std::log(m22/q2);
294 ? -0.5*std::log(m12/q2) + 0.75
295 : -0.5*std::log(m22/q2) + 0.25;
298double b22( double p, double m1, double m2, double q) noexcept
302 double b22l = B00(p*p, m1*m1, m2*m2).real();
311 if (is_zero(p, EPSTOL) && is_zero(m1, EPSTOL) && is_zero(m2, EPSTOL))
315 const double p2 = sqr(p), m12 = sqr(m1), m22 = sqr(m2);
316 const double pTolerance = 1.0e-10;
318 if (p2 < pTolerance * std::max(m12, m22)) {
320 if (is_close(m1, m2, EPSTOL)) {
321 return -m12 * std::log(m1/q) + m12 * 0.5;
324 if (m1 > EPSTOL && m2 > EPSTOL) {
325 return 0.375 * (m12 + m22) - 0.5 *
326 (sqr(m22) * std::log(m2/q) -
327 sqr(m12) * std::log(m1/q)) / (m22 - m12);
330 ? 0.375 * m22 - 0.5 * m22 * std::log(m2/q)
331 : 0.375 * m12 - 0.5 * m12 * std::log(m1/q);
334 const double b0Save = b0(p, m1, m2, q);
335 const double a01 = a0(m1, q);
336 const double a02 = a0(m2, q);
339 (0.5 * (a01 + a02) + (m12 + m22 - 0.5 * p2)
340 * b0Save + (m22 - m12) / (2.0 * p2) *
341 (a02 - a01 - (m22 - m12) * b0Save) +
342 m12 + m22 - p2 / 3.0);
345double d0( double m1, double m2, double m3, double m4) noexcept
347 const double m1sq = sqr(m1);
348 const double m2sq = sqr(m2);
350 if (is_close(m1, m2, EPSTOL)) {
351 const double m3sq = sqr(m3);
352 const double m4sq = sqr(m4);
354 if (is_zero(m2, EPSTOL)) {
357 } else if (is_zero(m3, EPSTOL)) {
358 return (-m2sq + m4sq - m2sq * std::log(m4sq/m2sq))/
359 sqr(m2 * m2sq - m2 * m4sq);
360 } else if (is_zero(m4, EPSTOL)) {
361 return (-m2sq + m3sq - m2sq * std::log(m3sq/m2sq))/
362 sqr(m2 * m2sq - m2 * m3sq);
363 } else if (is_close(m2, m3, EPSTOL) && is_close(m2, m4, EPSTOL)) {
364 return 1.0 / (6.0 * sqr(m2sq));
365 } else if (is_close(m2, m3, EPSTOL)) {
366 return (sqr(m2sq) - sqr(m4sq) + 2.0 * m4sq * m2sq * std::log(m4sq / m2sq)) /
367 (2.0 * m2sq * sqr(m2sq - m4sq) * (m2sq - m4sq));
368 } else if (is_close(m2, m4, EPSTOL)) {
369 return (sqr(m2sq) - sqr(m3sq) + 2.0 * m3sq * m2sq * std::log(m3sq / m2sq)) /
370 (2.0 * m2sq * sqr(m2sq - m3sq) * (m2sq - m3sq));
371 } else if (is_close(m3, m4, EPSTOL)) {
372 return -1.0 / sqr(m2sq - m3sq) *
373 ((m2sq + m3sq) / (m2sq - m3sq) * std::log(m3sq / m2sq) + 2.0);
377 (m4sq / sqr(m2sq - m4sq) * std::log(m4sq / m2sq) +
378 m4sq / (m2sq * (m2sq - m4sq)) -
379 m3sq / sqr(m2sq - m3sq) * std::log(m3sq / m2sq) -
380 m3sq / (m2sq * (m2sq - m3sq))) / (m3sq - m4sq);
382 return ( c0(m1, m3, m4) - c0(m2, m3, m4)) / (m1sq - m2sq);
385double d27( double m1, double m2, double m3, double m4) noexcept
387 if (is_close(m1, m2, EPSTOL))
390 const double m12 = sqr(m1), m22 = sqr(m2);
392 return (m12 * c0(m1, m3, m4) - m22 * c0(m2, m3, m4))
393 / (4.0 * (m12 - m22));
396double c0( double m1, double m2, double m3) noexcept
402 double c0l = C0(psq, psq, psq, m1*m1, m2*m2, m3*m3).real();
405 const double m12 = sqr(m1), m22 = sqr(m2), m32 = sqr(m3);
406 const bool m1_is_zero = is_zero(m1, EPSTOL);
407 const bool m2_is_zero = is_zero(m2, EPSTOL);
408 const bool m3_is_zero = is_zero(m3, EPSTOL);
410 if ((m1_is_zero && m2_is_zero && m3_is_zero) ||
411 (m2_is_zero && m3_is_zero) ||
412 (m1_is_zero && m3_is_zero) ||
413 (m1_is_zero && m2_is_zero)) {
418 if (is_close(m2,m3,EPSTOL))
420 return std::log(m32/m22)/(m22 - m32);
424 if (is_close(m1,m3,EPSTOL))
426 return std::log(m32/m12)/(m12 - m32);
430 if (is_close(m1,m2,EPSTOL))
432 return std::log(m22/m12)/(m12 - m22);
435 if (is_close(m2, m3, EPSTOL)) {
436 if (is_close(m1, m2, EPSTOL))
438 return m12 / sqr(m12-m22) * std::log(m22/m12) + 1.0 / (m12 - m22);
441 if (is_close(m1, m2, EPSTOL)) {
442 return - (1.0 + m32 / (m22-m32) * std::log(m32/m22)) / (m22-m32);
445 if (is_close(m1, m3, EPSTOL)) {
446 return - (1.0 + m22 / (m32-m22) * std::log(m22/m32)) / (m32-m22);
449 return (m22 / (m12 - m22) * std::log(m22 / m12) -
450 m32 / (m12 - m32) * std::log(m32 / m12)) / (m22 - m32);
464double d1_b0( double , double m2a, double m2b) noexcept
469 if ((m2a < 0.0001) != (m2b < 0.0001)) {
470 return (m2a - m2b) * (m2a + m2b) / (2 * pow3(m2a - m2b));
471 } else if (m2a < 0.0001 && m2b < 0.0001) {
473 } else if (std::abs(m2b - m2a) < 0.001) {
474 return 1. / (6 * m2a) + (m2a - m2b) / (12 * sqr(m2a));
477 return ((m2a - m2b) * (m2a + m2b) + 2 * m2a * m2b * std::log(m2b / m2a)) /
478 (2 * pow3(m2a - m2b));
481double c00( double m1, double m2, double m3, double q) noexcept
484 const double m12 = sqr(m1), m22 = sqr(m2), m32 = sqr(m3), q2 = sqr(q);
488 if (is_close(m1, 0., EPSTOL) && is_close(m2, 0., EPSTOL)
489 && is_close(m3, 0., EPSTOL)) {
492 } else if (is_close(m2, 0., EPSTOL) && is_close(m3, 0., EPSTOL)) {
493 ans = 3./8. + 1./4*std::log(q2/m12);
494 } else if (is_close(m1, 0., EPSTOL) && is_close(m3, 0., EPSTOL)) {
495 ans = 3./8. + 1./4*std::log(q2/m22);
496 } else if (is_close(m1, 0., EPSTOL) && is_close(m2, 0., EPSTOL)) {
497 ans = 3./8. + 1./4*std::log(q2/m32);
498 } else if (is_close(m1, 0., EPSTOL)) {
499 if (is_close(m2, m3, EPSTOL)) {
500 ans = 1./8 + 1./4*std::log(q2/m22);
502 ans = 3./8 - m22*std::log(m22/m32)/(4*(m22-m32)) + 1./4*std::log(q2/m32);
504 } else if (is_close(m2, 0., EPSTOL)) {
505 if (is_close(m1, m3, EPSTOL)) {
506 ans = 1./8 + 1./4*std::log(q2/m12);
508 ans = 3./8 - m12*std::log(m12/m32)/(4*(m12-m32)) + 1./4*std::log(q2/m32);
510 } else if (is_close(m3, 0., EPSTOL)) {
511 if (is_close(m1, m2, EPSTOL)) {
512 ans = 1./8 + 1./4*std::log(q2/m12);
514 ans = 3./8 - m22*std::log(m12/m22)/(4*(m12-m22)) + 1./4*std::log(q2/m12);
516 } else if (is_close(m2, m3, EPSTOL)) {
517 if (is_close(m1, m2, EPSTOL)) {
518 ans = 1./4*std::log(q2/m12);
520 ans = (3*m12-m22)/(8*(m12-m22))
521 - 1./4*(sqr(m12)*std::log(m12/m22))/sqr(m12-m22) + 1./4*std::log(q2/m22);
523 } else if (is_close(m1, m2, EPSTOL)) {
524 ans = (3*m32-m12)/(8*(m32-m12)) - 1./4*(sqr(m32)*std::log(m32/m12))/sqr(m32-m12)
525 + 1./4*std::log(q2/m12);
526 } else if (is_close(m1, m3, EPSTOL)) {
527 ans = (3*m22-m12)/(8*(m22-m12)) - 1./4*(sqr(m22)*std::log(m22/m12))/sqr(m22-m12)
528 + 1./4*std::log(q2/m12);
530 ans = 3./8 - 1./4*sqr(m12)*std::log(m12/m32)/((m12-m22)*(m12-m32))
531 - 1./4*sqr(m22)*std::log(m22/m32)/((m22-m12)*(m22-m32)) + 1./4*std::log(q2/m32);
std::complex< T > fast_log(const std::complex< T > &z) noexcept fast implementation of complex logarithm
double fB(const std::complex< double > &x) noexcept
constexpr double pow6(double a) noexcept
constexpr double dabs(double a) noexcept
constexpr bool is_close(double m1, double m2, double tol) noexcept
Comment if you want default softsusy behaviour.
double gfn(double p, double m1, double m2, double q) noexcept
double b1(double p, double m1, double m2, double q) noexcept Note that b1 is NOT symmetric in m1 <-> m2!!!
double c00(double m1, double m2, double m3, double q) noexcept
double rea0(double x, double q) noexcept
double c0(double m1, double m2, double m3) noexcept
double a0(double m, double q) noexcept
double b22(double p, double m1, double m2, double q) noexcept
double d27(double m1, double m2, double m3, double m4) noexcept
double hfn(double p, double m1, double m2, double q) noexcept
double ffn(double p, double m1, double m2, double q) noexcept
double b22bar(double p, double m1, double m2, double q) noexcept
double b0(double p, double m1, double m2, double q) noexcept
double d0(double m1, double m2, double m3, double m4) noexcept
double db0(double, double x, double y) noexcept
double d1_b0(double, double m2a, double m2b) noexcept
void swap(nlohmann::basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType, CustomBaseClass > &j1, nlohmann::basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType, CustomBaseClass > &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp) is_nothrow_move_constructible< nlohmann::basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType, CustomBaseClass > >::value &&//NOLINT(misc-redundant-expression, cppcoreguidelines-noexcept-swap, performance-noexcept-swap) is_nothrow_move_assignable< nlohmann::basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType, CustomBaseClass > >::value) exchanges the values of two JSON objects
|