module Numeric.MaxEnt.Linear where
import Numeric.MaxEnt.ConjugateGradient
import Numeric.Optimization.Algorithms.HagerZhang05
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Storable as S
import Numeric.AD
import GHC.IO (unsafePerformIO)
import Data.Traversable
import Numeric.AD.Types
import Numeric.AD.Internal.Classes
import Data.List (transpose)
import Control.Applicative
probs :: (RealFloat b) => [[b]] -> [b] -> [b]
probs matrix ls = map (pOfK matrix ls) [0..length matrix 1]
pOfK :: RealFloat a => [[a]] -> [a] -> Int -> a
pOfK matrix ls k = exp (dot (transpose matrix !! k) ls) / partitionFunc matrix ls
partitionFunc :: RealFloat a => [[a]] -> [a] -> a
partitionFunc matrix ws = sum $ [ exp (dot as ws) | as <- transpose matrix]
objectiveFunc :: RealFloat a => [[a]] -> [a]-> [a] -> a
objectiveFunc as moments ls = log (partitionFunc as ls) dot ls moments
data LinearConstraints a = LC {
matrix :: [[a]],
output :: [a]
}
deriving (Show, Eq)
linear :: Double
-> (forall a. RealFloat a => LinearConstraints a)
-> Either (Result, Statistics) [Double]
linear tolerance constraints = result where
obj :: RealFloat a => [a] -> a
obj = objectiveFunc (matrix constraints) (output constraints)
as :: [[Double]]
as = matrix constraints
result = probs as <$> solve tolerance (length as) obj
linear1 :: Double -> (forall a. RealFloat a => LinearConstraints a)
-> Either (Result, Statistics) [Double]
linear1 precision constraints = result where
obj :: RealFloat a => [a] -> a
obj = objectiveFunc (matrix constraints) (output constraints)
fs :: [[Double]]
fs = matrix constraints
guess :: RealFloat a => [a]
guess = replicate
(length fs) ((1.0) / (fromIntegral (length fs)))
result = Right . probs fs . last $ conjugateGradientDescent obj guess