hopfield-0.1.0.0: src/Hopfield/Experiments/Experiment.hs
{-# LANGUAGE ParallelListComp #-}
module Hopfield.Experiments.Experiment where
import Control.Monad (replicateM)
import Control.Monad.Random
import Test.QuickCheck
import Test.QuickCheck.Gen (unGen)
import Hopfield.Clusters
import Hopfield.Common
import Hopfield.Experiments.ExperimentUtil
import Hopfield.Hopfield
import Hopfield.Measurement
import Hopfield.SuperAttractors
import Hopfield.TestUtil (Type(H), patternGen)
import Hopfield.Util
genIO :: Gen a -> IO a
genIO g = do
rndInt <- randomIO
stdGen <- getStdGen
return $ unGen g stdGen rndInt
errorHeader :: String
errorHeader = "Degree\tExpected error"
basinHeader :: String
basinHeader = "Degree\tBasin size"
main :: IO ()
main = do
let n = 100 -- number of neurons
numRandoms = 8 -- number of random patterns to include
maxDegree = 32 -- maximum degree of super attractor
-- The super attractor - primary care giver
originPat <- genIO $ patternGen H n
-- Sample random patterns with Hamming distance between 25-75% from origin
-- This is to ensure that this is a pure super attractor experiment
-- and not a cluster one!
let minHamming = round $ n .* (0.25 :: Double)
maxHamming = round $ n .* (0.75 :: Double)
dist = hammingDistribution n (minHamming, maxHamming)
randomPats <- replicateM numRandoms $ sampleHammingRange originPat dist
let pats = originPat:randomPats
p = length pats
originIndex = 0 -- index of main pattern
degrees = powersOfTwo maxDegree
patCombiner = oneSuperAttr
putStrLn $ unwords [show n, "neurons.", "Super attractor plus", show numRandoms, "random patterns.\n"]
-- Compute probability of error
doErrorProb n p degrees
-- Compute hamming distance
doHamming originPat randomPats "origin" "random"
putStrLn "Building networks..."
let nets = buildNetworks pats degrees Hebbian patCombiner
--Check if pattern is fixed.
doCheckFixed (zip degrees nets) originIndex "degrees"
putStrLn "Measuring basins of attraction"
let results = measureMultiBasins measurePatternBasin nets originPat
putStrLn basinHeader
printMList results [ \r -> attachLabel [pack d, pack r] | d <- degrees ]
-- putStrLn "T1 experiment with 1 cluster"
-- putStrLn $ show $ evalRand (repeatExperiment experimentUsingT1 Storkey 1 50 8) (mkStdGen 1)
putStrLn "T1 experiment with 1 cluster with no average but lists"
let avgs = replicate 10 $ experimentUsingT1NoAvg Hebbian 100 10
printMList avgs (replicate 10 show)