libadic is a C++ library implementing p-adic arithmetic and the Reid-Li criterion for the Riemann Hypothesis. This document outlines all algorithms, mathematical formulations, and implementation details for independent verification.
File: include/libadic/zp.h, src/fields/zp.cpp
Internal Representation:
class Zp {
long prime; // The prime p
long precision; // Precision N in O(p^N)
BigInt value; // Value mod p^N
}Key Algorithms:
- Addition/Subtraction:
(a ± b) mod p^N - Multiplication:
(a × b) mod p^N - Division: Requires b coprime to p, computes
a × b^(-1) mod p^Nusing extended GCD - Valuation: Always returns 0 for Zp (no p-factors in unit)
- Teichmüller character:
Computed via iteration:
ω(a) = lim_{n→∞} a^(p^n) mod p^Na₀ = a, a_{n+1} = a_n^puntil convergence
File: include/libadic/qp.h, src/fields/qp.cpp
Internal Representation:
class Qp {
long prime;
long precision;
long valuation_val; // Power of p
Zp unit; // Unit part (coprime to p)
}
// Represents: unit × p^valuationPrecision Formula for Division:
new_precision = min(precision - valuation, other.precision - other.valuation)
+ min(new_valuation, 0)This correctly models precision loss when dividing by p.
File: include/libadic/gmp_wrapper.h, src/base/gmp_wrapper.cpp
- Wrapper around GMP's
mpz_t - RAII pattern for automatic memory management
- All standard arithmetic operations via GMP
File: include/libadic/padic_log.h, src/functions/padic_log.cpp
Algorithm: Standard Taylor series
log_p(1 + u) = u - u²/2 + u³/3 - u⁴/4 + ...
Convergence Condition:
- Requires
v_p(u) > 0(i.e., u ≡ 0 mod p) - For p = 2, requires
v_2(u) ≥ 2
Precision Management:
// Calculate precision loss from division by p
long p_divides_count = 0;
for (long n = p; n <= N * 2; n *= p) {
p_divides_count++;
}
long working_precision = N + p_divides_count + 5;This compensates for precision loss when n = p, p², p³, ... in the series.
File: include/libadic/padic_gamma.h, src/functions/padic_gamma.cpp
Definition (for positive integers):
Γ_p(n) = (-1)^n × (n-1)!
Key Properties Verified:
Γ_p(1) = -1Γ_p(2) = 1Γ_p(p) = 1- Functional equation:
Γ_p(x+1) = -x × Γ_p(x) - Reflection formula:
Γ_p(x) × Γ_p(1-x) = ±1
Extension to Zp: Via continuous extension using the functional equation
File: Defined as log_gamma_p() using composition
Algorithm:
Qp log_gamma_p(const Zp& gamma_val) {
if (!gamma_val.is_unit()) throw error;
Qp gamma_qp(gamma_val);
return log_p(gamma_qp);
}File: include/libadic/bernoulli.h, src/functions/bernoulli.cpp
Recursive Formula:
B₀ = 1
Σ_{k=0}^{n} C(n+1,k) × B_k = 0 for n ≥ 1
Generalized Bernoulli Numbers B_{n,χ}:
B_{n,χ} = n^(-1) × Σ_{a=1}^{f} χ(a) × Σ_{k=0}^{n-1} C(n,k) × B_k × a^(n-k)where f is the conductor of χ.
File: include/libadic/characters.h, src/functions/characters.cpp
Representation: Table of values for each residue class
Primitive Character Test:
- Character χ mod n is primitive if not induced from any proper divisor of n
- Check: χ(a) ≠ 1 for some a with gcd(a,n) = 1
Enumeration Algorithm:
- Find generators of (Z/nZ)*
- For each homomorphism to roots of unity
- Test primitivity
- Return list of primitive characters
File: include/libadic/l_functions.h, src/functions/l_functions.cpp
Kubota-Leopoldt L-function at negative integers:
L_p(1-n, χ) = -(1 - χ(p)p^(n-1)) × B_{n,χ}/n
Special Values:
L_p(0, χ) = -(1 - χ(p)/p) × B_{1,χ}- Derivative computed via differentiation of p-adic measure
For odd primitive characters χ:
Φ_p^(odd)(χ) = Σ_{a=1}^{p-1} χ(a) × log_p(Γ_p(a))
Ψ_p^(odd)(χ) = L'_p(0, χ)
For even primitive characters χ:
Φ_p^(even)(χ) = Σ_{a=1}^{p-1} χ(a) × log_p(a/(p-1))
Ψ_p^(even)(χ) = L_p(0, χ)
Reid-Li Criterion:
Φ_p^(odd/even)(χ) ≡ Ψ_p^(odd/even)(χ) (mod p^N)
File: tests/milestone1_test.cpp
Algorithm:
- Enumerate all primitive Dirichlet characters mod p
- For each character:
- Determine if odd or even
- Compute Φ_p using summation
- Compute Ψ_p using L-functions
- Verify equality to precision O(p^N)
All implemented in validate_mathematics.cpp:
- Fermat's Little Theorem:
a^(p-1) ≡ 1 (mod p)for gcd(a,p) = 1 - Wilson's Theorem:
(p-1)! ≡ -1 (mod p) - Geometric Series:
(1-p) × (1 + p + p² + ...) = 1in Zp - Hensel's Lemma: Lifting solutions via Newton's method
- Teichmüller Properties:
ω(a)^(p-1) = 1ω(a) ≡ a (mod p)
Logarithm:
- Additivity:
log(xy) = log(x) + log(y)(with precision loss accepted) - Series convergence for
|u|_p < 1
Gamma Function:
- Morita's values:
Γ_p(1) = -1,Γ_p(2) = 1 - Reflection formula verified
- Functional equation tested
Principle: Every operation tracks precision explicitly
Key Insight: When dividing by p in Qp, precision decreases by 1. This is mathematically correct, not a bug.
p-adic Norm: |x|_p = p^(-v_p(x))
Series Convergence:
- Requires terms → 0 in p-adic norm
- For log:
|u^n/n|_p → 0requires|u|_p < 1
For operations that lose precision (like log series with division by p):
- Calculate expected precision loss
- Start with higher working precision
- Return result with honest final precision
test_gmp_wrapper.cpp: 58 tests for BigInttest_zp.cpp: 94 tests for p-adic integerstest_qp.cpp: 59 tests for p-adic numberstest_functions.cpp: 40 tests for special functions
validate_mathematics.cpp: 17 mathematical theorems verifiedmilestone1_test.cpp: Reid-Li criterion for p = 5, 7, 11
- No approximations allowed
- Exact arithmetic only
- Precision tracked and verified
- Mathematical theorems as test cases
- Morita's p-adic Gamma: No other library has this specific formulation
- log(Γ_p(a)): Requires Morita's Gamma
- Reid-Li Φ computation: Depends on above
- Reid-Li criterion verification: Complete framework
The docs/validation/ directory contains:
- Proof that PARI/GP cannot implement Reid-Li
- Proof that SageMath lacks required functions
- Performance benchmarks
- Challenge problems only libadic can solve
- Full Taylor series for logarithm (no term skipping)
- Honest precision reporting (no artificial inflation)
- Exact Morita Gamma values
When precision loss is unavoidable (e.g., dividing by p):
- Calculate with extra precision internally
- Return honest final precision
- Document where precision is lost
- Domain errors for non-convergent series
- Precision warnings when significant loss occurs
- No silent failures
- GMP (GNU Multiple Precision Arithmetic Library)
- MPFR (Multiple Precision Floating-Point Reliable Library)
- C++17 compiler
- CMake 3.14+
- Supports static and shared libraries
- CPack for package generation
- Debian packaging for apt distribution
- Source build via CMake
- Debian packages (.deb)
- PPA for Ubuntu/Debian
- Docker container
For independent verification, confirm:
✓ Morita's Gamma values: Γ_p(1) = -1, Γ_p(2) = 1, Γ_p(p) = 1 ✓ Logarithm series: Complete Taylor series with no term skipping ✓ Precision formula: Correct handling of p-division ✓ Teichmüller convergence: ω(a) = lim a^(p^n) ✓ Wilson's theorem: Via Gamma function ✓ Reid-Li sums: Φ_p correctly computed ✓ L-function values: Match theoretical formulas
- GitHub: https://github.com/IguanAI/libadic
- Mathematical queries: Contact Reid & Li
- Implementation queries: See CONTRIBUTING.md
This document provides complete implementation details for independent verification of libadic's mathematical correctness and uniqueness.