# log_integral gives wrong values for complex arguments

Riemann's formula for the number of primes less than a given number requires the calculation of the logarithmic integral (Li(x) or li(x)) for complex values. This function is implemented in Sage as log_integral.

However, it does not seem to give the correct values for complex arguments. When I feed in -4.42464733272289 + 0.649996908475887I it returns -0.0380977804390431 + 4.49840994945387I, but -4.41940689179334 - 0.684720910130221I returns -0.0281163576275170 - 4.50165559913773I, i.e., there seems to be a discontinuity when the imaginary part turns negative.

This script shows the behaviour:

start = 0
end   = 10
steps = 100

args = [(start * (1 - s / steps) + end * (s / steps)) for s in range(steps+1)]
val1 = [20^(1/2+s*i) for s in args]
val2 = [log_integral(s) for s in val1]

for (x,y,z) in zip(args, val1, val2):
print n(x), '\t', n(y), '\t', n(z)


Maybe the problem is that a different branch of the complex logarithm should be used. But the values of the above sequence should converge to pi * i, which doesn't seem to be the case at all.

Has anybody seen this behaviour before or any idea how to fix it?

edit retag close merge delete

Question - do you want li(x) or Li(x), or does it matter here? See http://www.sagemath.org/doc/reference/functions/sage/functions/exp_integral.html for how we do each of these. Usually mpmath is pretty darn accurate so I am a little surprised...

It shouldn't matter here, since li(x) and Li(x) only differ in an additive constant, which should also hold for the complex continuation. But if in doubt - I mean Li(x)...

Yes, and we define it that way, but I just wanted to confirm...

Sort by » oldest newest most voted

It really seems come down to which branch of the complex logarithm you choose. log_integral(x) is implemented as Ei(log(x)), so it depends on the definition of the complex logarithm. Going up the critical line, the following delivers the right values for Li(20^(1/2+s*i)):

Ei((1/2+s*i)*log(20))

more

So, are you saying the Sage definition is "correct" in the sense of using the branch usually chosen?

Yes, I think if you evaluate Li(x) = Ei(log(x)) with the definition of the complex logarithm that Sage implements by default, the value could be considered "correct". But to be honest, I am not sure how the correct mathematical complex continuation of Li is defined. But the above expression certainly gives the expected result when working in the field of analytic number theory.

So I think what your question is about is that log_integral is not giving the same results as Ei(log(x)). Compare sage: Li(-4.41940689179334 - 0.684720910130221*I) -1.07328013774501 - 4.50165559913773*I sage: Ei(log(-4.41940689179334 - 0.684720910130221*I)) -0.0281163576275175 - 4.50165559913773*I sage: Li(-4.42464733272289 + 0.649996908475887*I) -1.08326156055654 + 4.49840994945387*I sage: Ei(log(-4.42464733272289 + 0.649996908475887*I)) -0.0380977804390431 + 4.49840994945387*I Combined with your observations, I would say that maybe it's there is a simplification step being taken which is incorrect in both of these cases, which is why your workaround seems to work...

In private communication, the author of mpmath suggests that Ei could indeed use different branch cuts... I've reported this at http://trac.sagemath.org/ticket/17237