exp-pairs-0.1.4.0: tests/Ivic.hs
module Ivic where
import Data.Ratio
import Math.ExpPairs
import Math.ExpPairs.Ivic
import Test.Tasty
import Test.Tasty.SmallCheck as SC
import Test.Tasty.QuickCheck as QC
import Test.Tasty.HUnit
import Instances
import Etalon (testEtalon)
fromMinus3To3 :: Rational -> Rational
fromMinus3To3 n = (n - 1 % 2) * 6
fromHalfToOne :: Rational -> Rational
fromHalfToOne n = n / 2 + 1 % 2
testZetaOnS1 :: Sorted (Ratio01 Rational, Ratio01 Rational) -> Bool
testZetaOnS1 (Sorted (Ratio01 a', Ratio01 b')) = a == b || za >= zb where
[ a, b] = map fromMinus3To3 [a', b']
[za, zb] = map (optimalValue . zetaOnS) [a, b]
-- May fail due to the granularity of 'sect'.
testZetaOnS2 :: Sorted (Ratio01 Rational, Ratio01 Rational) -> Bool
testZetaOnS2 (Sorted (Ratio01 a, Ratio01 b)) = a == b || za > zb where
[za, zb] = map (optimalValue . zetaOnS) [a, b]
testZetaOnSsym :: Ratio01 Rational -> Bool
testZetaOnSsym (Ratio01 a') = (toRational . abs) (za - za') == abs (a - 1 % 2) where
a = fromMinus3To3 a'
za = optimalValue $ zetaOnS a
za' = optimalValue $ zetaOnS (1 - a)
testZetaOnSZero :: Ratio01 Rational -> Bool
testZetaOnSZero (Ratio01 a') = a < 1 || optimalValue (zetaOnS a) == 0 where
a = fromMinus3To3 a'
testMOnS1 :: Sorted (Ratio01 Rational, Ratio01 Rational) -> Bool
testMOnS1 (Sorted (Ratio01 a', Ratio01 b')) = a == b || za <= zb where
[ a, b] = map fromMinus3To3 [a', b']
[za, zb] = map (optimalValue . mOnS) [a, b]
testMOnS2 :: Sorted (Ratio01 Rational, Ratio01 Rational) -> Bool
testMOnS2 (Sorted (Ratio01 a', Ratio01 b')) = a == b || za < zb where
[ a, b] = map fromHalfToOne [a', b']
[za, zb] = map (optimalValue . mOnS) [a, b]
testMOnSZero :: Ratio01 Rational -> Bool
testMOnSZero (Ratio01 a') = a >= 1%2 || (optimalValue . mOnS) a == 0 where
a = fromMinus3To3 a'
testMOnSInf :: Ratio01 Rational -> Bool
testMOnSInf (Ratio01 a') = a < 1 || (optimalValue . mOnS) a == InfPlus where
a = fromMinus3To3 a'
testZetaReverse :: Ratio01 Rational -> Bool
testZetaReverse (Ratio01 s') = abs (s - t) <= 5 % 1000 where
s = s' / 2
zs = zetaOnS s
t = toRational $ optimalValue $ reverseZetaOnS $ toRational $ optimalValue zs
-- Convexity tests - they fail and it is OK
testZetaConvex :: Sorted (Ratio01 Rational, Ratio01 Rational, Ratio01 Rational) -> Bool
testZetaConvex (Sorted (Ratio01 a, Ratio01 b, Ratio01 c)) = a == b || b == c || zb <= k * Finite b + l where
[za, zb, zc] = map (optimalValue . zetaOnS) [a, b, c]
k = (za - zc) / Finite (a - c)
l = za - k * Finite a
-- Ivic, Th. 8.1, p. 205
testMConvex :: Sorted (Ratio01 Rational, Ratio01 Rational, Ratio01 Rational) -> Bool
testMConvex (Sorted (Ratio01 a', Ratio01 b', Ratio01 c')) = a==b || b==c || za==InfPlus || zc==InfPlus
|| zb>= za*zc*Finite(c-a)/(zc*Finite(c-b) + za*Finite(b-a)) where
[a,b,c] = map fromHalfToOne [a', b', c']
[za, zb, zc] = map (optimalValue . mOnS) [a,b,c] :: [RationalInf]
etalonZetaOnS :: Integer -> Integer -> Integer -> Integer -> Bool
etalonZetaOnS a b c d = Finite (c%d) >= optimalValue (zetaOnS $ a%b)
etalonMOnS :: Integer -> Integer -> Integer -> Integer -> Bool
etalonMOnS a b c d = Finite (c%d) <= (optimalValue . mOnS) (a%b)
testSuite :: TestTree
testSuite = testGroup "Ivic"
[ testCase "etalon zetaOnS"
(testEtalon 100 (\(a:b:c:d:_) -> etalonZetaOnS a b c d) "tests/etalon-zetaOnS.txt")
, testCase "etalon mOnS"
(testEtalon 100 (\(a:b:c:d:_) -> etalonMOnS a b c d) "tests/etalon-mOnS.txt")
, adjustOption (\(SC.SmallCheckDepth n) -> SC.SmallCheckDepth (n `div` 2)) $
SC.testProperty "zetaOnS monotonic" testZetaOnS1
, QC.testProperty "zetaOnS monotonic" testZetaOnS1
, adjustOption (\(SC.SmallCheckDepth n) -> SC.SmallCheckDepth (n `div` 2)) $
SC.testProperty "zetaOnS strict monotonic" testZetaOnS2
, QC.testProperty "zetaOnS strict monotonic" testZetaOnS2
, adjustOption (\(SC.SmallCheckDepth n) -> SC.SmallCheckDepth (n `div` 2)) $
SC.testProperty "mOnS monotonic" testMOnS1
, QC.testProperty "mOnS monotonic" testMOnS1
-- , adjustOption (\(SC.SmallCheckDepth n) -> SC.SmallCheckDepth (n `div` 2)) $
-- SC.testProperty "mOnS strict monotonic" testMOnS2
-- , QC.testProperty "mOnS strict monotonic" testMOnS2
, SC.testProperty "zetaOnS reverse" testZetaReverse
, QC.testProperty "zetaOnS reverse" testZetaReverse
, SC.testProperty "zetaOnS symmetry" testZetaOnSsym
, QC.testProperty "zetaOnS symmetry" testZetaOnSsym
, SC.testProperty "zetaOnS above s=1" testZetaOnSZero
, QC.testProperty "zetaOnS above s=1" testZetaOnSZero
, SC.testProperty "mOnS below s=1/2" testMOnSZero
, QC.testProperty "mOnS below s=1/2" testMOnSZero
, SC.testProperty "mOnS above s=1" testMOnSInf
, QC.testProperty "mOnS above s=1" testMOnSInf
-- , SC.testProperty "mOnS convex" testMConvex
-- , QC.testProperty "mOnS convex" testMConvex
-- , SC.testProperty "zetaOnS convex" testZetaConvex
-- , QC.testProperty "zetaOnS convex" testZetaConvex
]