Himalaya
ThresholdLoopFunctions.cpp
Go to the documentation of this file.
1 // ====================================================================
2 // This file is part of FlexibleSUSY.
3 //
4 // FlexibleSUSY is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published
6 // by the Free Software Foundation, either version 3 of the License,
7 // or (at your option) any later version.
8 //
9 // FlexibleSUSY is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with FlexibleSUSY. If not, see
16 // <http://www.gnu.org/licenses/>.
17 // ====================================================================
18 
20 #include "himalaya/misc/Li2.hpp"
22 
23 #include <cmath>
24 #include <limits>
25 #include <utility>
26 
27 /**
28  * @file ThresholdLoopFunctions.cpp
29  * @brief Implementation of the loop functions from [arXiv:1407.4081]
30  * @note The file has been taken from FlexibleSUSY.
31  */
32 
33 namespace himalaya {
34 namespace mh2_eft {
35 namespace threshold_loop_functions {
36 namespace {
37  template <typename T> constexpr T sqr(T x) noexcept { return x*x; }
38  template <typename T> constexpr T cube(T x) noexcept { return x*x*x; }
39  template <typename T> constexpr T quad(T x) noexcept { return sqr(sqr(x)); }
40  template <typename T> constexpr T pow5(T x) noexcept { return quad(x) * x; }
41  template <typename T> constexpr T pow6(T x) noexcept { return sqr(sqr(x) * x); }
42  template <typename T> constexpr T pow7(T x) noexcept { return pow6(x) * x; }
43  template <typename T> constexpr T pow8(T x) noexcept { return sqr(quad(x)); }
44  template <typename T> constexpr T pow9(T x) noexcept { return pow8(x) * x; }
45 
46  double logx(double x) noexcept
47  {
48  if (is_zero(x, 10.0*std::numeric_limits<double>::epsilon())) {
49  return 0.;
50  }
51 
52  return std::log(x);
53  }
54 
55  double xlogx(double x) noexcept
56  {
57  if (is_zero(x, 1e-14)) {
58  return 0.;
59  }
60 
61  return x * std::log(x);
62  }
63 
64 } // anonymous namespace
65 
66 double F1(double x) noexcept
67 {
68  const double eps = std::numeric_limits<double>::epsilon();
69 
70  if (is_zero(x, eps)) {
71  return 0.;
72  }
73 
74  if (is_equal(x, 1., 0.01)) {
75  const double d = x - 1;
76  const double d2 = sqr(d);
77  return 1 + d2*(-1/6. + d*(1/6. - 2/15.*d));
78  }
79 
80  const double x2 = sqr(x);
81 
82  return x*std::log(x2)/(x2 - 1);
83 }
84 
85 double F2(double x) noexcept
86 {
87  const double eps = std::numeric_limits<double>::epsilon();
88 
89  if (is_zero(x, eps)) {
90  return 0.;
91  }
92 
93  if (is_equal(x, 1., 0.01)) {
94  const double d = (x - 1)*(x + 1);
95  const double d2 = sqr(d);
96  return 1 + d2*(-0.1 + d*(0.1 - 3/35.*d));
97  }
98 
99  const double x2 = sqr(x);
100 
101  return 6*x2*(2 - 2*x2 + (1 + x2)*std::log(x2))/cube(x2 - 1);
102 }
103 
104 double F3(double x) noexcept
105 {
106  const double eps = std::numeric_limits<double>::epsilon();
107 
108  if (is_zero(x, eps)) {
109  return 0.;
110  }
111 
112  if (is_equal(x, 1., 0.01)) {
113  const double d = x - 1;
114  return 1 + d*(5/9. + d*(-4/9. + d*(2/9. - 7/90.*d)));
115  }
116 
117  const double x2 = sqr(x);
118 
119  return 2*x*(5*(1 - x2) + (1 + 4*x2)*std::log(x2))/(3*sqr(x2 - 1));
120 }
121 
122 double F4(double x) noexcept
123 {
124  const double eps = std::numeric_limits<double>::epsilon();
125 
126  if (is_zero(x, eps)) {
127  return 0.;
128  }
129 
130  if (is_equal(x, 1., 0.01)) {
131  const double d = x - 1;
132  const double d2 = sqr(d);
133  return 1 + d*(-1/3. + d2*(2/15. - d/6.));
134  }
135 
136  const double x2 = sqr(x);
137 
138  return 2*x*(x2 - 1 - std::log(x2))/sqr(x2 - 1);
139 }
140 
141 double F5(double x) noexcept
142 {
143  const double eps = std::numeric_limits<double>::epsilon();
144 
145  if (is_zero(x, eps)) {
146  return 0.;
147  }
148 
149  if (is_equal(x, 1., 0.01)) {
150  const double d = x - 1;
151  const double d2 = sqr(d);
152  return 1 + d2*(-0.3 + d*(0.3 - 3/14.*d));
153  }
154 
155  if (is_equal(x, -1., 0.01)) {
156  const double d = x + 1;
157  const double d2 = sqr(d);
158  return -1 + d2*(0.3 + d*(0.3 + 3/14.*d));
159  }
160 
161  const double x2 = sqr(x);
162  const double x4 = sqr(x2);
163 
164  return 3*x*(1 - x4 + 2*x2*std::log(x2))/cube(1 - x2);
165 }
166 
167 double F6(double x) noexcept
168 {
169  const double eps = std::numeric_limits<double>::epsilon();
170 
171  if (is_zero(x, eps)) {
172  return -0.75;
173  }
174 
175  const double x2 = sqr(x);
176 
177  if (is_equal(x2, 1., 0.01)) {
178  const double d = (x - 1)*(x + 1);
179  return d*(1/3. + d*(-1/8. + d*(1/15. + d/24.)));
180  }
181 
182  return (x2 - 3)/(4*(1 - x2)) + x2*(x2 - 2)/(2*sqr(1 - x2))*std::log(x2);
183 }
184 
185 double F7(double x) noexcept
186 {
187  const double eps = std::numeric_limits<double>::epsilon();
188 
189  if (is_zero(x, eps)) {
190  return -1.5;
191  }
192 
193  const double x2 = sqr(x);
194 
195  if (is_equal(x2, 1., 0.01)) {
196  const double d = (x - 1)*(x + 1);
197  return 1 + d*(3/2. + d*(-9/20. + d*(0.2 - 3/28.*d)));
198  }
199 
200  const double x4 = sqr(x2);
201 
202  return -3*(x4 - 6*x2 + 1)/(2*sqr(x2 - 1))
203  + 3*x4*(x2 - 3)/cube(x2 - 1)*std::log(x2);
204 }
205 
206 /// F8(x1,x2) in the limit x1 -> 1 and x2 -> 1
207 static double F8_1_1(double x1, double x2) noexcept
208 {
209  const double d1 = (x1 - 1)*(x1 + 1);
210  const double d2 = (x2 - 1)*(x2 + 1);
211  const double d12 = sqr(d1);
212  const double d22 = sqr(d2);
213  const double d13 = d1*d12;
214  const double d23 = d2*d22;
215  const double d14 = sqr(d12);
216  const double d24 = sqr(d22);
217 
218  return 1 + 2/3.*(d1 + d2) + 1/6.*(-d12 - d1*d2 - d22)
219  + (d13 + d12*d2 + d1*d22 + d23)/15.
220  + (-d14 - d13*d2 - d12*d22 - d1*d23 - d24)/30.;
221 }
222 
223 /// F8(x1,x2) in the limit x1 -> 1, x2 != 1
224 static double F8_1_x2(double x1, double x2) noexcept
225 {
226  const double x22 = sqr(x2);
227  const double d = (x1 - 1)*(x1 + 1);
228 
229  if (is_zero(x2, 0.01)) {
230  return 2*x22 + d*(1 - x22 + d*(-1/3. + 2/3.*x22));
231  }
232 
233  const double d2 = sqr(d);
234  const double d3 = d*d2;
235  const double d4 = sqr(d2);
236  const double y = (x2 - 1)*(x2 + 1);
237  const double y2 = sqr(y);
238  const double y3 = y*y2;
239  const double y4 = sqr(y2);
240  const double y5 = y2*y3;
241  const double y6 = sqr(y3);
242  const double lx22 = std::log(x22);
243 
244  return
245  - 2 + 2*(1 + x22*(-1 + lx22*x22))/y2
246  + d*(-1 + x22*(4 + x22*(-3 + 2*lx22)))/y3
247  + d2*(-1 + x22*(6 + x22*(-3 + 6*lx22 + -2*x22)))/(3*y4)
248  + d3*(-1 + x22*(8 + x22*(12*lx22 + x22*(-8 + x22))))/(6*y5)
249  + d4*(-3 + x22*(30 + x22*(20 + 60*lx22 + x22*(-60 + x22*(15 - 2*x22)))))/(30*y6);
250 }
251 
252 /// F8(x1,x2) in the limit x1 -> 0, x2 != 0
253 static double F8_0_x2(double x1, double x2) noexcept
254 {
255  const double x12 = sqr(x1);
256  const double x22 = sqr(x2);
257  const double lx22 = std::log(x22);
258 
259  return 2*(1 - x22 + (x12 + x22)*lx22)/(-1 + x22);
260 }
261 
262 // F8(x1,x2) in the limit x1 -> x2, x2 != 1
263 static double F8_x1_x2(double x1, double x2) noexcept
264 {
265  const double x22 = sqr(x2);
266  const double d = (x1 - x2)*(x1 + x2);
267  const double d2 = sqr(d);
268  const double d3 = d*d2;
269  const double y = (x2 - 1)*(x2 + 1);
270  const double y2 = sqr(y);
271  const double y3 = y*y2;
272  const double y4 = sqr(y2);
273  const double y5 = y2*y3;
274  const double lx22 = std::log(x22);
275 
276  return
277  + 2*((-2 + x22)*x22*lx22 + y)/y2
278  + d*(3 + x22*(-4 + x22) + 2*lx22)/y3
279  + d2*(-2 + x22*(-3 - 6*lx22 + x22*(6 - x22)))/(3*x22*y4)
280  + d3*(-1 + x22*(8 + x22*(12*lx22 + x22*(-8 + x22))))/(6*x22*x22*y5);
281 }
282 
283 double F8(double x1, double x2) noexcept
284 {
285  const double eps = 10.*std::numeric_limits<double>::epsilon();
286 
287  if (is_zero(x1, eps) && is_zero(x2, eps)) {
288  return -2.;
289  }
290 
291  const double ax1 = std::fabs(x1);
292  const double ax2 = std::fabs(x2);
293 
294  if (is_equal(ax1, 1., 0.01) && is_equal(ax2, 1., 0.01)) {
295  return F8_1_1(x1, x2);
296  }
297 
298  if (is_equal(ax1, 1., 0.01)) {
299  return F8_1_x2(x1, x2);
300  }
301 
302  if (is_equal(ax2, 1., 0.01)) {
303  return F8_1_x2(x2, x1);
304  }
305 
306  if (is_zero(x1, 0.00001)) {
307  return F8_0_x2(x1, x2);
308  }
309 
310  if (is_zero(x2, 0.00001)) {
311  return F8_0_x2(x2, x1);
312  }
313 
314  if (is_equal(ax1, ax2, 0.00001)) {
315  return F8_x1_x2(x1, x2);
316  }
317 
318  const double x12 = sqr(x1);
319  const double x22 = sqr(x2);
320  const double x14 = sqr(x12);
321  const double x24 = sqr(x22);
322 
323  return -2. + 2./(x12 - x22)*(
324  + x14/(x12 - 1)*std::log(x12)
325  - x24/(x22 - 1)*std::log(x22));
326 }
327 
328 /// F9(x1,x2) in the limit x1 -> 1 and x2 -> 1
329 static double F9_1_1(double x1, double x2) noexcept
330 {
331  const double d1 = (x1 - 1)*(x1 + 1);
332  const double d2 = (x2 - 1)*(x2 + 1);
333  const double d12 = sqr(d1);
334  const double d22 = sqr(d2);
335  const double d13 = d1*d12;
336  const double d23 = d2*d22;
337  const double d14 = sqr(d12);
338  const double d24 = sqr(d22);
339 
340  return 1
341  + 1/3.*(-d2 - d1)
342  + 1/6.*(d12 + d1*d2 + d22)
343  + 1/10.*(-d13 - d12*d2 - d1*d22 - d23)
344  + 1/15.*(d14 + d13*d2 + d12*d22 + d1*d23 + d24);
345 }
346 
347 /// F9(x1,x2) in the limit x1 -> 1
348 static double F9_1_x2(double x1, double x2) noexcept
349 {
350  const double x22 = sqr(x2);
351  const double d = (x1 - 1)*(x1 + 1);
352  const double d2 = sqr(d);
353  const double d3 = d*d2;
354  const double d4 = sqr(d2);
355  const double y = (x2 - 1)*(x2 + 1);
356  const double y2 = sqr(y);
357  const double y3 = y*y2;
358  const double y4 = sqr(y2);
359  const double y5 = y2*y3;
360  const double y6 = sqr(y3);
361  const double lx22 = std::log(x22);
362 
363  if (is_zero(x2, 0.01)) {
364  return 2 + d;
365  }
366 
367  return
368  + 2*(1 + x22*(-1 + lx22))/y2
369  + d*(1 + x22*(2*lx22 - x22))/y3
370  + d2*(2 + x22*(3 + 6*lx22 + x22*(-6 + x22)))/(3*y4)
371  + d3*(3 + x22*(10 + 12*lx22 + x22*(-18 + x22*(6 - x22))))/(6*y5)
372  + d4*(12 + x22*(65 + 60*lx22 + x22*(-120 + x22*(60 + x22*(-20 + 3*x22)))))/(30*y6);
373 }
374 
375 /// F9(x1,x2) in the limit x1 -> 0, x2 != 1, x2 != 0
376 static double F9_0_x2(double /* x1 */, double x2) noexcept
377 {
378  const double x22 = sqr(x2);
379 
380  return 2*std::log(x22)/(-1 + x22);
381 }
382 
383 /// F9(x1,x2) in the limit x1 -> x2, x2 != 0
384 static double F9_x1_x2(double x1, double x2) noexcept
385 {
386  const double x22 = sqr(x2);
387  const double d = (x1 - x2)*(x1 + x2);
388  const double d2 = sqr(d);
389  const double d3 = d*d2;
390  const double y = (x2 - 1)*(x2 + 1);
391  const double y2 = sqr(y);
392  const double y3 = y*y2;
393  const double y4 = sqr(y2);
394  const double y5 = y2*y3;
395  const double lx22 = std::log(x22);
396 
397  return
398  + 2*(y - lx22)/y2
399  + d*(1 + x22*(2*lx22 - x22))/(x22*y3)
400  + d2*(1 + x22*(-6 + x22*(3 - 6*lx22 + 2*x22)))/(3*x22*x22*y4)
401  + d3*(1 + x22*(-6 + x22*(18 + x22*(-10 + 12*lx22 - 3*x22))))/(6*x22*x22*x22*y5);
402 }
403 
404 double F9(double x1, double x2) noexcept
405 {
406  const double ax1 = std::fabs(x1);
407  const double ax2 = std::fabs(x2);
408 
409  if (is_equal(ax1, 1., 0.01) && is_equal(ax2, 1., 0.01)) {
410  return F9_1_1(x1, x2);
411  }
412 
413  if (is_equal(ax1, 1., 0.01)) {
414  return F9_1_x2(x1, x2);
415  }
416 
417  if (is_equal(ax2, 1., 0.01)) {
418  return F9_1_x2(x2, x1);
419  }
420 
421  if (is_zero(x1, 0.0001)) {
422  return F9_0_x2(x1, x2);
423  }
424 
425  if (is_zero(x2, 0.0001)) {
426  return F9_0_x2(x2, x1);
427  }
428 
429  if (is_equal(ax1, ax2, 0.00001)) {
430  return F9_x1_x2(x1, x2);
431  }
432 
433  const double x12 = sqr(x1);
434  const double x22 = sqr(x2);
435 
436  return 2/(x12 - x22)*(
437  + x12/(x12 - 1)*std::log(x12)
438  - x22/(x22 - 1)*std::log(x22));
439 }
440 
441 double f(double r) noexcept
442 {
443  return F5(r);
444 }
445 
446 double g(double r) noexcept
447 {
448  return F7(r);
449 }
450 
451 double f1(double r) noexcept
452 {
453  const double r2 = sqr(r);
454 
455  if (is_zero(r, 0.01)) {
456  return 18./7.*r2;
457  }
458 
459  const double d = r2 - 1;
460 
461  if (is_equal(std::fabs(r), 1., 0.01)) {
462  return 1 + d*(4/7. + d*(-13/70. + d*(3/35. - 23/490.*d)));
463  }
464 
465  const double d2 = sqr(d);
466  const double d3 = d*d2;
467 
468  return 6*(r2 + 3)*r2/(7*d2) + 6*(r2 - 5)*sqr(r2)*std::log(r2)/(7*d3);
469 }
470 
471 double f2(double r) noexcept
472 {
473  const double r2 = sqr(r);
474 
475  if (is_zero(r, 0.01)) {
476  return 22./9.*r2;
477  }
478 
479  const double d = r2 - 1;
480 
481  if (is_equal(std::fabs(r), 1., 0.01)) {
482  return 1 + d*(16/27. + d*(-49/270. + d*(11/135. - 83/1890.*d)));
483  }
484 
485  const double d2 = sqr(d);
486  const double d3 = d*d2;
487 
488  return 2*(r2 + 11)*r2/(9*d2) + 2*(5*r2 - 17)*sqr(r2)*std::log(r2)/(9*d3);
489 }
490 
491 double f3(double r) noexcept
492 {
493  if (is_zero(r, 1e-6)) {
494  return 4./3.;
495  }
496 
497  const double r2 = sqr(r);
498  const double d = r2 - 1;
499 
500  if (is_equal(std::fabs(r), 1., 0.01)) {
501  return 1 + d*(2/9. + d*(1/90. + d*(-2/45. + 29/630.*d)));
502  }
503 
504  const double r4 = sqr(r2);
505  const double d2 = sqr(d);
506  const double d3 = d*d2;
507 
508  return 2*(r4 + 9*r2 + 2)/(3*d2) + 2*(r4 - 7*r2 - 6)*r2*std::log(r2)/(3*d3);
509 }
510 
511 double f4(double r) noexcept
512 {
513  if (is_zero(r, 1e-6)) {
514  return 12./7.;
515  }
516 
517  const double r2 = sqr(r);
518  const double d = r2 - 1;
519 
520  if (is_equal(std::fabs(r), 1., 0.01)) {
521  return 1 + d*(2/21. + d*(13/210. + d*(-8/105. + 101/1470.*d)));
522  }
523 
524  const double r4 = sqr(r2);
525  const double d2 = sqr(d);
526  const double d3 = d*d2;
527 
528  return 2*(5*r4 + 25*r2 + 6)/(7*d2) + 2*(r4 - 19*r2 - 18)*r2*std::log(r2)/(7*d3);
529 }
530 
531 /// f5(r1,r2) in the limit r1 -> 0, r2 -> 0
532 static double f5_0_0(double r1, double r2) noexcept
533 {
534  if (is_zero(r1, 1e-6) && is_zero(r2, 1e-6)) {
535  return 0.75;
536  }
537 
538  if (std::abs(r1) > std::abs(r2)) {
539  std::swap(r1, r2);
540  }
541 
542  const double r12 = sqr(r1);
543  const double r22 = sqr(r2);
544  const double r2lr2 = xlogx(r2);
545  const double lr2 = logx(r2);
546 
547  // expansion of f5 in
548  // r1 up to (including) r1^2
549  // r2 up to (including) r1^3
550  return 0.75*(
551  + 1
552  + 2*r1*(r2 + r2lr2)
553  + 2*r22 + 2*r2*r2lr2
554  + r12*(2 + 2*lr2 + r2*(2*r2 + 6*r2lr2))
555  + r1*r22*(6*r2lr2 + 2*r2)
556  );
557 }
558 
559 /// f5(r1,r2) in the limit r1 -> 1 and r2 -> 1
560 static double f5_1_1(double r1, double r2) noexcept
561 {
562  const double d1 = r1 - 1;
563  const double d2 = r2 - 1;
564  const double d12 = sqr(d1);
565  const double d22 = sqr(d2);
566  const double d13 = d1*d12;
567  const double d23 = d2*d22;
568  const double d14 = sqr(d12);
569  const double d24 = sqr(d22);
570 
571  return 1
572  + 3./8.*(d1 + d2)
573  + 1./40.*(d12 + d1*d2 + d22)
574  + 1./20.*(-d13 - d12*d2 - d1*d22 - d23)
575  + 1./280.*(9*(d14 + d13*d2 + d12*d22 + d1*d23 + d24));
576 }
577 
578 /// f5(r1,r2) in the limit r1 -> 1, r2 != 1
579 static double f5_1_r2(double r1, double r2) noexcept
580 {
581  if (is_zero(r2, 0.01)) {
582  const double d = r1 - 1;
583  return 0.75*(1 + d*(1./3. + d/6. + r2/3.));
584  }
585 
586  const double d1 = r1 - 1;
587  const double d2 = r2 - 1;
588  const double d12 = sqr(d1);
589  const double d13 = d12*d1;
590  const double d14 = d13*d1;
591  const double d22 = sqr(d2);
592  const double d23 = d22*d2;
593  const double d24 = d23*d2;
594  const double d25 = d24*d2;
595  const double d26 = d25*d2;
596  const double d27 = d26*d2;
597  const double y = 1 + r2;
598  const double y2 = sqr(y);
599  const double r22 = sqr(r2);
600  const double lr22 = std::log(r22);
601 
602  return
603  + (-3 + r2*(3 + r2*(6 + r2*(3*lr22 + r2*(-3 + (-3 + 3*lr22)*r2)))))/(4.*d23*y2)
604  + d1*(1 + r2*(-1 + r2*(-2 + r2*(8 + 3*lr22 + r2*(1 + (-7 + 3*lr22)*r2)))))/(4.*d24*y2)
605  + d12*(-1 + r2*(4 + r2*(-1 + r2*(4 + 6*lr22 + r2*(5 + (-8 + 6*lr22 - 3*r2)*r2)))))/(8.*d25*y2)
606  + d13*(-4 + r2*(17 + r2*(-4 + r2*(25 + 30*lr22 + r2*(20 + r2*(-41 + 30*lr22 + (-12 - r2)*r2))))))/(40.*d26*y2)
607  + d14*(-2 + r2*(9 + r2*(4 + r2*(33 + 30*lr22 + r22*(-33 + 30*lr22 + r2*(-4 + r2*(-9 + 2*r2)))))))/(40.*d27*y2);
608 }
609 
610 /// f5(r1,r2) in the limit r1 -> 0
611 static double f5_0_r2(double r1, double r2) noexcept
612 {
613  const double r22 = sqr(r2);
614  const double lr22 = std::log(r22);
615 
616  // expansion in terms of r1 around r1 = 0 up to maximum possible
617  // power such that no IR-divergent terms appear (e.g. log(r1))
618  const double res =
619  (1 + r22*(lr22 + (-1 + lr22)*r22)
620  + r1*(r1*(2 + lr22 + (-2 + lr22)*r22) + r2*(2 + lr22 + (-2 + lr22)*r22)))/sqr(-1 + r22);
621 
622  return 0.75 * res;
623 }
624 
625 /// f5(r1,r2) in the limit r1 -> r2
626 static double f5_r1_r2(double r1, double r2) noexcept
627 {
628  const double d = r1 - r2;
629  const double d2 = sqr(d);
630  const double d3 = d2*d;
631  const double r22 = sqr(r2);
632  const double y = r22 - 1;
633  const double y3 = sqr(y)*y;
634  const double y4 = y3*y;
635  const double y5 = y4*y;
636  const double y6 = y5*y;
637  const double lr22 = std::log(r22);
638 
639  return 0.75*(
640  + (-1 + r22*(-5 - 3*lr22 + r22*(5 - 6*lr22 + (1 + lr22)*r22)))/y3
641  + d*r2*(11 + 3*lr22 + r22*(3 + 18*lr22 + r22*(-15 + 3*lr22 + r22)))/y4
642  + d2*(-17 - 3*lr22 + r22*(-116 - 75*lr22 + r22*(90 - 105*lr22 + r22*(44 - 9*lr22 - r22))))/(3.*y5)
643  + d3*(3 + r22*(273 + 90*lr22 + r22*(314 + 510*lr22 + r22*(-498 + 342*lr22 + r22*(-93 + 18*lr22 + r22)))))/(6.*r2*y6)
644  );
645 }
646 
647 double f5(double r1, double r2) noexcept
648 {
649  const double eps_zero = 1e-4;
650  const double eps_one = 1e-2;
651 
652  if (is_zero(r1, eps_zero) && is_zero(r2, eps_zero)) {
653  return f5_0_0(r1, r2);
654  }
655 
656  if (is_equal(r1, 1., eps_one) && is_equal(r2, 1., eps_one)) {
657  return f5_1_1(r1, r2);
658  }
659 
660  if (is_equal(r1, -1., eps_one) && is_equal(r2, -1., eps_one)) {
661  return f5_1_1(-r1, -r2);
662  }
663 
664  if (is_equal(r1, 1., eps_one)) {
665  return f5_1_r2(r1, r2);
666  }
667 
668  if (is_equal(r2, 1., 0.01)) {
669  return f5_1_r2(r2, r1);
670  }
671 
672  if (is_zero(r1, eps_zero)) {
673  return f5_0_r2(r1, r2);
674  }
675 
676  if (is_zero(r2, eps_zero)) {
677  return f5_0_r2(r2, r1);
678  }
679 
680  if (is_equal(r1, r2, 0.0001)) {
681  return f5_r1_r2(r2, r1);
682  }
683 
684  const double r12 = sqr(r1);
685  const double r22 = sqr(r2);
686 
687  const double result
688  = (1 + sqr(r1 + r2) - r12*r22)/((r12 - 1)*(r22 - 1))
689  + (cube(r1)*(r12 + 1)*std::log(r12))/(sqr(r12 - 1)*(r1 - r2))
690  - (cube(r2)*(r22 + 1)*std::log(r22))/((r1 - r2)*sqr(r22 - 1));
691 
692  return 0.75 * result;
693 }
694 
695 /// f6(r1,r2) in the limit r1 -> 0 and r2 -> 0
696 static double f6_0_0(double r1, double r2) noexcept
697 {
698  if (is_zero(r1, 1e-10) && is_zero(r2, 1e-10)) {
699  return 0.;
700  }
701 
702  const double r22 = sqr(r2);
703  const double lr22 = std::log(r22);
704 
705  const double res =
706  r22*(1 + (1 + lr22)*r22)
707  + r1*(r2*(1 + (1 + lr22)*r22)
708  + r1*(1 + r22*(1 + lr22 + (1 + 2*lr22)*r22)
709  + r1*(r2*(1 + lr22 + (1 + 2*lr22)*r22)
710  + r1*(1 + lr22 + r22*(1 + 2*lr22 + (1 + 3*lr22)*r22)))));
711 
712  return 6./7.*res;
713 }
714 
715 /// f6(r1,r2) in the limit r1 -> 1 and r2 -> 1
716 static double f6_1_1(double r1, double r2) noexcept
717 {
718  const double d1 = r1 - 1;
719  const double d2 = r2 - 1;
720 
721  return
722  1 + d2*(4./7 + d2*(-2./35 + (-1./70 + 9.*d2/490)*d2)) +
723  d1*(4./7 + d2*(-2./35 + d2*(-1./70 + (9./490 - 3.*d2/245)*d2)) +
724  d1*(-2./35 + d2*(-1./70 + d2*(9./490 + (-3./245 + d2/147)*d2)) +
725  d1*(-1./70 + d2*(9./490 + d2*(-3./245 + (1./147 - d2/294)*d2)) +
726  d1*(9./490 + d2*(-3./245 + d2*(1./147 + (-1./294 + 5.*d2/3234)*d2))))));
727 }
728 
729 /// f6(r1,r2) in the limit r1 -> 0 and r2 -> 1
730 static double f6_0_1(double r1, double r2) noexcept
731 {
732  const double d2 = r2 - 1;
733  const double d22 = sqr(d2);
734 
735  return
736  + 3./7 + d2*(4./7 + (-2./35 + 3.*d2/70)*d22)
737  + r1*(3./7 + d2*(1./7 + d2*(-1./7 + (3./35 - 3.*d2/70)*d2))
738  + r1*(3./7 + d2*(-2./7 + d2*(1./7 + (-2./35 + d2/70)*d2))
739  + r1*(-3./7 + d2*(1./7 + (-2./35 + d2/14)*d22)
740  + r1*(-3./7 + d2*(4./7 + d2*(-4./7 + (18./35 - 31.*d2/70)*d2))))));
741 }
742 
743 /// f6(r1,r2) in the limit r1 -> 1
744 static double f6_1_r2(double r1, double r2) noexcept
745 {
746  if (is_zero(r2, 1e-4)) {
747  return f6_0_1(r2, r1);
748  }
749 
750  const double r22 = sqr(r2);
751  const double lr22 = std::log(r22);
752  const double y = 1 + r2;
753  const double y2 = sqr(y);
754  const double z = r2 - 1;
755  const double z2 = sqr(z);
756  const double z3 = z2*z;
757  const double z4 = z3*z;
758  const double z5 = z4*z;
759  const double z6 = z5*z;
760  const double z7 = z6*z;
761  const double d = r1 - 1;
762  const double d2 = sqr(d);
763  const double d3 = d2*d;
764  const double d4 = d3*d;
765 
766  return
767  (-3 + r22*(6 + r2*(6 + r2*(-3 + r2*(-6 + 6*lr22)))))/(7.*z3*y2)
768  + d*(4 + r2*(-7 + r2*(-8 + r2*(20 + r2*(4 + r2*(-13 + 6*lr22))))))/(7.*z4*y2)
769  + d2*r2*(1 + r2*(-4 + r2*(4 + r2*(8 + r2*(-5 - 4*r2 + 6*lr22)))))/(7.*z5*y2)
770  + d3*(-2 + r2*(11 + r2*(-22 + r2*(10 + r2*(50 + r2*(-23 + r2*(-26 + 2*r2) + 30*lr22))))))/(35.*z6*y2)
771  + d4*(-3 + r2*(18 + r2*(-40 + r2*(24 + r2*(90 + r2*(-42 + r2*(-48 + r22) + 60*lr22))))))/(70.*z7*y2);
772 }
773 
774 /// f6(r1,r2) in the limit r1 -> 0
775 static double f6_0_r2(double r1, double r2) noexcept
776 {
777  const double r22 = sqr(r2);
778  const double lr22 = std::log(r22);
779 
780  return
781  6./7.*(r22*(1 + (-1 + lr22)*r22)
782  + r1*(r2*(1 + (-1 + lr22)*r22)
783  + r1*(1 + (-1 + lr22)*r22
784  + r1*(r1*(1 + lr22 - r22) + r2*(1 + lr22 - r22)))))/sqr(-1 + r22);
785 }
786 
787 // f6(r1,r2) in the limit r1 -> r2
788 static double f6_r1_r2(double r1, double r2) noexcept
789 {
790  const double d = r1 - r2;
791  const double d2 = sqr(d);
792  const double d3 = d2*d;
793  const double d4 = d3*d;
794  const double r22 = sqr(r2);
795  const double y = r22 - 1;
796  const double y2 = sqr(y);
797  const double y3 = y2*y;
798  const double y4 = y3*y;
799  const double y5 = y4*y;
800  const double y6 = y5*y;
801  const double y7 = y6*y;
802  const double lr22 = std::log(r22);
803 
804  return
805  6./7. * (
806  r22*(-3 + r22*(2 - 5*lr22 + (1 + lr22)*r22))/y3
807  + d*r2*(3 + r22*(7 + 10*lr22 + r22*(-11 + 2*lr22 + r22)))/y4
808  + d2*(-3 + r22*(-62 - 30*lr22 + r22*(36 - 60*lr22 + r22*(30 - 6*lr22 - r22))))/(3.*y5)
809  + d3*r2*(107 + 30*lr22 + r22*(206 + 240*lr22 + r22*(-252 + 198*lr22 + r22*(-62 + 12*lr22 + r22))))/(6.*y6)
810  + d4*(-167 - 30*lr22 + r22*(-2215 - 1050*lr22 + r22*(-510 - 3150*lr22 + r22*(2570 - 1470*lr22 + r22*(325 - 60*lr22 - 3*r22)))))/(30.*y7)
811  );
812 }
813 
814 double f6(double r1, double r2) noexcept
815 {
816  const double eps_zero = 1e-4;
817 
818  if (is_zero(r1, eps_zero) && is_zero(r2, eps_zero)) {
819  return f6_0_0(r1, r2);
820  }
821 
822  if (is_equal(r1, 1., 0.02) && is_equal(r2, 1., 0.02)) {
823  return f6_1_1(r1, r2);
824  }
825 
826  if (is_equal(r1, -1., 0.02) && is_equal(r2, -1., 0.02)) {
827  return f6_1_1(-r1, -r2);
828  }
829 
830  if (is_equal(r1, 1., 0.001)) {
831  return f6_1_r2(r1, r2);
832  }
833 
834  if (is_equal(r2, 1., 0.001)) {
835  return f6_1_r2(r2, r1);
836  }
837 
838  if (is_zero(r1, eps_zero)) {
839  return f6_0_r2(r1, r2);
840  }
841 
842  if (is_zero(r2, eps_zero)) {
843  return f6_0_r2(r2, r1);
844  }
845 
846  if (is_equal(r1, r2, 1e-4)) {
847  return f6_r1_r2(r2, r1);
848  }
849 
850  const double r12 = sqr(r1);
851  const double r22 = sqr(r2);
852 
853  const double result
854  = (r12 + r22 + r1*r2 - r12*r22)/((r12 - 1)*(r22 - 1))
855  + (pow5(r1)*std::log(r12))/(sqr(r12 - 1)*(r1 - r2))
856  - (pow5(r2)*std::log(r22))/((r1 - r2)*sqr(r22 - 1));
857 
858  return 6./7. * result;
859 }
860 
861 /// f7(r1,r2) in the limit r1 -> 0, r2 -> 0
862 static double f7_0_0(double r1, double r2) noexcept
863 {
864  if (is_zero(r1, 1e-6) && is_zero(r2, 1e-6)) {
865  return 6.;
866  }
867 
868  if (std::abs(r1) > std::abs(r2)) {
869  std::swap(r1, r2);
870  }
871 
872  const double r22 = sqr(r2);
873  const double lr22 = std::log(r22);
874 
875  const double res =
876  1 + (1 + lr22)*r22
877  + r1*((1 + lr22)*r2 + r1*(1 + lr22 + (1 + 2*lr22)*r22));
878 
879  return 6*res;
880 }
881 
882 /// f7(r1,r2) in the limit r1 -> 1 and r2 -> 1
883 static double f7_1_1(double r1, double r2) noexcept
884 {
885  const double d1 = r1 - 1;
886  const double d2 = r2 - 1;
887 
888  return
889  1 + d2*(-1 + d2*(3./5 + (-3./10 + 9.*d2/70)*d2))
890  + d1*(-1 + d2*(3./5 + d2*(-3./10 + (9./70 - 3.*d2/70)*d2))
891  + d1*(3./5 + d2*(-3./10 + d2*(9./70 + (-3./70 + d2/210)*d2))
892  + d1*(-3./10 + d2*(9./70 + d2*(-3./70 + (1./210 + d2/105)*d2))
893  + d1*(9./70 + d2*(-3./70 + d2*(1./210 + (1./105 - d2/77)*d2))))));
894 }
895 
896 /// f7(r1,r2) in the limit r1 -> 0 and r2 -> 1
897 static double f7_0_1(double r1, double r2) noexcept
898 {
899  const double d = r2 - 1;
900  const double r12 = sqr(r1);
901 
902  return 3 + r1*(-4 - 3*r1 + r2)
903  + d*(-2 + 4*r12
904  + d*(1 - 4*r12
905  + d*(-0.4 + r1*(-0.4 + (18*r1)/5.)
906  + d*(0.1 + (0.5 - (31*r1)/10.)*r1))));
907 }
908 
909 /// f7(r1,r2) in the limit r1 -> 1
910 static double f7_1_r2(double r1, double r2) noexcept
911 {
912  if (is_zero(r2, 0.0001)) {
913  return f7_0_1(r2, r1);
914  }
915 
916  const double d = r1 - 1;
917  const double d2 = sqr(d);
918  const double d3 = d2*d;
919  const double d4 = d3*d;
920  const double y = r2 - 1;
921  const double y2 = sqr(y);
922  const double y3 = y2*y;
923  const double y4 = y3*y;
924  const double y5 = y4*y;
925  const double y6 = y5*y;
926  const double y7 = y6*y;
927  const double z = 1 + r2;
928  const double z2 = sqr(z);
929  const double r22 = sqr(r2);
930  const double lr22 = std::log(r22);
931 
932  return
933  (-3 + r2*(6 + r2*(6 + (-6 + 6*lr22 - 3*r2)*r2)))/(y3*z2)
934  + d*(-2 + r2*(5 + r2*(4 + r2*(-4 + 6*lr22 + (-2 - r2)*r2))))/(y4*z2)
935  + d2*(-1 + r2*(3 + r2*(3 + r2*(6*lr22 + r2*(-3 + (-3 + r2)*r2)))))/(y5*z2)
936  + d3*(-2 + r2*(6 + r2*(18 + r2*(15 + 30*lr22 + r2*(-30 + r2*(-18 + (14 - 3*r2)*r2))))))/(5.*y6*z2)
937  + d4*(-1 + r22*(48 + r2*(42 + 60*lr22 + r2*(-90 + r2*(-24 + r2*(40 + r2*(-18 + 3*r2)))))))/(10.*y7*z2);
938 }
939 
940 /// f7(r1,r2) in the limit r1 -> 0
941 static double f7_0_r2(double r1, double r2) noexcept
942 {
943  const double r12 = sqr(r1);
944  const double r22 = sqr(r2);
945  const double lr22 = std::log(r22);
946  const double r12lr12 = xlogx(r12);
947 
948  return
949  6*(
950  + r22*(1 + (-1 + lr22)*r22)
951  + r1*(r2*(-r12lr12 + r22*(1 + lr22 + 2*r12lr12 + (-1 - r12lr12)*r22))
952  + r1*(-r12lr12 + r22*(1 + lr22 + 2*r12lr12 + (-1 - r12lr12)*r22)
953  + r1*(r1*(lr22 + r22*(1 - r22)) + r2*(lr22 + r22*(1 - r22)))))
954  )/(r22*sqr(-1 + r22));
955 }
956 
957 /// f7(r1,r2) in the limit r1 -> r2
958 static double f7_r1_r2(double r1, double r2) noexcept
959 {
960  const double d = r1 - r2;
961  const double d2 = sqr(d);
962  const double d3 = d2*d;
963  const double d4 = d3*d;
964  const double r22 = sqr(r2);
965  const double y = r22 - 1;
966  const double y2 = sqr(y);
967  const double y3 = y2*y;
968  const double y4 = y3*y;
969  const double y5 = y4*y;
970  const double y6 = y5*y;
971  const double y7 = y6*y;
972  const double lr22 = std::log(r22);
973 
974  const double res =
975  (-1 + r22*(-2 - 3*lr22 + (3 - lr22)*r22))/y3
976  + d*r2*(8 + 3*lr22 + r22*(-4 + 8*lr22 + (-4 + lr22)*r22))/y4
977  + d2*(-14 - 3*lr22 + r22*(-54 - 45*lr22 + r22*(54 - 45*lr22 + (14 - 3*lr22)*r22)))/(3.*y5)
978  + d3*(3 + r22*(166 + 60*lr22 + r22*(108 + 270*lr22 + r22*(-246 + 144*lr22 + (-31 + 6*lr22)*r22))))/(6.*r2*y6)
979  + d4*(3 + r22*(-325 - 60*lr22 + r22*(-2570 - 1470*lr22 + r22*(510 - 3150*lr22 + r22*(2215 - 1050*lr22 + (167 - 30*lr22)*r22)))))/(30.*r22*y7);
980 
981  return 6*res;
982 }
983 
984 double f7(double r1, double r2) noexcept
985 {
986  const double eps_zero = 1e-4;
987  const double eps_one = 2e-2;
988 
989  if (is_zero(r1, eps_zero) && is_zero(r2, eps_zero)) {
990  return f7_0_0(r1, r2);
991  }
992 
993  if (is_equal(r1, 1., eps_one) && is_equal(r2, 1., eps_one)) {
994  return f7_1_1(r1, r2);
995  }
996 
997  if (is_equal(r1, -1., eps_one) && is_equal(r2, -1., eps_one)) {
998  return f7_1_1(-r1, -r2);
999  }
1000 
1001  if (is_equal(r1, 1., eps_one)) {
1002  return f7_1_r2(r1, r2);
1003  }
1004 
1005  if (is_equal(r2, 1., eps_one)) {
1006  return f7_1_r2(r2, r1);
1007  }
1008 
1009  if (is_zero(r1, eps_zero)) {
1010  return f7_0_r2(r1, r2);
1011  }
1012 
1013  if (is_zero(r2, eps_zero)) {
1014  return f7_0_r2(r2, r1);
1015  }
1016 
1017  if (is_equal(r1, r2, 0.0001)) {
1018  return f7_r1_r2(r2, r1);
1019  }
1020 
1021  const double r12 = sqr(r1);
1022  const double r22 = sqr(r2);
1023 
1024  const double result
1025  = (1 + r1*r2)/((r12 - 1)*(r22 - 1))
1026  + (cube(r1)*std::log(r12))/(sqr(r12 - 1)*(r1 - r2))
1027  - (cube(r2)*std::log(r22))/((r1 - r2)*sqr(r22 - 1));
1028 
1029  return 6. * result;
1030 }
1031 
1032 /// f8(r1,r2) in the limit r1 -> 0 and r2 -> 0
1033 static double f8_0_0(double r1, double r2) noexcept
1034 {
1035  if (is_zero(r1, 1e-10) && is_zero(r2, 1e-10)) {
1036  return 0.;
1037  }
1038 
1039  if (std::abs(r1) > std::abs(r2)) {
1040  std::swap(r1, r2);
1041  }
1042 
1043  const double r22 = sqr(r2);
1044  const double lr22 = logx(r22);
1045  const double r2lr22 = r2*lr22;
1046  const double r22lr22 = r2*r2lr22;
1047 
1048  if (is_zero(r1, 1e-8) && is_zero(r2, 1e-8)) {
1049  return
1050  (3*r2)/2.
1051  + r1*(1.5 + (3*r22)/2. + (3*r22lr22)/2.
1052  + r1*((3*r2)/2. + (3*r2lr22)/2.));
1053  }
1054 
1055  return
1056  r2*(1.5 + (3*r22)/2. + (3*r22lr22)/2.)
1057  + r1*(1.5 + (3*r22)/2. + (3*r22lr22)/2.
1058  + r1*(r2*(1.5 + (3*r22)/2. + 3*r22lr22)
1059  + r1*(1.5 + (3*lr22)/2. + (3*r22)/2. + 3*r22lr22) + (3*r2lr22)/2.));
1060 }
1061 
1062 /// f8(r1,r2) in the limit r1 -> 1 and r2 -> 1
1063 static double f8_1_1(double r1, double r2) noexcept
1064 {
1065  const double d1 = r1 - 1;
1066  const double d2 = r2 - 1;
1067  const double d22 = sqr(d2);
1068 
1069  return
1070  1 + d22*(-1./10 + (3./40 - 3.*d2/70)*d2)
1071  + d1*(d2*(-1./10 + d2*(3./40 + (-3./70 + 3.*d2/140)*d2))
1072  + d1*(-1./10 + d2*(3./40 + d2*(-3./70 + (3./140 - d2/105)*d2))
1073  + d1*(3./40 + d2*(-3./70 + d2*(3./140 + (-1./105 + d2/280)*d2))
1074  + d1*(-3./70 + d2*(3./140 + d2*(-1./105 + (1./280 - d2/1155)*d2))))));
1075 }
1076 
1077 /// f8(r1,r2) in the limit r1 -> 0 and r2 -> 1
1078 static double f8_0_1(double r1, double r2) noexcept
1079 {
1080  const double r12 = sqr(r1);
1081  const double d2 = r2 - 1;
1082 
1083  return 0.75 + r1*(0.75 + r1*(-0.75 + r1*(-1.75 + r2)))
1084  + d2*(0.25 + (-0.5 + r1/4.)*r1
1085  + d2*(-0.25 + r1*(0.25 - r12)
1086  + d2*(0.15 + r1*(-0.1 + (-0.1 + (9*r1)/10.)*r1))));
1087 }
1088 
1089 /// f8(r1,r2) in the limit r1 -> 1
1090 static double f8_1_r2(double r1, double r2) noexcept
1091 {
1092  if (is_zero(r2, 1e-4)) {
1093  return f8_0_1(r2, r1);
1094  }
1095 
1096  const double d1 = r1 - 1;
1097  const double d12 = sqr(d1);
1098  const double d13 = d12*d1;
1099  const double d14 = d13*d1;
1100  const double y = 1 + r2;
1101  const double y2 = sqr(y);
1102  const double d2 = r2 - 1;
1103  const double d22 = sqr(d2);
1104  const double d23 = d22*d2;
1105  const double d24 = d23*d2;
1106  const double d25 = d24*d2;
1107  const double d26 = d25*d2;
1108  const double d27 = d26*d2;
1109  const double r22 = sqr(r2);
1110  const double lr22 = std::log(r22);
1111 
1112  return
1113  (-3 + r22*(12 + (-9 + 6*lr22)*r22))/(4.*d23*y2)
1114  + d1*(1 + r2*(-4 + r2*(4 + r2*(8 + (-5 + 6*lr22 - 4*r2)*r2))))/(4.*d24*y2)
1115  + d12*(1 + r2*(-4 + r2*(4 + r2*(8 + (-5 + 6*lr22 - 4*r2)*r2))))/(4.*d25*y2)
1116  + d13*(3 + r2*(-14 + r2*(18 + r2*(30 + r2*(-15 + 30*lr22 + r2*(-18 + r2*(-6 + 2*r2)))))))/(20.*d26*y2)
1117  + d14*(3 + r2*(-16 + r2*(24 + r2*(48 + r2*(60*lr22 + r2*(-48 + r2*(-24 + (16 - 3*r2)*r2)))))))/(40.*d27*y2);
1118 }
1119 
1120 /// f8(r1,r2) in the limit r1 -> 0
1121 static double f8_0_r2(double r1, double r2) noexcept
1122 {
1123  const double r12 = sqr(r1);
1124  const double r22 = sqr(r2);
1125  const double lr22 = std::log(r22);
1126  const double r12lr12 = xlogx(r12);
1127 
1128  return
1129  (r22*(3 + (-3 + 3*lr22)*r22)
1130  + r1*(r2*(3 + (-3 + 3*lr22)*r22)
1131  + r1*(-3*r12lr12 + r22*(3 + 3*lr22 + 6*r12lr12 + (-3 - 3*r12lr12)*r22)
1132  + r1*(r2*(3 + 3*lr22 - 3*r22) + r1*(3*lr22 + r22*(3 - 3*r22))))))/(2*r2*sqr(-1 + r22));
1133 }
1134 
1135 /// f8(r1,r2) in the limit r1 -> r2
1136 static double f8_r1_r2(double r1, double r2) noexcept
1137 {
1138  const double d = r1 - r2;
1139  const double d2 = sqr(d);
1140  const double d3 = d2*d;
1141  const double d4 = d3*d;
1142  const double r22 = sqr(r2);
1143  const double y = r22 - 1;
1144  const double y2 = sqr(y);
1145  const double y3 = y2*y;
1146  const double y4 = y3*y;
1147  const double y5 = y4*y;
1148  const double y6 = y5*y;
1149  const double y7 = y6*y;
1150  const double lr22 = std::log(r22);
1151 
1152  return
1153  (r2*(-3 + r22*(-6*lr22 + 3*r22)))/y3
1154  + d*(3 + r22*(27 + 18*lr22 + r22*(-27 + 18*lr22 - 3*r22)))/(2.*y4)
1155  + d2*r2*(-19 - 6*lr22 + r22*(-9 - 30*lr22 + r22*(27 - 12*lr22 + r22)))/y5
1156  + d3*(31 + 6*lr22 + r22*(246 + 144*lr22 + r22*(-108 + 270*lr22 + r22*(-166 + 60*lr22 - 3*r22))))/(4.*y6)
1157  + d4*(-3 + r22*(-285 - 90*lr22 + r22*(-570 - 630*lr22 + r22*(570 - 630*lr22 + r22*(285 - 90*lr22 + 3*r22)))))/(5.*r2*y7);
1158 }
1159 
1160 double f8(double r1, double r2) noexcept
1161 {
1162  const double eps_zero = 5e-5;
1163  const double eps_one = 1e-2;
1164 
1165  if (is_zero(r1, eps_zero) && is_zero(r2, eps_zero)) {
1166  return f8_0_0(r1, r2);
1167  }
1168 
1169  if (is_equal(r1, 1., eps_one) && is_equal(r2, 1., eps_one)) {
1170  return f8_1_1(r1, r2);
1171  }
1172 
1173  if (is_equal(r1, -1., eps_one) && is_equal(r2, -1., eps_one)) {
1174  return -1.;
1175  }
1176 
1177  if (is_equal(r1, 1., eps_one)) {
1178  return f8_1_r2(r1, r2);
1179  }
1180 
1181  if (is_equal(r2, 1., eps_one)) {
1182  return f8_1_r2(r2, r1);
1183  }
1184 
1185  if (is_zero(r1, eps_zero)) {
1186  return f8_0_r2(r1, r2);
1187  }
1188 
1189  if (is_zero(r2, eps_zero)) {
1190  return f8_0_r2(r2, r1);
1191  }
1192 
1193  if (is_equal(r1, r2, 0.0001)) {
1194  return f8_r1_r2(r2, r1);
1195  }
1196 
1197  const double r12 = sqr(r1);
1198  const double r22 = sqr(r2);
1199 
1200  const double result
1201  = (r1 + r2)/((r12 - 1)*(r22 - 1))
1202  + (quad(r1)*std::log(r12))/(sqr(r12 - 1)*(r1 - r2))
1203  - (quad(r2)*std::log(r22))/((r1 - r2)*sqr(r22 - 1));
1204 
1205  return 1.5 * result;
1206 }
1207 
1208 double fth1(double y) noexcept
1209 {
1210  const double eps = 10.*std::numeric_limits<double>::epsilon();
1211 
1212  if (is_zero(y, eps)) {
1213  return 0.;
1214  }
1215 
1216  if (is_equal(std::abs(y), 1.0, eps)) {
1217  return -1.;
1218  }
1219 
1220  if (!is_zero(y, eps) && !is_equal(std::abs(y), 1.0, eps)) {
1221  const double y2 = sqr(y);
1222 
1223  return y2*std::log(y2) / (1. - y2);
1224  }
1225 
1226  return 0.;
1227 }
1228 
1229 double fth2(double y) noexcept
1230 {
1231  const double eps = 10.*std::numeric_limits<double>::epsilon();
1232 
1233  if (is_zero(y, eps)) {
1234  return 0.;
1235  }
1236 
1237  if (is_equal(std::abs(y), 1.0, eps)) {
1238  return 0.5;
1239  }
1240 
1241  if (!is_zero(y, eps) && !is_equal(std::abs(y), 1.0, eps)) {
1242  const double y2 = sqr(y);
1243 
1244  return (1. + y2*std::log(y2) / (1. - y2)) / (1 - y2);
1245  }
1246 
1247  return 0.;
1248 }
1249 
1250 double fth3(double y) noexcept
1251 {
1252  const double eps = 10.*std::numeric_limits<double>::epsilon();
1253  const double z2 = 1.644934066848226;
1254 
1255  if (is_zero(y, eps)) {
1256  return z2;
1257  }
1258 
1259  if (is_equal(std::abs(y), 1.0, eps)) {
1260  return -9./4.;
1261  }
1262 
1263  if (!is_zero(y, eps) && !is_equal(std::abs(y), 1.0, eps)) {
1264  const double y2 = sqr(y);
1265  const double y4 = sqr(y2);
1266  const double ly = std::log(y2);
1267 
1268  return (-1. + 2*y2 + 2*y4)
1269  *(-z2 - y2*ly + ly*std::log(1. - y2) + dilog(y2))
1270  / sqr(1 - y2);
1271  }
1272 
1273  return 0.;
1274 }
1275 
1276 namespace {
1277 
1278 /// I2abc(a,a,a), squared arguments, a != 0
1279 double I2aaa(double a, double b, double c) noexcept {
1280  const double ba = b - a;
1281  const double ca = c - a;
1282  const double a2 = sqr(a);
1283  const double a3 = a2*a;
1284 
1285  return 0.5/a + (-ba - ca)/(6.0*a2) + (sqr(ba) + ba*ca + sqr(ca))/(12.0*a3);
1286 }
1287 
1288 /// I2abc(a,a,c), squared arguments, a != c
1289 double I2aac(double a, double b, double c) noexcept {
1290  const double ba = b - a;
1291  const double ac = a - c;
1292  const double a2 = sqr(a);
1293  const double a3 = a2*a;
1294  const double c2 = sqr(c);
1295  const double c3 = c2*c;
1296  const double ac2 = sqr(ac);
1297  const double ac3 = ac2*ac;
1298  const double ac4 = ac2*ac2;
1299  const double lac = std::log(a/c);
1300 
1301  return (ac - c*lac)/ac2
1302  + ba*(-a2 + c2 + 2*a*c*lac)/(2.0*a*ac3)
1303  + sqr(ba)*((2*a3 + 3*a2*c - 6*a*c2 + c3 - 6*a2*c*lac)/(6.*a2*ac4));
1304 }
1305 
1306 /// I2abc(a,a,0), squared arguments, a != 0
1307 double I2aa0(double a, double b) noexcept {
1308  const double a2 = sqr(a);
1309  const double a3 = a2*a;
1310  const double ba = b - a;
1311  const double ba2 = sqr(ba);
1312 
1313  return 1.0/a - ba/(2.0*a2) + ba2/(3.0*a3);
1314 }
1315 
1316 /// I2abc(0,b,c), squared arguments, b != c
1317 double I20bc(double b, double c) noexcept {
1318  return std::log(b/c)/(b - c);
1319 }
1320 
1321 } // anonymous namespace
1322 
1323 double Iabc(double a, double b, double c) noexcept {
1324  const double eps = 10.0*std::numeric_limits<double>::epsilon();
1325 
1326  if ((is_zero(a, eps) && is_zero(b, eps) && is_zero(c, eps)) ||
1327  (is_zero(a, eps) && is_zero(b, eps)) ||
1328  (is_zero(a, eps) && is_zero(c, eps)) ||
1329  (is_zero(b, eps) && is_zero(c, eps))) {
1330  return 0.0;
1331  }
1332 
1333  const double a2 = sqr(a);
1334  const double b2 = sqr(b);
1335  const double c2 = sqr(c);
1336  const double eps_eq = 0.001;
1337 
1338  if (is_close(a2, b2, eps_eq) && is_close(a2, c2, eps_eq)) {
1339  return I2aaa(a2, b2, c2);
1340  }
1341 
1342  if (is_close(a2, b2, eps_eq)) {
1343  if (is_zero(c, eps)) {
1344  return I2aa0(a2, b2);
1345  }
1346  return I2aac(a2, b2, c2);
1347  }
1348 
1349  if (is_close(b2, c2, eps_eq)) {
1350  if (is_zero(a, eps)) {
1351  return I2aa0(b2, c2);
1352  }
1353  return I2aac(b2, c2, a2);
1354  }
1355 
1356  if (is_close(a2, c2, eps_eq)) {
1357  if (is_zero(b, eps)) {
1358  return I2aa0(a2, c2);
1359  }
1360  return I2aac(a2, c2, b2);
1361  }
1362 
1363  if (is_zero(a, eps)) {
1364  return I20bc(b2, c2);
1365  }
1366 
1367  if (is_zero(b, eps)) {
1368  return I20bc(c2, a2);
1369  }
1370 
1371  if (is_zero(c, eps)) {
1372  return I20bc(a2, b2);
1373  }
1374 
1375  return (+ a2 * b2 * std::log(a2/b2)
1376  + b2 * c2 * std::log(b2/c2)
1377  + c2 * a2 * std::log(c2/a2))
1378  / ((a2 - b2) * (b2 - c2) * (a2 - c2));
1379 }
1380 
1381 /// Delta function from hep-ph/0907.47682v1
1382 double delta_xyz(double x, double y, double z) noexcept
1383 {
1384  return sqr(x)+sqr(y)+sqr(z)-2*(x*y+x*z+y*z);
1385 }
1386 
1387 namespace {
1388  /// lambda^2(u,v)
1389  double lambda_2(double u, double v) noexcept
1390  {
1391  return sqr(1 - u - v) - 4*u*v;
1392  }
1393 
1394  /// u < 1 && v < 1, lambda^2(u,v) > 0; note: phi_pos(u,v) = phi_pos(v,u)
1395  double phi_pos(double u, double v) noexcept
1396  {
1397  const double eps = 1.0e-7;
1398 
1399  if (is_equal(u, 1.0, eps) && is_equal(v, 1.0, eps)) {
1400  return 2.343907238689459;
1401  }
1402 
1403  const double Pi = 3.141592653589793;
1404  const auto lambda = std::sqrt(lambda_2(u,v));
1405 
1406  if (is_equal(u, v, eps)) {
1407  return (-(sqr(std::log(u)))
1408  + 2*sqr(std::log((1 - lambda)/2.))
1409  - 4*dilog((1 - lambda)/2.)
1410  + sqr(Pi)/3.)/lambda;
1411  }
1412 
1413  return (-(std::log(u)*std::log(v))
1414  + 2*std::log((1 - lambda + u - v)/2.)*std::log((1 - lambda - u + v)/2.)
1415  - 2*dilog((1 - lambda + u - v)/2.)
1416  - 2*dilog((1 - lambda - u + v)/2.)
1417  + sqr(Pi)/3.)/lambda;
1418  }
1419 
1420  /// lambda^2(u,v) < 0, u = 1
1421  double phi_neg_1v(double v, double lambda) noexcept
1422  {
1423  return 2*(+ clausen_2(2*std::acos((2 - v)/2))
1424  + 2*clausen_2(2*std::acos(0.5*std::sqrt(v))))/lambda;
1425  }
1426 
1427  /// lambda^2(u,v) < 0; note: phi_neg(u,v) = phi_neg(v,u)
1428  double phi_neg(double u, double v) noexcept
1429  {
1430  const double eps = 1.0e-7;
1431 
1432  if (is_equal(u, 1.0, eps) && is_equal(v, 1.0, eps)) {
1433  return 2.343907238689459;
1434  }
1435 
1436  const auto lambda = std::sqrt(-lambda_2(u,v));
1437 
1438  if (is_equal(u, 1.0, eps)) {
1439  return phi_neg_1v(v, lambda);
1440  }
1441 
1442  if (is_equal(v, 1.0, eps)) {
1443  return phi_neg_1v(u, lambda);
1444  }
1445 
1446  if (is_equal(u, v, eps)) {
1447  return 2*(2*clausen_2(2*std::acos(1/(2.*std::sqrt(u))))
1448  + clausen_2(2*std::acos((-1 + 2*u)/(2.*std::abs(u)))))/lambda;
1449  }
1450 
1451  return 2*(+ clausen_2(2*std::acos((1 + u - v)/(2.*std::sqrt(u))))
1452  + clausen_2(2*std::acos((1 - u + v)/(2.*std::sqrt(v))))
1453  + clausen_2(2*std::acos((-1 + u + v)/(2.*std::sqrt(u*v)))))/lambda;
1454  }
1455 
1456  /**
1457  * Phi(u,v) with u = x/z, v = y/z.
1458  *
1459  * The following identities hold:
1460  * Phi(u,v) = Phi(v,u) = Phi(1/u,v/u)/u = Phi(1/v,u/v)/v
1461  */
1462  double phi_uv(double u, double v) noexcept
1463  {
1464  const auto lambda = lambda_2(u,v);
1465 
1466  if (is_zero(lambda, std::numeric_limits<double>::epsilon())) {
1467  // phi_uv is always multiplied by lambda. So, in order to
1468  // avoid nans if lambda == 0, we simply return 0
1469  return 0.0;
1470  }
1471 
1472  if (lambda > 0.) {
1473  if (u <= 1 && v <= 1) {
1474  return phi_pos(u,v);
1475  }
1476  if (u >= 1 && v/u <= 1) {
1477  return phi_pos(1./u,v/u)/u;
1478  }
1479  // v >= 1 && u/v <= 1
1480  return phi_pos(1./v,u/v)/v;
1481  }
1482 
1483  return phi_neg(u,v);
1484  }
1485 } // anonymous namespace
1486 
1487 /**
1488  * \f$\Phi(x,y,z)\f$ function. The arguments x, y and z are
1489  * interpreted as squared masses.
1490  *
1491  * Davydychev and Tausk, Nucl. Phys. B397 (1993) 23
1492  *
1493  * @param x squared mass
1494  * @param y squared mass
1495  * @param z squared mass
1496  *
1497  * @return \f$\Phi(x,y,z)\f$
1498  */
1499 double phi_xyz(double x, double y, double z) noexcept
1500 {
1501  const auto u = x/z, v = y/z;
1502  return phi_uv(u,v);
1503 }
1504 
1505 } // namespace threshold_loop_functions
1506 } // namespace mh2_eft
1507 } // namespace himalaya
static double f6_r1_r2(double r1, double r2) noexcept
static double F8_0_x2(double x1, double x2) noexcept
F8(x1,x2) in the limit x1 -> 0, x2 != 0.
static double F9_1_1(double x1, double x2) noexcept
F9(x1,x2) in the limit x1 -> 1 and x2 -> 1.
static double f5_0_0(double r1, double r2) noexcept
f5(r1,r2) in the limit r1 -> 0, r2 -> 0
Definition: H3.cpp:14
static double f5_r1_r2(double r1, double r2) noexcept
f5(r1,r2) in the limit r1 -> r2
double delta_xyz(double x, double y, double z) noexcept
Delta function from hep-ph/0907.47682v1.
static double f7_0_0(double r1, double r2) noexcept
f7(r1,r2) in the limit r1 -> 0, r2 -> 0
Declaration of the dilogarithm function.
static double f7_0_1(double r1, double r2) noexcept
f7(r1,r2) in the limit r1 -> 0 and r2 -> 1
static double f7_1_1(double r1, double r2) noexcept
f7(r1,r2) in the limit r1 -> 1 and r2 -> 1
double clausen_2(double x) noexcept
Clausen function .
Definition: Li2.cpp:214
static double f8_0_0(double r1, double r2) noexcept
f8(r1,r2) in the limit r1 -> 0 and r2 -> 0
static double f6_0_0(double r1, double r2) noexcept
f6(r1,r2) in the limit r1 -> 0 and r2 -> 0
static double F9_1_x2(double x1, double x2) noexcept
F9(x1,x2) in the limit x1 -> 1.
static double f6_1_1(double r1, double r2) noexcept
f6(r1,r2) in the limit r1 -> 1 and r2 -> 1
static double f5_1_r2(double r1, double r2) noexcept
f5(r1,r2) in the limit r1 -> 1, r2 != 1
double dilog(double x) noexcept
Real dilogarithm .
Definition: Li2.cpp:62
static double f5_1_1(double r1, double r2) noexcept
f5(r1,r2) in the limit r1 -> 1 and r2 -> 1
static double F9_x1_x2(double x1, double x2) noexcept
F9(x1,x2) in the limit x1 -> x2, x2 != 0.
static double f8_1_r2(double r1, double r2) noexcept
f8(r1,r2) in the limit r1 -> 1
double f8(double r1, double r2) noexcept
double Iabc(double a, double b, double c) noexcept
(arguments are interpreted as unsquared)
static double f8_0_r2(double r1, double r2) noexcept
f8(r1,r2) in the limit r1 -> 0
static double f8_r1_r2(double r1, double r2) noexcept
f8(r1,r2) in the limit r1 -> r2
double F9(double x1, double x2) noexcept
static double f8_1_1(double r1, double r2) noexcept
f8(r1,r2) in the limit r1 -> 1 and r2 -> 1
static double f7_1_r2(double r1, double r2) noexcept
f7(r1,r2) in the limit r1 -> 1
static double F8_x1_x2(double x1, double x2) noexcept
static double f5_0_r2(double r1, double r2) noexcept
f5(r1,r2) in the limit r1 -> 0
static double f6_0_1(double r1, double r2) noexcept
f6(r1,r2) in the limit r1 -> 0 and r2 -> 1
static double f8_0_1(double r1, double r2) noexcept
f8(r1,r2) in the limit r1 -> 0 and r2 -> 1
double phi_xyz(double x, double y, double z) noexcept
(arguments are interpreted as squared masses)
Declaration of the loop functions from [arXiv:1407.4081].
static double F9_0_x2(double, double x2) noexcept
F9(x1,x2) in the limit x1 -> 0, x2 != 1, x2 != 0.
double f5(double r1, double r2) noexcept
Complex< T > log(const Complex< T > &z_) noexcept
Definition: complex.hpp:45
static double f6_0_r2(double r1, double r2) noexcept
f6(r1,r2) in the limit r1 -> 0
static double f7_0_r2(double r1, double r2) noexcept
f7(r1,r2) in the limit r1 -> 0
static double f6_1_r2(double r1, double r2) noexcept
f6(r1,r2) in the limit r1 -> 1
double f7(double r1, double r2) noexcept
double f6(double r1, double r2) noexcept
static double f7_r1_r2(double r1, double r2) noexcept
f7(r1,r2) in the limit r1 -> r2
double F8(double x1, double x2) noexcept
static double F8_1_1(double x1, double x2) noexcept
F8(x1,x2) in the limit x1 -> 1 and x2 -> 1.
static double F8_1_x2(double x1, double x2) noexcept
F8(x1,x2) in the limit x1 -> 1, x2 != 1.