flexiblesusy is hosted by Hepforge, IPPP Durham
FlexibleSUSY
Li5.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 "Li5.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> Li5(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 zeta5 = 1.0369277551433699;
40 const double bf[19] = {
41 1.0 , -15.0/32.0 ,
42 1.3953189300411523e-01, -2.8633777006172840e-02,
43 4.0317412551440329e-03, -3.3985018004115226e-04,
44 4.5445184621617666e-06, 2.3916808048569012e-06,
45 -1.2762692600122747e-07, -3.1628984306505932e-08,
46 3.2848118445335192e-09, 4.7613713995660579e-10,
47 -8.0846898171909830e-11, -7.2387648587737207e-12,
48 1.9439760115173968e-12, 1.0256978405977236e-13,
49 -4.6180551009884830e-14, -1.1535857196470580e-15,
50 1.0903545401333394e-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 { zeta5, iz };
62 }
63 if (rz == -1) {
64 return { -15.0*zeta5/16.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 = zeta5;
75 const double c1 = 1.0823232337111382; // zeta(4)
76 const double c2 = 0.60102845157979714; // zeta(3)/2
77 const double c3 = 0.27415567780803774;
78 const auto c4 = (25.0/12.0 - pos_log(-u))/24.0;
79 const double c5 = -1.0/240.0;
80 const double cs[6] = {
81 -1.1574074074074074e-04, 2.0667989417989418e-07,
82 -1.0935444136502338e-09, 8.6986487449450412e-12,
83 -8.6899587861588824e-14, 1.0081254080218813e-15
84 };
85 const auto u2 = u*u;
86
87 return c0 + u * c1 +
88 u2 * (c2 + u * c3 +
89 u2 * (c4 + u * c5 +
90 u2 * horner<0>(u2, cs)));
91 }
92
93 std::complex<double> u(0.0, 0.0), rest(0.0, 0.0);
94
95 if (nz <= 1) {
96 u = -log1p(-z);
97 } else { // nz > 1
98 const double arg = pz > 0.0 ? pz - PI : pz + PI;
99 const std::complex<double> lmz(lnz, arg); // log(-z)
100 const auto lmz2 = lmz*lmz;
101 u = -log1p(-1.0/z);
102 rest = -1.0/360.0*lmz*(7*PI4 + lmz2*(10.0*PI2 + 3.0*lmz2));
103 }
104
105 const auto u2 = u*u;
106 const auto u4 = u2*u2;
107 const auto u8 = u4*u4;
108
109 return
110 rest +
111 u*bf[0] +
112 u2*(bf[1] + u*bf[2]) +
113 u4*(bf[3] + u*bf[4] + u2*(bf[5] + u*bf[6])) +
114 u8*(bf[7] + u*bf[8] + u2*(bf[9] + u*bf[10]) +
115 u4*(bf[11] + u*bf[12] + u2*(bf[13] + u*bf[14]))) +
116 u8*u8*(bf[15] + u*bf[16] + u2*(bf[17] + u*bf[18]));
117}
118
125std::complex<long double> Li5(const std::complex<long double>& z) noexcept
126{
127 const long double PI = 3.14159265358979323846264338327950288L;
128 const long double PI2 = PI*PI;
129 const long double PI4 = PI2*PI2;
130 const long double zeta5 = 1.03692775514336992633136548645703417L;
131 const long double bf[] = {
132 1.0L,
133 -15.0L/32.0L,
134 1.39531893004115226337448559670781893e-01L,
135 -2.86337770061728395061728395061728395e-02L,
136 4.03174125514403292181069958847736626e-03L,
137 -3.39850180041152263374485596707818930e-04L,
138 4.54451846216176664909446003743133026e-06L,
139 2.39168080485690118829088702752453967e-06L,
140 -1.27626926001227465885443518981747128e-07L,
141 -3.16289843065059324402567872795470007e-08L,
142 3.28481184453351916215185742384719818e-09L,
143 4.76137139956605790483191328977324967e-10L,
144 -8.08468981719098302564602603623317490e-11L,
145 -7.23876485877372069468292158375897580e-12L,
146 1.94397601151739684930556492093599766e-12L,
147 1.02569784059772359718813559433198981e-13L,
148 -4.61805510098848301805820862410656158e-14L,
149 -1.15358571964705800368425114834190972e-15L,
150 1.09035454013333939879770883809662643e-15L,
151 2.31481363172925263940797103190091493e-18L,
152 -2.56699170432652921943348919933966693e-17L,
153#if LDBL_DIG > 18
154 4.57086206073149690144959626860139115e-19L,
155 6.03667796132057058823561033114107090e-19L,
156 -2.16776249440624129587941717218396578e-20L,
157 -1.41940966156001652983322668820112130e-20L,
158 7.50200095064138625532377521619527234e-22L,
159 3.33870453950783971643715159254469304e-22L,
160 -2.30600404426203476825215151352586388e-23L,
161 -7.85817324568948189044990646315027350e-24L,
162 6.66834530437388085486513704613056895e-25L,
163 1.85091565409252971894649796883651603e-25L,
164 -1.85915294451740855841031840576364891e-26L,
165 -4.36297464803458904472660817437095794e-27L,
166 5.06110760995292844822634895878109349e-28L,
167 1.02919182497568782037888979300008731e-28L,
168 -1.35513912210183166156877853283041765e-29L,
169 -2.42940596129573826559241540956570701e-30L,
170 3.58519739665037052115164738053066333e-31L,
171 5.73796581610397206400846538673280837e-32L,
172 -9.40035936245687345352774520389480989e-33L,
173 -1.35590280493486311500090284171223034e-33L,
174 2.44784384191528918377859141748058708e-34L,
175 3.20528849130720958124170712217928968e-35L,
176 -6.33983878185254827964152375942174520e-36L,
177 -7.57925545801218291534870941639851689e-37L
178#endif
179 };
180
181 const long double rz = std::real(z);
182 const long double iz = std::imag(z);
183
184 if (iz == 0) {
185 if (rz == 0) {
186 return { rz, iz };
187 }
188 if (rz == 1) {
189 return { zeta5, iz };
190 }
191 if (rz == -1) {
192 return { -15.0L*zeta5/16.0L, iz };
193 }
194 }
195
196 const long double nz = std::abs(z);
197 const long double pz = std::arg(z);
198 const long double lnz = std::log(nz);
199
200 if (lnz*lnz + pz*pz < 1) { // |log(z)| < 1
201 const std::complex<long double> u(lnz, pz); // log(z)
202 const long double c0 = zeta5;
203 const long double c1 = 1.08232323371113819151600369654116790L; // zeta(4)
204 const long double c2 = 0.601028451579797142699869080755724995L; // zeta(3)/2
205 const long double c3 = 0.274155677808037739412069194441004198L;
206 const auto c4 = (25.0L/12.0L - pos_log(-u))/24.0L;
207 const long double c5 = -1.0L/240.0L;
208 const long double cs[] = {
209 -1.15740740740740740740740740740740741e-04L,
210 2.06679894179894179894179894179894180e-07L,
211 -1.09354441365023375605386187396769407e-09L,
212 8.69864874494504124133753763383393013e-12L,
213 -8.68995878615888235897855907475917096e-14L,
214 1.00812540802188133105305292318749173e-15L,
215 -1.30160058071551887185136369583811112e-17L,
216#if LDBL_DIG > 18
217 1.82193858376471817317584461603964703e-19L,
218 -2.71703945984843566116551019291461834e-21L,
219 4.26404710646461092493552846764602135e-23L,
220 -6.97907523609028772068847244464155123e-25L,
221 1.18322350137468824961908885022923872e-26L,
222 -2.06699310884539801347149709357488995e-28L,
223 3.70514089192917181888714449508744051e-30L,
224 -6.79216396752655546304766934905316826e-32L,
225 1.26987457489641744061409835124861589e-33L,
226 -2.41590408788077922327391223699041147e-35L,
227 4.66812326074215685597260023169508118e-37L
228#endif
229 };
230 const auto u2 = u*u;
231
232 return c0 + u * c1 +
233 u2 * (c2 + u * c3 +
234 u2 * (c4 + u * c5 +
235 u2 * horner<0>(u2, cs)));
236 }
237
238 std::complex<long double> u(0.0L, 0.0L), rest(0.0L, 0.0L);
239
240 if (nz <= 1) {
241 u = -log1p(-z);
242 } else { // nz > 1
243 const long double arg = pz > 0.0 ? pz - PI : pz + PI;
244 const std::complex<long double> lmz(lnz, arg); // log(-z)
245 const auto lmz2 = lmz*lmz;
246 u = -log1p(-1.0L/z);
247 rest = -1.0L/360.0L*lmz*(7*PI4 + lmz2*(10.0L*PI2 + 3.0L*lmz2));
248 }
249
250 return rest + u*horner<0>(u, bf);
251}
252
253} // 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 > Li5(const std::complex< double > &z) noexcept
Complex polylogarithm .
Definition Li5.cpp:34
static constexpr double zeta5
Definition wrappers.hpp:57