packages feed

ad 4.2 → 4.2.0.1

raw patch · 3 files changed

+105/−11 lines, 3 filesdep ~base

Dependency ranges changed: base

Files

ad.cabal view
@@ -1,5 +1,5 @@ name:         ad-version:      4.2+version:      4.2.0.1 license:      BSD3 license-File: LICENSE copyright:    (c) Edward Kmett 2010-2014,@@ -142,10 +142,11 @@     Numeric.AD.Newton     Numeric.AD.Rank1.Forward     Numeric.AD.Rank1.Forward.Double-    Numeric.AD.Rank1.Sparse-    Numeric.AD.Rank1.Tower+    Numeric.AD.Rank1.Halley     Numeric.AD.Rank1.Kahn     Numeric.AD.Rank1.Newton+    Numeric.AD.Rank1.Sparse+    Numeric.AD.Rank1.Tower    other-modules:     Numeric.AD.Internal.Combinators
bench/BlackScholes.hs view
@@ -3,6 +3,7 @@ import Data.Number.Erf import qualified Numeric.AD as Mixed import qualified Numeric.AD.Mode.Forward as Forward+import qualified Numeric.AD.Mode.Forward.Double as ForwardDouble import qualified Numeric.AD.Mode.Kahn as Kahn import qualified Numeric.AD.Mode.Reverse as Reverse import qualified Numeric.AD.Mode.Sparse as Sparse@@ -39,6 +40,9 @@         [ bench "greeks Double" $ nf (runDouble $ \r s v t k -> Forward.jacobian (fromPair . bs) [r, s, v, t, k]) 2         , bench "greeks Float" $ nf (runFloat $ \r s v t k -> Forward.jacobian (fromPair . bs) [r, s, v, t, k]) 2         ]+    , bgroup "ForwardDouble"+        [ bench "greeks Double" $ nf (runDouble $ \r s v t k -> ForwardDouble.jacobian (fromPair . bs) [r, s, v, t, k]) 2+        ]     , bgroup "Kahn"         [ bench "greeks Double" $ nf (runDouble $ \r s v t k -> Kahn.jacobian (fromPair . bs) [r, s, v, t, k]) 2         , bench "higherGreeks Double" $ nf (runDouble $ \r s v t k -> (Kahn.hessian (fst . bs) [r, s, v, t, k], Kahn.hessian (snd . bs) [r, s, v, t, k])) 2@@ -63,12 +67,12 @@         , bench "higherGreeks Float" $ nf (runFloat $ \r s v t k -> (Sparse.hessian (fst . bs) [r, s, v, t, k], Sparse.hessian (snd . bs) [r, s, v, t, k])) 2         , bench "highererGreeks Float" $ nf (runFloat $ \r s v t k -> Sparse.hessianF (fromPair . bs) [r, s, v, t, k]) 2         ]---    , bgroup "Mixed"---        [ bench "greeks Double" $ nf (runDouble $ \r s v t k -> Mixed.jacobian (fromPair . bs) [r, s, v, t, k]) 2---        , bench "higherGreeks Double" $ nf (runDouble $ \r s v t k -> (Mixed.hessian (fst . bs) [r, s, v, t, k], Mixed.hessian (snd . bs) [r, s, v, t, k])) 2---        , bench "highererGreeks Double" $ nf (runDouble $ \r s v t k -> Mixed.hessianF (fromPair . bs) [r, s, v, t, k]) 2---        , bench "greeks Float" $ nf (runFloat $ \r s v t k -> Mixed.jacobian (fromPair . bs) [r, s, v, t, k]) 2---        , bench "higherGreeks Float" $ nf (runFloat $ \r s v t k -> (Mixed.hessian (fst . bs) [r, s, v, t, k], Mixed.hessian (snd . bs) [r, s, v, t, k])) 2---        , bench "highererGreeks Float" $ nf (runFloat $ \r s v t k -> Mixed.hessianF (fromPair . bs) [r, s, v, t, k]) 2---        ]+   , bgroup "Mixed"+       [ bench "greeks Double" $ nf (runDouble $ \r s v t k -> Mixed.jacobian (fromPair . bs) [r, s, v, t, k]) 2+       , bench "higherGreeks Double" $ nf (runDouble $ \r s v t k -> (Mixed.hessian (fst . bs) [r, s, v, t, k], Mixed.hessian (snd . bs) [r, s, v, t, k])) 2+       , bench "highererGreeks Double" $ nf (runDouble $ \r s v t k -> Mixed.hessianF (fromPair . bs) [r, s, v, t, k]) 2+       , bench "greeks Float" $ nf (runFloat $ \r s v t k -> Mixed.jacobian (fromPair . bs) [r, s, v, t, k]) 2+       , bench "higherGreeks Float" $ nf (runFloat $ \r s v t k -> (Mixed.hessian (fst . bs) [r, s, v, t, k], Mixed.hessian (snd . bs) [r, s, v, t, k])) 2+       , bench "highererGreeks Float" $ nf (runFloat $ \r s v t k -> Mixed.hessianF (fromPair . bs) [r, s, v, t, k]) 2+       ]     ]
+ src/Numeric/AD/Rank1/Halley.hs view
@@ -0,0 +1,89 @@+-----------------------------------------------------------------------------+-- |+-- Copyright   :  (c) Edward Kmett 2010-2014+-- License     :  BSD3+-- Maintainer  :  ekmett@gmail.com+-- Stability   :  experimental+-- Portability :  GHC only+--+-- Root finding using Halley's rational method (the second in+-- the class of Householder methods). Assumes the function is three+-- times continuously differentiable and converges cubically when+-- progress can be made.+--+-----------------------------------------------------------------------------++module Numeric.AD.Rank1.Halley+  (+  -- * Halley's Method (Tower AD)+    findZero+  , inverse+  , fixedPoint+  , extremum+  ) where++import Prelude hiding (all)+import Numeric.AD.Internal.Forward (Forward)+import Numeric.AD.Internal.On+import Numeric.AD.Internal.Tower (Tower)+import Numeric.AD.Mode+import Numeric.AD.Rank1.Tower (diffs0)+import Numeric.AD.Rank1.Forward (diff)++-- $setup+-- >>> import Data.Complex++-- | The 'findZero' function finds a zero of a scalar function using+-- Halley's method; its output is a stream of increasingly accurate+-- results.  (Modulo the usual caveats.) If the stream becomes constant+-- ("it converges"), no further elements are returned.+--+-- Examples:+--+-- >>> take 10 $ findZero (\x->x^2-4) 1+-- [1.0,1.8571428571428572,1.9997967892704736,1.9999999999994755,2.0]+--+-- >>> last $ take 10 $ findZero ((+1).(^2)) (1 :+ 1)+-- 0.0 :+ 1.0+findZero :: (Fractional a, Eq a) => (Tower a -> Tower a) -> a -> [a]+findZero f = go where+  go x = x : if x == xn then [] else go xn where+    (y:y':y'':_) = diffs0 f x+    xn = x - 2*y*y'/(2*y'*y'-y*y'')+{-# INLINE findZero #-}++-- | The 'inverse' function inverts a scalar function using+-- Halley's method; its output is a stream of increasingly accurate+-- results.  (Modulo the usual caveats.) If the stream becomes constant+-- ("it converges"), no further elements are returned.+--+-- Note: the @take 10 $ inverse sqrt 1 (sqrt 10)@ example that works for Newton's method+-- fails with Halley's method because the preconditions do not hold!+inverse :: (Fractional a, Eq a) => (Tower a -> Tower a) -> a -> a -> [a]+inverse f x0 y = findZero (\x -> f x - auto y) x0+{-# INLINE inverse  #-}++-- | The 'fixedPoint' function find a fixedpoint of a scalar+-- function using Halley's method; its output is a stream of+-- increasingly accurate results.  (Modulo the usual caveats.)+--+-- If the stream becomes constant ("it converges"), no further+-- elements are returned.+--+-- >>> last $ take 10 $ fixedPoint cos 1+-- 0.7390851332151607+fixedPoint :: (Fractional a, Eq a) => (Tower a -> Tower a) -> a -> [a]+fixedPoint f = findZero (\x -> f x - x)+{-# INLINE fixedPoint #-}+++-- | The 'extremum' function finds an extremum of a scalar+-- function using Halley's method; produces a stream of increasingly+-- accurate results.  (Modulo the usual caveats.) If the stream becomes+-- constant ("it converges"), no further elements are returned.+--+-- >>> take 10 $ extremum cos 1+-- [1.0,0.29616942658570555,4.59979519460002e-3,1.6220740159042513e-8,0.0]+extremum :: (Fractional a, Eq a) => (On (Forward (Tower a)) -> On (Forward (Tower a))) -> a -> [a]+extremum f = findZero (diff (off . f . On))+{-# INLINE extremum #-}