packages feed

ad-delcont-0.5.0.0: test/Numeric/AD/DelContSpec.hs

{-# options_ghc -Wno-type-defaults -Wno-unused-imports -Wno-missing-methods -Wno-orphans #-}
module Numeric.AD.DelContSpec where

import Numeric.AD.DelCont (grad, rad1)
import qualified Numeric.AD as AD (grad)
import Test.Hspec (Spec, hspec, describe, it, shouldBe, shouldSatisfy)


spec :: Spec
spec = do
  describe "rad1 : Unary functions" $ do
    let
      x0 = 1.2
      x1 = 0.0
    it "(** 2)" $ do
      let
        f x = x ** 2
        (_, dfdx) = rad1 f x0
        (_, dfdx1) = rad1 f x1
      dfdx `shouldBe` 2.4
      dfdx1 `shouldBe` 0.0
    it "sqrt" $ do
      let
        (_, dfdx) = rad1 sqrt x0
        xhat = 1 / (2 * (sqrt x0))
      dfdx `shouldBe` xhat
    it "reciprocal" $ do
      let
        (_, dfdx) = rad1 recip x0
        xhat = negate $ 1 / (x0 **2)
      dfdx `shouldBe` xhat
  describe "grad : Multivariate functions" $ do
    let
      x = [1.2, 1.3]
    it "inverse of the L2 norm" $ do
      let
        f z = 1 / norm z
        (_, gradf) = grad f x -- 'ad-delcont'
        gradAD = AD.grad f x -- 'ad'
      norm (gradf - gradAD) `shouldSatisfy` (<= 1e-12)

instance Num a => Num [a] where
  (-) = zipWith (-)

norm :: Floating a => [a] -> a
norm = sqrt . dot

dot :: Num c => [c] -> c
dot xs = sum $ zipWith (*) xs xs