Files
haskell-math/test/GF2test.hs
T

77 lines
2.6 KiB
Haskell

module GF2test (run) where
import Data.Bits (xor)
import Data.List (foldl')
import Test.HUnit
import LinearAlgebra.GF2
( fromBools
, gaussianEliminationAllMasks
, maskToIndicesInt
)
-- XOR of the rows selected by a mask
xorSelected :: [Integer] -> [Int] -> Integer
xorSelected rows idxs = foldl' xor 0 [ rows !! i | i <- idxs ]
run :: IO ()
run = do
putStrLn "GF2 Gaussian elimination test"
-- one dependency: rows 0, 1 and 3 XOR to zero
let rowsBits =
map fromBools
[ [True, False, True]
, [False, True, True]
, [True, True, True]
, [True, True, False]
]
masks = gaussianEliminationAllMasks rowsBits
assertEqual "expected exactly one dependency" 1 (length masks)
assertEqual "expected rows 0,1,3" [[0,1,3]] (map maskToIndicesInt masks)
-- no dependency case: the three rows are independent
let rowsBits2 =
map fromBools
[ [True, False, True]
, [False, True, True]
, [True, True, True]
]
assertEqual "Expected no dependency" [] (gaussianEliminationAllMasks rowsBits2)
-- several dependencies: 5 rows of rank 2 give a null space of dimension 3
let rowsBits3 =
map fromBools
[ [True, False, True] -- a
, [False, True, True] -- b
, [True, True, False] -- a xor b
, [True, False, True] -- a again
, [False, False, False] -- zero row
]
masks3 = gaussianEliminationAllMasks rowsBits3
idxs3 = map maskToIndicesInt masks3
assertEqual "expected rows - rank = 3 dependencies" 3 (length masks3)
assertBool "every dependency must XOR to zero"
(all (\ix -> xorSelected rowsBits3 ix == 0) idxs3)
assertBool "no dependency may be empty" (all (not . null) idxs3)
assertBool "the zero row (index 4) must be a dependency on its own" ([4] `elem` idxs3)
-- the dependencies must be linearly independent (distinct and non-zero masks)
assertEqual "dependencies must be pairwise distinct" (length masks3) (length (dedup masks3))
-- a repeated row is a dependency of size two
let rowsBits4 = map fromBools [ [True, False], [False, True], [True, False] ]
assertEqual "duplicate row dependency" [[0,2]]
(map maskToIndicesInt (gaussianEliminationAllMasks rowsBits4))
-- empty input
assertEqual "no rows, no dependency" [] (gaussianEliminationAllMasks [])
putStrLn "GF2 test done."
where
dedup [] = []
dedup (x : xs) = x : dedup (filter (/= x) xs)