exp-pairs-0.1.4.0: Math/ExpPairs/Ivic.hs
{-|
Module : Math.ExpPairs.Ivic
Description : Riemann zeta-function
Copyright : (c) Andrew Lelechenko, 2014-2015
License : GPL-3
Maintainer : andrew.lelechenko@gmail.com
Stability : experimental
Portability : POSIX
Provides functions to compute estimates Riemann zeta-function
ζ in a critical strip, given in /Ivić A./ `The Riemann zeta-function: Theory and applications',
Mineola, New York: Dover Publications, 2003.
-}
module Math.ExpPairs.Ivic
( zetaOnS
, reverseZetaOnS
, mOnS
, reverseMOnS
, checkAbscissa
, findMinAbscissa
, mBigOnHalf
, reverseMBigOnHalf
) where
import Data.Ratio
import Data.List (minimumBy)
import Data.Ord (comparing)
import Math.ExpPairs
-- | Compute µ(σ) such that |ζ(σ+it)| ≪ |t|^µ(σ) .
-- See equation (7.57) in Ivić2003.
zetaOnS :: Rational -> OptimizeResult
zetaOnS s
| s >= 1 = simulateOptimize 0
| s >= 1%2 = optimize
[RationalForm (LinearForm 1 1 (-s)) 2]
[Constraint (LinearForm (-1) 1 (-s)) NonStrict]
| otherwise = optRes {optimalValue = r} where
optRes = zetaOnS (1-s)
r = Finite (1%2 - s) + optimalValue optRes
zetaOnHalf :: Rational
zetaOnHalf = 32%205
-- | An attempt to reverse 'zetaOnS'.
reverseZetaOnS :: Rational -> OptimizeResult
reverseZetaOnS mu
| mu >= 1%2 = simulateOptimize 0
| mu > zetaOnHalf = optimize [RationalForm (LinearForm 1 (-1) 1) 1] [Constraint (LinearForm 0 (-2) (1+2*mu)) NonStrict]
| mu == zetaOnHalf = simulateOptimize (1 % 2)
| otherwise = optRes {optimalValue = negate $ optimalValue optRes} where
optRes = optimize [RationalForm (LinearForm 1 (-1) 0) 1] [Constraint (LinearForm 1 0 (-mu)) NonStrict, Constraint (LinearForm (-1) 1 (-1%2)) NonStrict]
lemma82_f :: Rational -> Rational
lemma82_f s
| s < 1%2 = undefined
| s<= 2%3 = 2/(3-4*s)
| s<=11%14 = 10/(7-8*s)
| s<=13%15 = 34/(15-16*s)
| s<=57%62 = 98/(31-32*s)
| otherwise = 5/(1-s)
-- | Compute maximal m(σ) such that ∫_1^T |ζ(σ+it)|^m(σ) dt ≪ T^(1+ε).
-- See equation (8.97) in Ivić2003. Further justification will be published elsewhere.
mOnS :: Rational -> OptimizeResult
mOnS s
| s < 1%2 = simulateOptimize 0
| s < 5%8 = simulateOptimize $ 4/(3-4*s)
| s>= 1 = simulateOptimize' InfPlus
| otherwise = minimumBy (comparing optimalValue) [x1, x2, simulateOptimize (lemma82_f s * 2)] where
optRes = zetaOnS s
muS = toRational $ optimalValue optRes
alpha1 = (4-4*s)/(1+2*s)
beta1 = -12/(1+2*s)
x1 = optRes {optimalValue = Finite $ (1-alpha1)/muS - beta1}
--alpha2 = 4*(1-s)*(k+l)/((2*m+4*l)*s-m+2*k-2*l)
--beta2 = -4*(m+2*k+2*l)/((2*m+4*l)*s-m+2*k-2*l)
--ratio = (1-alpha2)/muS - beta2
--numer = numerator ratio
--denom = denominator ratio
numer = LinearForm
(-4*s + (-8*muS + 2))
(-8*s + (-8*muS + 6))
(-2*s + (-4*muS + 1))
denom = LinearForm
(2*muS)
(4*muS*s - 2*muS)
(2*muS*s - muS)
cons = if s >= 2%3 then [] else [Constraint
(LinearForm (4*s-2) (8*s-6) (2*s-1)) NonStrict
]
x2' = optimize [RationalForm numer denom] cons
x2 = x2' {optimalValue = negate $ optimalValue x2'}
-- | Try to reverse 'mOnS': for a given precision and m compute minimal possible σ.
-- Implementation is usual try-and-divide search, so performance is very poor.
-- Sometimes, when 'mOnS' gets especially lucky exponent pair, 'reverseMOnS' can miss
-- real σ and returns bigger value.
reverseMOnS :: Rational -> RationalInf -> Rational
reverseMOnS prec m = reverseMOnS' from to where
from = 1 % 2
to = 1
reverseMOnS' a b
| b - a < prec = c
| optimalValue (mOnS c) > m = reverseMOnS' a c
| otherwise = reverseMOnS' c b
where
c = (numerator a + numerator b) % (denominator a + denominator b)
-- | Check whether ∫_1^T Π_i |ζ(n_i*σ+it)|^m_i dt ≪ T^(1+ε) for a given list of pairs [(n_1, m_1), ...] and fixed σ.
checkAbscissa :: [(Rational, Rational)] -> Rational -> Bool
checkAbscissa xs s = sum rs < Finite 1 where
qs = map (\(n,m) -> optimalValue (mOnS (n*s)) / Finite m) xs
rs = map (\q -> 1/q) qs
-- | Find for a given precision and list of pairs [(n_1, m_1), ...] the minimal σ
-- such that ∫_1^T Π_i|ζ(n_i*σ+it)|^m_i dt ≪ T^(1+ε).
findMinAbscissa :: Rational -> [(Rational, Rational)] -> Rational
findMinAbscissa prec xs = searchMinAbscissa' from to where
from = 1 % 2 / minimum (map fst xs)
to = 1 % 1
searchMinAbscissa' a b
| b - a < prec = b
| checkAbscissa xs c = searchMinAbscissa' a c
| otherwise = searchMinAbscissa' c b
where
c = (numerator a + numerator b) % (denominator a + denominator b)
-- | Compute minimal M(A) such that ∫_1^T |ζ(1/2+it)|^A dt ≪ T^(M(A)+ε).
-- See Ch. 8 in Ivić2003. Further justification will be published elsewhere.
mBigOnHalf :: Rational -> OptimizeResult
mBigOnHalf a
| a < 4 = simulateOptimize 1
| a < 12 = simulateOptimize $ 1+(a-4)/8
| a > 41614060315296730740083860226662 % 2636743270445733804969041895717 = simulateOptimize $ 1 + 32*(a-6)/205
| otherwise = if Finite x >= optimalValue optRes
then simulateOptimize x
else optRes where
optRes = optimize [RationalForm (LinearForm 1 1 0) (LinearForm 1 0 0)]
[Constraint (LinearForm (4-a) 4 2) NonStrict]
x = 1 + 32*(a-6)/205
-- Constant 41614060315296730740083860226662 % 2636743270445733804969041895717
-- is produced by
-- optimize [RationalForm (LinearForm 4 4 2) (LinearForm 1 0 0)] [Constraint (LinearForm (-64) (-77) 64) Strict]
-- | Try to reverse 'mBigOnHalf': for a given M(A) find maximal possible A.
-- Sometimes, when 'mBigOnHalf' gets especially lucky exponent pair, 'reverseMBigOnHalf' can miss
-- real A and returns lower value.
reverseMBigOnHalf :: Rational -> OptimizeResult
reverseMBigOnHalf m
| m <= 2 = simulateOptimize $ (m-1)*8 + 4
| otherwise = if Finite a <= optimalValue optRes
then simulateOptimize a
else optRes where
a = (m-1)*205/32 + 6
optRes = optimize [RationalForm (LinearForm 4 4 2) (LinearForm 1 0 0)] [Constraint (LinearForm (1-m) 1 0) NonStrict]