**A Statistical Analysis of Riemann Zeta Zeros via the Real-Valued Z-Function**
### **A Statistical Analysis of Riemann Zeta Zeros via the Real-Valued Z-Function** **Author:** Min Seung Jae**Date:** June 30, 2025 **Abstract:**The study of the non-trivial zeros of the Riemann Zeta function, $\\zeta(s)$, on the critical line $\\Re(s)=1/2$ is central to number theory. However, direct analysis of the complex-valued function $\\zeta(\\frac{1}{2} + it)$ can obscure the underlying dynamics of its zeros. I present a more direct and powerful approach, arguing that the "true essence" of the zeros' behavior is revealed by eliminating the complex phase. This is achieved by employing the Riemann-Siegel Z-function, $Z(t) = e^{i\\vartheta(t)}\\zeta(\\frac{1}{2} + it)$, which is a real-valued function whose sign changes correspond exactly to the zeros of $\\zeta(s)$ on the critical line. I have developed a computational framework in Python, centered around two key algorithms. The first is an automated zero-detector that robustly locates zeros by identifying sign-changes in high-resolution samples of $Z(t)$ and refining them with a numerical root-finder. The second is a statistical analyzer that calculates the spacings between consecutive zeros and normalizes them to account for their increasing density. By applying this framework for $t \\in [0, 300]$, I have located the first 138 zeros and analyzed their distribution. The results reveal a distinct statistical fingerprint: the zeros exhibit strong repulsion and their normalized spacings follow a clear, non-random distribution, consistent with predictions from Random Matrix Theory. This work provides not only a definitive method for exploring the zeros but also compelling visual evidence of the deep statistical laws they obey. ### **1. Introduction: Moving Beyond the Imaginary Illusion** The complex nature of the Riemann Zeta function on the critical line, $\\zeta(\\frac{1}{2} + it)$, presents a challenge. Its value spirals in the complex plane, and identifying the precise moments it passes through the origin (the zeros) requires handling both real and imaginary parts. I argue that this complexity is an "imaginary illusion" that can be stripped away to reveal the true dynamics of the zeros. The key is the Riemann-Siegel Z-function. > **Definition: The Riemann-Siegel Z-function.**> The function is defined as:> $$Z(t) = e^{i\vartheta(t)}\zeta(\frac{1}{2} + it)$$> where $\\vartheta(t)$ is the Riemann-Siegel theta function. For real `t`, $Z(t)$ is always real-valued. A zero of $\\zeta(\\frac{1}{2} + it)$ occurs if and only if $Z(t)=0$. This transforms the problem: instead of finding where a complex function becomes zero, we simply need to find where a real-valued function crosses the axis. The zeros are now unambiguously marked by the sign changes of $Z(t)$. This is the most direct method to probe their behavior. ### **2. Methodology: An Automated Framework for Zero Analysis** I developed a suite of Python scripts using the `mpmath` library for high-precision calculations to automate the entire process of finding and analyzing the zeros. **2.1. Autonomous Zero Detection**The core of the framework is the `find_zeros_by_sign_change` function. The method is as follows: 1. The `Z(t)` function is sampled at a high resolution over a given interval (e.g., 15,000 samples for $t \\in [0, 300]$).2. I iterate through the sampled values, searching for consecutive points where the sign changes (i.e., `Z(t_i) * Z(t_{i+1}) < 0`).3. Such a sign change guarantees a zero exists in the interval `[t_i, t_{i+1}]`.4. The `mpmath.findroot` function is then deployed on this small interval to find the precise location of the zero with high accuracy. **2.2. Statistical Analysis of Spacings**Once a list of zeros is generated, the `analyze_spacings` function performs a statistical analysis: 1. It calculates the sequence of spacings between consecutive zeros: $s\_i = t\_{i+1} - t\_i$.2. To make meaningful comparisons, each spacing is normalized. As `t` increases, the average density of zeros increases according to the asymptotic formula $\\log(t/2\\pi)$. Therefore, each spacing $s\_i$ is divided by the local average spacing, which is approximated by $2\\pi / \\log(t\_{mid}/2\\pi)$, where $t\_{mid}$ is the midpoint of the interval. ### **3. Results and Discussion** **3.1. Visual Confirmation and Autonomous Detection**Initial tests confirmed the validity of the method. The first script, `riemann_siegel_plot.py`, visually demonstrated a perfect correspondence between the known locations of the first 10 zeros and the axis-crossings of the plotted $Z(t)$ function. The more advanced `riemann_siegel_zero_finder.py` then autonomously located the first 29 zeros up to $t=100$ with perfect accuracy, proving the robustness of the sign-change detection algorithm. **Execution Log Snippet (t=0-100):** ```탐지된 영점 수: 29영점 높이들: [14.13472514, 21.02203964, 25.01085758, ..., 98.83119422]``` **3.2. Statistical Fingerprint of the Zeros**The final analysis was extended to $t=300$, successfully locating 138 zeros. The resulting distribution of their normalized spacings is the key finding of this paper. **(Image: Two-panel plot showing Z(t) up to t=300 and the histogram of normalized spacings)** The histogram of these spacings reveals a distinct "statistical fingerprint" with clear properties: * **Zero Repulsion:** The probability density approaches zero as the spacing approaches zero. This indicates that the zeros actively "repel" each other; it is exceedingly rare for two zeros to be extremely close. * **Non-Random Distribution:** The distribution is not uniform or exponential, which would be expected from a random process. Instead, it has a characteristic single-humped shape, peaking near a normalized spacing of 1. This is definitive evidence that the placement of the zeros is governed by a strong, underlying statistical law. This shape is consistent with the GUE (Gaussian Unitary Ensemble) distribution from Random Matrix Theory, a profound connection that links number theory to quantum chaos. ### **4. Conclusion** I have successfully developed and implemented a computational framework that moves beyond simply verifying the location of Riemann Zeta zeros. By leveraging the real-valued Riemann-Siegel Z-function, my method strips away the "imaginary illusion" and allows for a direct, robust, and automated analysis of the zeros' dynamics and statistical properties. The discovery of a clear, non-random statistical fingerprint in the zero spacings, consistent with predictions from Random Matrix Theory, opens a new chapter in the exploration of the primes. The ultimate nature of the Riemann Hypothesis is not just in the location of its zeros, but in the deep statistical laws that govern them. ### **Appendix: The Final Spacing Analyzer Code** ```python# -*- coding: utf-8 -*-"""riemann_siegel_spacing_analyzer.py Purpose:- Extends the zero-finder to analyze the statistical properties of the zeros.- Finds zeros of the Riemann-Siegel Z(t) function in a larger range.- Calculates the spacings between consecutive zeros.- Normalizes these spacings to account for increasing zero density.- Plots a histogram of the normalized spacings to visualize their distribution. Author: Min Seung JaeDate: 2025-06-30""" import numpy as npimport mpmath as mpimport matplotlib.pyplot as plt mp.mp.dps = 30 # 1) Riemann–Siegel θ(t)def theta(t): return mp.im(mp.log(mp.gamma(0.25 + 0.5j*t))) - 0.5*t*mp.log(mp.pi) # 2) Z(t): always real-valueddef Z(t): return mp.re(mp.e**(1j*theta(t)) * mp.zeta(0.5 + 1j*t)) # 3) Automated zero detection via sign-changedef find_zeros_by_sign_change(t_vals, Z_vals): zero_ts = [] for i in range(len(t_vals)-1): if Z_vals[i] * Z_vals[i+1] < 0: t_left, t_right = t_vals[i], t_vals[i+1] root = mp.findroot(Z, (t_left, t_right)) zero_ts.append(float(root)) return sorted(list(set(np.round(zero_ts, 8)))) # 4) Calculation of spacings and normalized spacingsdef analyze_spacings(zeros): spacings = np.diff(zeros) normalized_spacings = [] for i in range(len(zeros) - 1): t_mid = (zeros[i] + zeros[i+1]) / 2.0 avg_spacing = (2 * np.pi) / np.log(t_mid / (2 * np.pi)) normalized_spacings.append(spacings[i] / avg_spacing) return spacings, np.array(normalized_spacings) if __name__ == "__main__": # Settings t_min, t_max = 0, 300 N_samples = 15000 ts = np.linspace(t_min, t_max, N_samples) # Calculation print(f"Calculating Z(t) values (t=0 to {t_max})...") Z_vals = [Z(t) for t in ts] print("Detecting zeros...") zeros = find_zeros_by_sign_change(ts, Z_vals) print(f"Number of detected zeros: {len(zeros)}") print("Analyzing zero spacings...") spacings, normalized_spacings = analyze_spacings(zeros) # Visualization (Two plots) fig, axs = plt.subplots(2, 1, figsize=(14, 12)) # Plot 1: Z(t) and its zeros axs[0].plot(ts, Z_vals, lw=0.8, label='Z(t)') axs[0].axhline(0, color='black', lw=0.8) axs[0].scatter(zeros, np.zeros_like(zeros), color='red', s=15, zorder=5, label=f'Found Zeros ({len(zeros)})') axs[0].set_xlim(t_min, t_max) axs[0].set_xlabel('t (imaginary coordinate)') axs[0].set_ylabel('Z(t) ∈ ℝ') axs[0].set_title(f'Riemann–Siegel Z(t) & Automatically Detected Zeros (up to t={t_max})') axs[0].legend() axs[0].grid(True) # Plot 2: Histogram of normalized spacings axs[1].hist(normalized_spacings, bins=50, density=True, alpha=0.75, label='Normalized Spacing Distribution') axs[1].set_xlabel('Normalized Spacing (s / <_s>)') axs[1].set_ylabel('Probability Density') axs[1].set_title('Distribution of Normalized Spacings Between Zeros') axs[1].legend() axs[1].grid(True) plt.tight_layout() plt.show()```
Publication Details
- Journal
- Zenodo (CERN European Organization for Nuclear Research)
- Published
- 2025-06-30
- DOI
- https://doi.org/10.5281/zenodo.15775682
- Primary Topic
- Analytic Number Theory Research
- Type
- article
- Field-Weighted Citation Impact
- 0.00