module Data.ANN.BAM (BAM ,makeBAM ,recallForward ,recallBackward ) where import Data.List -- Discrete Bidirectional Associative Memory -- Stores associations between pairs of vectors -- Quick and dirty version using lists. Would be nice to do this using a vector space library type Vector a = [a] type Matrix a = [Vector a] vecPlus = zipWith (+) matPlus = zipWith vecPlus matZero = repeat (repeat 0) matProd xs ys = [ [sum $ zipWith (*) x y | y<-transpose ys] | x<-xs] outerProd xs ys = [ [x*y | y<-ys] | x<-xs] boolToInt b = if b then 1 else -1 intToBool i | i >= 0 = True | otherwise = False sign i | i >= 0 = 1 | otherwise = -1 data BAM = BAM (Matrix Int) deriving (Eq,Ord,Show) makeBAM :: [(Vector Bool, Vector Bool)] -> BAM makeBAM assocs = BAM $ foldl matPlus matZero [ (map boolToInt x) `outerProd` (map boolToInt y) | (x,y) <- assocs] runBackward (BAM ws) y = [sign $ sum $ zipWith (*) w y | w<-ws] runForward (BAM ws) x = [sign $ sum $ zipWith (*) x w | w<-transpose ws] recallForward bam x = map intToBool $ untilStable (runForward bam . runBackward bam) $ map boolToInt x recallBackward bam x = map intToBool $ untilStable (runBackward bam . runForward bam) $ map boolToInt x untilStable f x = let x' = f x in if x==x' then x else untilStable f x'