GNFS implementation + GF2 gaussian elimination fix
This commit is contained in:
1 parent
da4662ac1c
commit
529d887486
14 files changed
+980
-87
No files matched your search
+57
-24
@@ -1,43 +1,76 @@
|
||||
module GF2test (run) where
|
||||
|
||||
import Data.Bits (xor)
|
||||
import Data.List (foldl')
|
||||
import Test.HUnit
|
||||
|
||||
import LinearAlgebra.GF2
|
||||
( fromBools
|
||||
, gaussianEliminationIndices
|
||||
, 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"
|
||||
|
||||
let rowsBools =
|
||||
[ [True, False, True]
|
||||
, [False, True, True]
|
||||
, [True, True, True]
|
||||
, [True, True, False]
|
||||
]
|
||||
-- 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
|
||||
|
||||
nCols = length (head rowsBools)
|
||||
rowsBits = map fromBools rowsBools
|
||||
maybeIndices = gaussianEliminationIndices nCols rowsBits
|
||||
assertEqual "expected exactly one dependency" 1 (length masks)
|
||||
assertEqual "expected rows 0,1,3" [[0,1,3]] (map maskToIndicesInt masks)
|
||||
|
||||
case maybeIndices of
|
||||
Nothing -> assertFailure "expected rows 0,1,3"
|
||||
Just rows -> assertEqual "expected rows 0,1,3" rows [0,1,3]
|
||||
-- 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)
|
||||
|
||||
-- no depency case
|
||||
let rowsBools2 =
|
||||
[ [True, False, True]
|
||||
, [False, True, True]
|
||||
, [True, True, True]
|
||||
]
|
||||
nCols2 = length (head rowsBools2)
|
||||
rowsBits2 = map fromBools rowsBools2
|
||||
maybeIndices2 = gaussianEliminationIndices nCols2 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 no dependency" Nothing maybeIndices2
|
||||
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)
|
||||
Reference in new issue
Block a user