{-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} {- | Implementation of Max-product factors for MAP queries -} module Bayes.Factor.MaxCPT( -- * Type MAXCPT , mpeInstantiations ) where import Bayes.Factor import Bayes.Factor.PrivateCPT import Bayes.PrivateTypes import qualified Data.Vector as V import qualified Data.IntMap as IM import Data.List(maximumBy) import Data.Function(on) import Bayes.VariableElimination.Buckets(IsBucketItem(..)) --import Debug.Trace --debug a = trace (show a ++ "\n") a instance FactorElement (Double,PossibleInstantiations) where doubleValue = fst mkValue x = (x,[]) scale s (d,l) = (s*d,l) multiply (da,[]) (db,lb) = (da*db,lb) multiply (da,la) (db,[]) = (da*db,la) multiply (da,la) (db,lb) = (da*db,[xa ++ xb | xa <- la, xb <- lb]) divide _ _ = error "It does not make sense to divide MAXCPT elements" elementSum _ _ = error "It does not make sense to sum MAXCPT elements" instantiationProba :: ((Double,PossibleInstantiations), DVISet) -> Double instantiationProba (a,b) = fst a maximization :: [((Double,PossibleInstantiations), DVISet)] -> (Double,PossibleInstantiations) maximization [] = (1.0, []) maximization l = let ((d,possible),newInst) = maximumBy (compare `on` instantiationProba) l addTo [] l = l addTo i [] = [i] addTo i l = map (i ++) l in (d,addTo newInst possible) instance Factor (MAXCPT) where emptyFactor = _emptyFactor factorVariables = _factorVariables isScalarFactor = _isScalarFactor containsVariable = _containsVariable factorDimension = _factorDimension variablePosition = _variablePosition isUsingSameVariablesAs = _isUsingSameVariablesAs factorFromScalar = _factorFromScalar factorWithVariables = _factorWithVariables factorToList = _factorToList factorNorm = _factorNorm factorScale = _factorScale factorValue = _factorValue factorStringValue f d = show (privateFactorValue f d) evidenceFrom = _evidenceFrom factorProduct = _factorProduct (Op (factorFromScalar 1.0) (1.0,[]) multiply) factorProjectOut _ f@(Scalar v) = f factorProjectOut s f = cptFactorProjectOutWith maximization s f mpeInstantiations :: MAXCPT -> [DVISet] mpeInstantiations (Scalar (_,i)) = i mpeInstantiations _ = error "The final MAXCPT factor should be a scalar one" instance Show MAXCPT where show (Scalar v) = "\nScalar Factor:\n" ++ show v show c@(Table [] _ v) = "\nEmpty MAXCPT:\n" show c = displayFactorBody c instance IsBucketItem MAXCPT where scalarItem = isScalarFactor itemProduct = factorProduct itemProjectOut d = factorProjectOut [d] itemContainsVariable = containsVariable instance MultiDimTable MAXCPT where elementStringValue = factorStringValue tableVariables = factorVariables