Skip to content

Commit

Permalink
[#118] Add test to divModE
Browse files Browse the repository at this point in the history
  • Loading branch information
rockbmb committed Aug 13, 2018
1 parent 3b481b2 commit 76d2415
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 21 deletions.
42 changes: 21 additions & 21 deletions Math/NumberTheory/EisensteinIntegers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -100,38 +100,38 @@ divModE alfa beta | norm rho1 < norm rho2 = (gamma1, rho1)

-- First step of assignments performed in the Division Algorithm from
-- Theorem 4.1.1.
alfa' = eisensteinToComplex alfa
beta' = eisensteinToComplex beta
a1 C.:+ b1 = alfa' / beta'
a2 C.:+ b2 = alfa' / beta' - eisensteinToComplex ω
alfa' = eisensteinToComplex alfa
beta' = eisensteinToComplex beta
a1 C.:+ b1 = alfa' / beta'
a2 C.:+ b2 = (alfa' / beta') - eisensteinToComplex ω

-- @round@s a @Double@ and returns that as another @Double@.
dToIToD :: Double -> Double
dToIToD = (fromIntegral :: Integer -> Double) . round
dToIToD :: Double -> Double
dToIToD = (fromIntegral :: Integer -> Double) . round

-- Second step of assignments performed in the Division Algorithm from
-- Theorem 4.1.1.
properFraction' :: Double -> (Integer, Double)
properFraction' = properFraction
rho' :: Double -> Double -> C.Complex Double
rho' a' b' = (snd $ properFraction' a') C.:+ (b' - sqrt3 * dToIToD (b' / sqrt3))
rho1' = rho' a1 b1
rho2' = rho' a2 b2
properFraction' :: Double -> (Integer, Double)
properFraction' = properFraction
rho' :: Double -> Double -> C.Complex Double
rho' a' b' = (snd $ properFraction' a') C.:+ (b' - sqrt3 * dToIToD (b' / sqrt3))
rho1' = rho' a1 b1
rho2' = rho' a2 b2

-- Converts a complex number in the form @a + bι@, where @a, b@ are
-- @Double@s, into an @EisensteinInteger@ in the form @α + βω@, where
-- @α, β@ are @Integer@s.
toEisen :: C.Complex Double -> EisensteinInteger
toEisen (x C.:+ y) = round (x + y / sqrt3) :+ round (y * 2 / sqrt3)
toEisen :: C.Complex Double -> EisensteinInteger
toEisen (x C.:+ y) = round (x + y / sqrt3) :+ round (y * 2 / sqrt3)

-- Third step of assignments performed in the Division Alrgorithm from
-- Third step of assignments performed in the Division Algorithm from
-- Theorem 4.1.1.
rho1 = toEisen $ beta' * rho1'
b1sqrt3' = round $ b1 / sqrt3
gamma1 = ((round a1) + b1sqrt3') :+ (2 * b1sqrt3')
rho2 = toEisen $ beta' * rho2'
b2sqrt3' = round $ b2 / sqrt3
gamma2 = ((round a2) + b2sqrt3') :+ (1 + 2 * b2sqrt3')
rho1 = toEisen $ beta' * rho1'
b1sqrt3' = round $ b1 / sqrt3
gamma1 = ((round a1) + b1sqrt3') :+ (2 * b1sqrt3')
rho2 = toEisen $ beta' * rho2'
b2sqrt3' = round $ b2 / sqrt3
gamma2 = ((round a2) + b2sqrt3') :+ (1 + 2 * b2sqrt3')


-- | Eisenstein integer division, truncating toward negative infinity.
Expand Down
5 changes: 5 additions & 0 deletions test-suite/Math/NumberTheory/EisensteinIntegersTests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,14 @@ absProperty z = isOrigin || (inFirstSextant && isAssociate)
inFirstSextant = x' > y' && y' >= 0
isAssociate = z' `elem` map (\e -> z * (1 E.:+ 1) ^ e) [0 .. 5]

-- | Verify that `divModE` produces the right quotient and remainder.
divModProperty1 :: E.EisensteinInteger -> E.EisensteinInteger -> Bool
divModProperty1 x y = (y == 0) || (x `E.divE` y) * y + (x `E.modE` y) == x

testSuite :: TestTree
testSuite = testGroup "EisensteinIntegers" $
[ testSmallAndQuick "forall z . z == signum z * abs z" signumAbsProperty
, testSmallAndQuick "abs z always returns an @EisensteinInteger@ in the\
\ first sextant of the complex plane" absProperty
, testSmallAndQuick "divModE works properly" divModProperty1
]

0 comments on commit 76d2415

Please sign in to comment.