# 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...

( 2014-10-26 04:48:13 +0100 )edit

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)...

( 2014-10-27 15:37:01 +0100 )edit

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

( 2014-10-27 16:28:39 +0100 )edit

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?

( 2014-10-27 14:46:46 +0100 )edit

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.

( 2014-10-27 15:35:26 +0100 )edit

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...

( 2014-10-27 16:40:24 +0100 )edit

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

( 2014-10-27 19:30:12 +0100 )edit

Thanks for that!

( 2014-10-28 11:44:13 +0100 )edit