{- | 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
     it under the terms of the GNU General Public License as published by
     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]