flexiblesusy is hosted by Hepforge, IPPP Durham
FlexibleSUSY
Li6.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
19#include "Li6.hpp"
20#include "horner.hpp"
21#include "log.hpp"
22#include <cfloat>
23#include <cmath>
24#include <complex>
25
26namespace flexiblesusy {
27
34std::complex<double> Li6(const std::complex<double>& z) noexcept
35{
36 const double PI = 3.1415926535897932;
37 const double PI2 = PI*PI;
38 const double PI4 = PI2*PI2;
39 const double PI6 = PI2*PI4;
40 const double zeta6 = 1.0173430619844491;
41 const double bf[18] = {
42 1.0 , -31.0/64.0 ,
43 1.5241340877914952e-01, -3.4365555877057613e-02,
44 5.7174797239368999e-03, -6.8180453746570645e-04,
45 4.9960361948734493e-05, -4.9166051196039048e-07,
46 -3.0632975161302164e-07, 1.4414599270849095e-08,
47 3.7272438230924107e-09, -3.7300867345487607e-10,
48 -5.1246526816085832e-11, 9.0541930956636683e-12,
49 6.7381882615512517e-13, -2.1215831150303135e-13,
50 -6.8408811719011698e-15, 4.8691178462005581e-15
51 };
52
53 const double rz = std::real(z);
54 const double iz = std::imag(z);
55
56 if (iz == 0) {
57 if (rz == 0) {
58 return { rz, iz };
59 }
60 if (rz == 1) {
61 return { zeta6, iz };
62 }
63 if (rz == -1) {
64 return { -31.0*zeta6/32.0, iz };
65 }
66 }
67
68 const double nz = std::abs(z);
69 const double pz = std::arg(z);
70 const double lnz = std::log(nz);
71
72 if (lnz*lnz + pz*pz < 1) { // |log(z)| < 1
73 const std::complex<double> u(lnz, pz); // log(z)
74 const double c0 = zeta6;
75 const double c1 = 1.0369277551433699; // zeta(5)
76 const double c2 = 0.54116161685556910;
77 const double c3 = 0.20034281719326571;
78 const double c4 = 0.068538919452009435;
79 const auto c5 = (137.0/60.0 - pos_log(-u))/120.0;
80 const double c6 = -1.0/1440.0;
81 const double cs[5] = {
82 -1.6534391534391534e-05, 2.2964432686654909e-08,
83 -9.9413128513657614e-11, 6.6912682653423394e-13,
84 -5.7933058574392549e-15
85 };
86 const auto u2 = u*u;
87
88 return c0 + u * c1 +
89 u2 * (c2 + u * c3 +
90 u2 * (c4 + u * c5 +
91 u2 * (c6 +
92 u * horner<0>(u2, cs))));
93 }
94
95 std::complex<double> u(0.0, 0.0), rest(0.0, 0.0);
96 double sgn = 1;
97
98 if (nz <= 1) {
99 u = -log1p(-z);
100 } else { // nz > 1
101 const double arg = pz > 0.0 ? pz - PI : pz + PI;
102 const std::complex<double> lmz(lnz, arg); // log(-z)
103 const auto lmz2 = lmz*lmz;
104 u = -log1p(-1.0/z);
105 rest = -31.0*PI6/15120.0 + lmz2*(-7.0/720.0*PI4 + lmz2*(-1.0/144.0*PI2 - 1.0/720.0*lmz2));
106 sgn = -1;
107 }
108
109 const auto u2 = u*u;
110 const auto u4 = u2*u2;
111 const auto u8 = u4*u4;
112
113 return
114 rest + sgn * (
115 u*bf[0] +
116 u2*(bf[1] + u*bf[2]) +
117 u4*(bf[3] + u*bf[4] + u2*(bf[5] + u*bf[6])) +
118 u8*(bf[7] + u*bf[8] + u2*(bf[9] + u*bf[10]) +
119 u4*(bf[11] + u*bf[12] + u2*(bf[13] + u*bf[14]))) +
120 u8*u8*(bf[15] + u*bf[16] + u2*bf[17])
121 );
122}
123
130std::complex<long double> Li6(const std::complex<long double>& z) noexcept
131{
132 const long double PI = 3.14159265358979323846264338327950288L;
133 const long double PI2 = PI*PI;
134 const long double PI4 = PI2*PI2;
135 const long double PI6 = PI2*PI4;
136 const long double zeta6 = 1.01734306198444913971451792979092053L;
137 const long double bf[] = {
138 1.0L,
139 -31.0L/64.0L,
140 1.52413408779149519890260631001371742e-01L,
141 -3.43655558770576131687242798353909465e-02L,
142 5.71747972393689986282578875171467764e-03L,
143 -6.81804537465706447187928669410150892e-04L,
144 4.99603619487344931145170169621327906e-05L,
145 -4.91660511960390477202530822164616726e-07L,
146 -3.06329751613021637853530304310404212e-07L,
147 1.44145992708490953612537421448012923e-08L,
148 3.72724382309241065768599245664598825e-09L,
149 -3.73008673454876072077977229159261141e-10L,
150 -5.12465268160858324340087646115722592e-11L,
151 9.05419309566366828868797447620893807e-12L,
152 6.73818826155125170776107544938009482e-13L,
153 -2.12158311503031353185279689296609530e-13L,
154 -6.84088117190116976639204518781909079e-15L,
155 4.86911784620055813206387586512917456e-15L,
156 -4.84398784998725041650889647473159420e-18L,
157 -1.10271048491074909370430302576046237e-16L,
158 3.33537969169393816624889411840735964e-18L,
159 2.47353074886413529791540987487137046e-18L,
160#if LDBL_DIG > 18
161 -1.43706164342324920216883687134737009e-19L,
162 -5.50471103350981180614826435059791109e-20L,
163 4.74677139173272249791309840662617185e-21L,
164 1.21583871780681052243739817416294433e-21L,
165 -1.41075524035618500414240309078008657e-22L,
166 -2.66388312532683465965856437677118103e-23L,
167 3.96676574286310079767900226081781935e-24L,
168 5.78216973585436153112366193481125963e-25L,
169 -1.07877780631642573172998876995922389e-25L,
170 -1.24073970867569098990147736977589145e-26L,
171 2.87041179178936017042609524684092346e-27L,
172 2.62355535630293306165747520383606820e-28L,
173 -7.52294854657541272615881214134337672e-29L,
174 -5.44017883796246961820291930722306669e-30L,
175 1.95025795325101663793862223381656999e-30L,
176 1.09784942822051879961178213597012971e-31L,
177 -5.01495835741630092074469585415763612e-32L,
178 -2.12867375043927610535633806917391780e-33L,
179 1.28159440165221259409319852281486752e-33L,
180 3.87108447330479441622204568697607460e-35L,
181 -3.25941253155837592741689642881678163e-35L,
182 -6.25269198847740581093233860701356903e-37L,
183 8.25794162051839801918004563317046685e-37L
184#endif
185 };
186
187 const long double rz = std::real(z);
188 const long double iz = std::imag(z);
189
190 if (iz == 0) {
191 if (rz == 0) {
192 return { rz, iz };
193 }
194 if (rz == 1) {
195 return { zeta6, iz };
196 }
197 if (rz == -1) {
198 return { -31.0L*zeta6/32.0L, iz };
199 }
200 }
201
202 const long double nz = std::abs(z);
203 const long double pz = std::arg(z);
204 const long double lnz = std::log(nz);
205
206 if (lnz*lnz + pz*pz < 1) { // |log(z)| < 1
207 const std::complex<long double> u(lnz, pz); // log(z)
208 const long double c0 = zeta6;
209 const long double c1 = 1.03692775514336992633136548645703417L; // zeta(5)
210 const long double c2 = 0.541161616855569095758001848270583951L;
211 const long double c3 = 0.200342817193265714233289693585241665L;
212 const long double c4 = 0.0685389194520094348530172986102510496L;
213 const auto c5 = (137.0L/60.0L - pos_log(-u))/120.0L;
214 const long double c6 = -1.0L/1440.0L;
215 const long double cs[] = {
216 -1.65343915343915343915343915343915344e-05L,
217 2.29644326866549088771310993533215755e-08L,
218 -9.94131285136576141867147158152449158e-11L,
219 6.69126826534233941641349048756456164e-13L,
220 -5.79330585743925490598570604983944731e-15L,
221 5.93014945895224312384148778345583373e-17L,
222#if LDBL_DIG > 18
223 -6.85052937218694143079665103072690062e-19L,
224 8.67589801792722939607545055256974774e-21L,
225 -1.18132150428192854833283051865852971e-22L,
226 1.70561884258584436997421138705840854e-24L,
227 -2.58484268003343989655128609060798194e-26L,
228 4.08008103922306292972099603527323696e-28L,
229 -6.66771970595289681764999062443512889e-30L,
230 1.12276996725126418754155893790528500e-31L,
231 -1.94061827643615870372790552830090522e-33L,
232 3.43209344566599308274080635472598888e-35L,
233 -6.19462586636097236736900573587284992e-37L
234#endif
235 };
236 const auto u2 = u*u;
237
238 return c0 + u * c1 +
239 u2 * (c2 + u * c3 +
240 u2 * (c4 + u * c5 +
241 u2 * (c6 +
242 u * horner<0>(u2, cs))));
243 }
244
245 std::complex<long double> u(0.0L, 0.0L), rest(0.0L, 0.0L);
246 long double sgn = 1;
247
248 if (nz <= 1) {
249 u = -log1p(-z);
250 } else { // nz > 1
251 const long double arg = pz > 0.0 ? pz - PI : pz + PI;
252 const std::complex<long double> lmz(lnz, arg); // log(-z)
253 const auto lmz2 = lmz*lmz;
254 u = -log1p(-1.0L/z);
255 rest = -31.0L*PI6/15120.0L
256 + lmz2*(-7.0L/720.0L*PI4 +
257 lmz2*(-1.0L/144.0L*PI2 - 1.0L/720.0L*lmz2));
258 sgn = -1;
259 }
260
261 return rest + sgn*u*horner<0>(u, bf);
262}
263
264} // namespace flexiblesusy
std::complex< T > log1p(const std::complex< T > &z) noexcept
returns log(1 + z) for complex z
Definition log.hpp:30
std::complex< T > pos_log(const std::complex< T > &z) noexcept
Definition log.hpp:52
std::complex< double > Li6(const std::complex< double > &z) noexcept
Complex polylogarithm .
Definition Li6.cpp:34