{- | Gaussian Process Library. This module contains the definition
of the standard squared exponential covariance function.

Copyright (C) 2008-11 Sean Holden. sbh11\@cl.cam.ac.uk.
-}
{-   HasGP is free software: you can redistribute it and/or modify
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

HasGP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with HasGP.  If not, see <http://www.gnu.org/licenses/>.
-}
module HasGP.Covariance.SquaredExp
(
SquaredExponential(..)
) where

import Numeric.LinearAlgebra

import HasGP.Types.MainTypes
import HasGP.Covariance.Basic

data SquaredExponential = SquaredExponential
{
f :: Double,         -- ^ log \sigma_f^2
l :: Double          -- ^ log l
}

instance CovarianceFunction SquaredExponential where

trueHyper se = mapVector exp \$ fromList [(f se), (l se)]

covariance se in1 in2 =
f2 * exp (-(1/(2 * (l2^2))) * (diff <.> diff))
where
diff = in1 - in2
f2 = exp (f se)
l2 = exp (l se)

dCovarianceDParameters se in1 in2 =
fromList [dLogByDF, dLogByDL]
where
diff = in1 - in2
d = diff <.> diff
f2 = exp (f se)
l2 = exp (l se)
dLogByDF = exp (-(1/(2 * (l2^2))) * d)
dLogByDL = f2 * dLogByDF * (d * (l2^^(-3)))

makeCovarianceFromList se [f, l] = SquaredExponential f l
makeCovarianceFromList se _ =
error "SquaredExp requires exactly 2 hyperparameters"

makeListFromCovariance se = [f se, l se]