module Numeric.AD.Rank1.Tower
( Tower
, auto
, taylor
, taylor0
, maclaurin
, maclaurin0
, diff
, diff'
, diffs
, diffs0
, diffsF
, diffs0F
, du
, du'
, dus
, dus0
, duF
, duF'
, dusF
, dus0F
) where
import Control.Applicative ((<$>))
import Numeric.AD.Internal.Tower
import Numeric.AD.Mode
diffs :: Num a => (Tower a -> Tower a) -> a -> [a]
diffs f a = getADTower $ apply f a
diffs0 :: Num a => (Tower a -> Tower a) -> a -> [a]
diffs0 f a = zeroPad (diffs f a)
diffsF :: (Functor f, Num a) => (Tower a -> f (Tower a)) -> a -> f [a]
diffsF f a = getADTower <$> apply f a
diffs0F :: (Functor f, Num a) => (Tower a -> f (Tower a)) -> a -> f [a]
diffs0F f a = (zeroPad . getADTower) <$> apply f a
taylor :: Fractional a => (Tower a -> Tower a) -> a -> a -> [a]
taylor f x dx = go 1 1 (diffs f x) where
go !n !acc (a:as) = a * acc : go (n + 1) (acc * dx / n) as
go _ _ [] = []
taylor0 :: Fractional a => (Tower a -> Tower a) -> a -> a -> [a]
taylor0 f x dx = zeroPad (taylor f x dx)
maclaurin :: Fractional a => (Tower a -> Tower a) -> a -> [a]
maclaurin f = taylor f 0
maclaurin0 :: Fractional a => (Tower a -> Tower a) -> a -> [a]
maclaurin0 f = taylor0 f 0
diff :: Num a => (Tower a -> Tower a) -> a -> a
diff f = d . diffs f
diff' :: Num a => (Tower a -> Tower a) -> a -> (a, a)
diff' f = d' . diffs f
du :: (Functor f, Num a) => (f (Tower a) -> Tower a) -> f (a, a) -> a
du f = d . getADTower . f . fmap withD
du' :: (Functor f, Num a) => (f (Tower a) -> Tower a) -> f (a, a) -> (a, a)
du' f = d' . getADTower . f . fmap withD
duF :: (Functor f, Functor g, Num a) => (f (Tower a) -> g (Tower a)) -> f (a, a) -> g a
duF f = fmap (d . getADTower) . f . fmap withD
duF' :: (Functor f, Functor g, Num a) => (f (Tower a) -> g (Tower a)) -> f (a, a) -> g (a, a)
duF' f = fmap (d' . getADTower) . f . fmap withD
dus :: (Functor f, Num a) => (f (Tower a) -> Tower a) -> f [a] -> [a]
dus f = getADTower . f . fmap tower
dus0 :: (Functor f, Num a) => (f (Tower a) -> Tower a) -> f [a] -> [a]
dus0 f = zeroPad . getADTower . f . fmap tower
dusF :: (Functor f, Functor g, Num a) => (f (Tower a) -> g (Tower a)) -> f [a] -> g [a]
dusF f = fmap getADTower . f . fmap tower
dus0F :: (Functor f, Functor g, Num a) => (f (Tower a) -> g (Tower a)) -> f [a] -> g [a]
dus0F f = fmap getADTower . f . fmap tower