# An experimental guide to the Riemann conjecture

The term must be correct my guide Proof. It is not formal proof from a mathematical point of view, but strong arguments based on empirical evidence. It is noteworthy that I decided to publish it. In this article I go straight to the point without discussing the concepts in detail. The goal is to provide a quick overview so that a busy reader can get a good idea of ​​the method. Also, it is a great introduction to the Python MPmath library for scientific computing, which deals with advanced and complex mathematical functions. In fact, I hesitated for a long time between choosing the current title and “Introduction to the MPmath Python Library for Scientific Programming”.

## Generalized Riemann hypothesis

The generalized Riemann hypothesis or conjecture (GRH) states the following. A certain type of complex job the(sAnd χ) have no roots when the real part of the argument s Between 0.5 and 1. Here χ is a parameter called character , and s = σ + meR is the argument. The real part is σ. Blogging can seem awkward. But it is well established. I don’t use it to confuse mathematicians. Personal χ It is a multiplication function defined on positive integers. I focus on χ4Dirichlet’s main character form 4:

• if s is a prime number and s So – 1 is a multiple of 4 χ4(s) = 1
• If p is a prime number and s – 3 is a multiple of 4, then χ4(s) = -1
• if s = 2, χ4(s) = 0

These functions have an Euler product:

L(s,\chi) = \prod_p \Bigg(1 - \frac{\chi(p)}{p^{s}}\Bigg)^{-1},

where the product is above all prime numbers. The crux of the problem is the convergence of the product at its real part s (code σ) fulfilled σ ≤ 1. If σ > 1, the convergence is absolute and thus the function the It does not have a root dependent on an Euler product. If convergence is not absolute, there may be invisible roots “hidden” behind the formula of the product. This happens when σ = 0.5.

## Where it gets very interesting

Prime numbers s Alternate somewhat randomly between χ4(s) = +1 f χ4(s) = -1 in equal proportions (50/50) when you consider all of them. This is a consequence of Dirichlet’s theory. But with those χ4(s) = -1 get a very strong start, a fact known as the Chebyshev bias.

The idea is to rearrange the operators in Euler’s product so that if χ4(s) = +1, its next factor χ4(s) = -1. And vice versa, with as few changes as possible. I call the resulting product the whipped product. You may remember your math teacher saying that you cannot change the order of terms in a series unless you have absolute convergence. This is true here too. Actually, this is the crux of the matter.

Assuming the operation is legitimate, you add each successive pair of operators, (1 – p-s) and (1 + F-s), in one factor. when s Too big, corresponding F very close to s so that (1 – p-s) (1 + F-s) very close to (1 – p-2 sec). For example, if s = 4,999,961 then F = 4995923.

## magic trick

On the assumption that s and then F = s + Δs close enough when s So big, scrambling and bundling turn the product into one that converges just when σ (The real part of s) is greater than 0.5 with precision. As a result, there is no root if σ >0.5. Although there is an infinite number of when σ = 0.5, where the affinity for the product is uncertain. In the latter case, one can use the analytic continuation of the calculation the. It voila!

It all boils down to whether Δs Small enough compared to swhen s he is big. To this day no one knows, and thus GRH remains unproven. However, you can use Euler’s product for the calculation the(sAnd χ4) not just when σ > 1 of course, but also when σ >0.5. You can do this using the Python code below. It is ineffective, there are much faster ways, but it works! In mathematical circles, I have been told that such calculations are “illegal” because no one knows the convergence state. Knowing the affinity state is equivalent to solving GRH. However, if you play around with the code, you’ll see that convergence is “obvious”. At least when R not very big, σ Not too close to 0.5, and you’re using many millions of prime numbers in the product.

There is one caveat. You can use the same approach for different Dirichlet-L functions the(sAnd χ), and not just for χ = χ4. But there is one χ For which the method does not apply: when it is a constant equal to 1, and therefore does not rotate. that χ It corresponds to the classic Riemann zeta function ζ(s). Although the method won’t work for the most famous case, just have official proof χ4 It will instantly turn you into the most famous mathematician of all time. However, recent attempts to prove GRH avoid the direct approach (going through factoring) but instead focus on other statements that are equivalent to or implied by GRH. See my article on the topic, here. for roots the(sAnd χ4), We see here.

## Python code with MPmath library

I figured the(sAnd χ) and various related functions using different formulas. The goal is to test whether the Euler product converges as expected to the correct value of 0.5 σ <1. The code is also in my GitHub repository, here.

import matplotlib.pyplot as plt
import mpmath
import numpy as np
from primePy import primes

m =  150000
p1 = []
p3 = []
p  = []
cnt1 = 0
cnt3 = 0
cnt  = 0
for k in range(m):
if primes.check(k) and k>1:
if k % 4 == 1:
p1.append(k)
p.append(k)
cnt1 += 1
cnt += 1
elif k % 4 ==3:
p3.append(k)
p.append(k)
cnt3 += 1
cnt += 1

cnt1 = len(p1)
cnt3 = len(p3)
n = min(cnt1, cnt3)
max = min(p1[n-1],p3[n-1])

print(n,p1[n-1],p3[n-1])
print()

sigma = 0.95
t_0 = 6.0209489046975965 # 0.5 + t_0*i is a root of DL4

DL4 = []
imag = []
print("------ MPmath library")
for t in np.arange(0,1,0.25):
f = mpmath.dirichlet(complex(sigma,t), [0, 1, 0, -1])
DL4.append(f)
imag.append
r = np.sqrt(f.real**2 + f.imag**2)
print("%8.5f %8.5f %8.5f" % (t,f.real,f.imag))

print("------ scrambled product")
for t in np.arange(0,1,0.25):
prod = 1.0
for k in range(n):
num1 = 1 - mpmath.power(1/p1[k],complex(sigma,t))
num3 = 1 + mpmath.power(1/p3[k],complex(sigma,t))
prod *= (num1 * num3)
prod = 1/prod
print("%8.5f %8.5f %8.5f" % (t,prod.real,prod.imag))

DL4_bis = []
print("------ scrambled swapped")
for t in np.arange(0,1,0.25):
prod = 1.0
for k in range(n):
num1 = 1 + mpmath.power(1/p1[k],complex(sigma,t))
num3 = 1 - mpmath.power(1/p3[k],complex(sigma,t))
prod *= (num1 * num3)
prod = 1/prod
DL4_bis.append(prod)
print("%8.5f %8.5f %8.5f" % (t,prod.real,prod.imag))

print("------ compare zeta with DL4 * DL4_bis")
for i in range(len(DL4)):
t = imag[i]
if t == 0 and sigma == 0.5:
print("%8.5f" %
else:
zeta = mpmath.zeta(complex(2*sigma,2*t))
prod = DL4[i] * DL4_bis[i] / (1 - 2**(-complex(2*sigma,2*t)))
print("%8.5f %8.5f %8.5f %8.5f %8.5f" % (t,zeta.real,zeta.imag,prod.real,prod.imag))

print("------ correct product")
for t in np.arange(0,1,0.25):
prod = 1.0
chi = 0
k = 0
while p[k] <= max:
pp = p[k]
if pp % 4 == 1:
chi = 1
elif pp % 4 == 3:
chi = -1
num = 1 - chi * mpmath.power(1/pp,complex(sigma,t))
prod *= num
k = k+1
prod = 1/prod
print("%8.5f %8.5f %8.5f" % (t,prod.real,prod.imag))

print("------ series")
for t in np.arange(0,1,0.25):
sum = 0.0
flag = 1
k = 0
while 2*k + 1 <= 10000:
num = flag * mpmath.power(1/(2*k+1),complex(sigma,t))
sum = sum + num
flag = -flag
k = k + 1
print("%8.5f %8.5f %8.5f" % (t,sum.real,sum.imag))