module Optimization.LineSearch.BFGS
(
bfgs
, module Optimization.LineSearch
) where
import Linear
import Optimization.LineSearch
import Control.Applicative
import Data.Traversable
import Data.Foldable
bfgs :: ( Metric f, Additive f, Foldable f, Traversable f, Applicative f
, Fractional a, Epsilon a)
=> LineSearch f a
-> (f a -> f a)
-> f (f a)
-> f a
-> [f a]
bfgs search df = go
where go b0 x0 = let p1 = negated $ b0 !* df x0
alpha = search df p1 x0
s = alpha *^ p1
x1 = x0 ^+^ s
y = df x1 ^-^ df x0
sy = s `dot` y
rho = if nearZero sy then 1000 else 1 / sy
i = scaled (pure 1)
u = i !-! rho *!! outer y s
v = i !-! rho *!! outer s y
b1 = u !*! b0 !*! v !+! rho *!! outer s s
in x1 : go b1 x1