{-# LANGUAGE CPP #-}
module Numeric.AD.Rank1.Halley
(
findZero
, findZeroNoEq
, inverse
, inverseNoEq
, fixedPoint
, fixedPointNoEq
, extremum
, extremumNoEq
) 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)
import Numeric.AD.Internal.Combinators (takeWhileDifferent)
findZero :: (Fractional a, Eq a) => (Tower a -> Tower a) -> a -> [a]
findZero :: forall a. (Fractional a, Eq a) => (Tower a -> Tower a) -> a -> [a]
findZero Tower a -> Tower a
f = [a] -> [a]
forall a. Eq a => [a] -> [a]
takeWhileDifferent ([a] -> [a]) -> (a -> [a]) -> a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tower a -> Tower a) -> a -> [a]
forall a. Fractional a => (Tower a -> Tower a) -> a -> [a]
findZeroNoEq Tower a -> Tower a
f
{-# INLINE findZero #-}
findZeroNoEq :: Fractional a => (Tower a -> Tower a) -> a -> [a]
findZeroNoEq :: forall a. Fractional a => (Tower a -> Tower a) -> a -> [a]
findZeroNoEq Tower a -> Tower a
f = (a -> a) -> a -> [a]
forall a. (a -> a) -> a -> [a]
iterate a -> a
go where
go :: a -> a
go a
x = a
xn where
(a
y,a
y',a
y'') = case (Tower a -> Tower a) -> a -> [a]
forall a. Num a => (Tower a -> Tower a) -> a -> [a]
diffs0 Tower a -> Tower a
f a
x of
(a
z:a
z':a
z'':[a]
_) -> (a
z,a
z',a
z'')
[a]
_ -> [Char] -> (a, a, a)
forall a. HasCallStack => [Char] -> a
error [Char]
"findZeroNoEq: Impossible (diffs0 should produce an infinite list)"
xn :: a
xn = a
x a -> a -> a
forall a. Num a => a -> a -> a
- a
2a -> a -> a
forall a. Num a => a -> a -> a
*a
ya -> a -> a
forall a. Num a => a -> a -> a
*a
y'a -> a -> a
forall a. Fractional a => a -> a -> a
/(a
2a -> a -> a
forall a. Num a => a -> a -> a
*a
y'a -> a -> a
forall a. Num a => a -> a -> a
*a
y'a -> a -> a
forall a. Num a => a -> a -> a
-a
ya -> a -> a
forall a. Num a => a -> a -> a
*a
y'')
#ifdef HERBIE
{-# ANN findZeroNoEq "NoHerbie" #-}
#endif
{-# INLINE findZeroNoEq #-}
inverse :: (Fractional a, Eq a) => (Tower a -> Tower a) -> a -> a -> [a]
inverse :: forall a.
(Fractional a, Eq a) =>
(Tower a -> Tower a) -> a -> a -> [a]
inverse Tower a -> Tower a
f a
x0 = [a] -> [a]
forall a. Eq a => [a] -> [a]
takeWhileDifferent ([a] -> [a]) -> (a -> [a]) -> a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tower a -> Tower a) -> a -> a -> [a]
forall a. Fractional a => (Tower a -> Tower a) -> a -> a -> [a]
inverseNoEq Tower a -> Tower a
f a
x0
{-# INLINE inverse #-}
inverseNoEq :: Fractional a => (Tower a -> Tower a) -> a -> a -> [a]
inverseNoEq :: forall a. Fractional a => (Tower a -> Tower a) -> a -> a -> [a]
inverseNoEq Tower a -> Tower a
f a
x0 a
y = (Tower a -> Tower a) -> a -> [a]
forall a. Fractional a => (Tower a -> Tower a) -> a -> [a]
findZeroNoEq (\Tower a
x -> Tower a -> Tower a
f Tower a
x Tower a -> Tower a -> Tower a
forall a. Num a => a -> a -> a
- Scalar (Tower a) -> Tower a
forall t. Mode t => Scalar t -> t
auto a
Scalar (Tower a)
y) a
x0
{-# INLINE inverseNoEq #-}
fixedPoint :: (Fractional a, Eq a) => (Tower a -> Tower a) -> a -> [a]
fixedPoint :: forall a. (Fractional a, Eq a) => (Tower a -> Tower a) -> a -> [a]
fixedPoint Tower a -> Tower a
f = [a] -> [a]
forall a. Eq a => [a] -> [a]
takeWhileDifferent ([a] -> [a]) -> (a -> [a]) -> a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tower a -> Tower a) -> a -> [a]
forall a. Fractional a => (Tower a -> Tower a) -> a -> [a]
fixedPointNoEq Tower a -> Tower a
f
{-# INLINE fixedPoint #-}
fixedPointNoEq :: Fractional a => (Tower a -> Tower a) -> a -> [a]
fixedPointNoEq :: forall a. Fractional a => (Tower a -> Tower a) -> a -> [a]
fixedPointNoEq Tower a -> Tower a
f = (Tower a -> Tower a) -> a -> [a]
forall a. Fractional a => (Tower a -> Tower a) -> a -> [a]
findZeroNoEq (\Tower a
x -> Tower a -> Tower a
f Tower a
x Tower a -> Tower a -> Tower a
forall a. Num a => a -> a -> a
- Tower a
x)
{-# INLINE fixedPointNoEq #-}
extremum :: (Fractional a, Eq a) => (On (Forward (Tower a)) -> On (Forward (Tower a))) -> a -> [a]
extremum :: forall a.
(Fractional a, Eq a) =>
(On (Forward (Tower a)) -> On (Forward (Tower a))) -> a -> [a]
extremum On (Forward (Tower a)) -> On (Forward (Tower a))
f = [a] -> [a]
forall a. Eq a => [a] -> [a]
takeWhileDifferent ([a] -> [a]) -> (a -> [a]) -> a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (On (Forward (Tower a)) -> On (Forward (Tower a))) -> a -> [a]
forall a.
Fractional a =>
(On (Forward (Tower a)) -> On (Forward (Tower a))) -> a -> [a]
extremumNoEq On (Forward (Tower a)) -> On (Forward (Tower a))
f
{-# INLINE extremum #-}
extremumNoEq :: Fractional a => (On (Forward (Tower a)) -> On (Forward (Tower a))) -> a -> [a]
extremumNoEq :: forall a.
Fractional a =>
(On (Forward (Tower a)) -> On (Forward (Tower a))) -> a -> [a]
extremumNoEq On (Forward (Tower a)) -> On (Forward (Tower a))
f = (Tower a -> Tower a) -> a -> [a]
forall a. Fractional a => (Tower a -> Tower a) -> a -> [a]
findZeroNoEq ((Forward (Tower a) -> Forward (Tower a)) -> Tower a -> Tower a
forall a. Num a => (Forward a -> Forward a) -> a -> a
diff (On (Forward (Tower a)) -> Forward (Tower a)
forall t. On t -> t
off (On (Forward (Tower a)) -> Forward (Tower a))
-> (Forward (Tower a) -> On (Forward (Tower a)))
-> Forward (Tower a)
-> Forward (Tower a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. On (Forward (Tower a)) -> On (Forward (Tower a))
f (On (Forward (Tower a)) -> On (Forward (Tower a)))
-> (Forward (Tower a) -> On (Forward (Tower a)))
-> Forward (Tower a)
-> On (Forward (Tower a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Forward (Tower a) -> On (Forward (Tower a))
forall t. t -> On t
On))
{-# INLINE extremumNoEq #-}