{- |
Compute Taylor expansions of some standard functions at given points.
The outputs are essentially the derivatives divided by factorials.
-}
module PowerSeries.Taylor where
import qualified PowerSeries as PowerSeries
import qualified Numerics.Differentiation as Diff
import Combinatorics (binomialSeq, binomialSeqGen)
import qualified Prelude
import Prelude hiding (id, recip, exp, log, sin, cos, atan)
type T a = a -> PowerSeries.T a
compose :: Num a => T a -> PowerSeries.T a -> PowerSeries.T a
compose x (y:ys) = PowerSeries.compose (x y) ys
compose x [] = x 0
id :: Fractional a => T a
id x = [x,1]
recip :: Fractional a => T a
recip x = iterate (/ negate x) $ Prelude.recip x
{- |
The exponent must be non-negative.
-}
cardinalPower :: Num a => Integer -> T a
cardinalPower n x =
reverse $
zipWith (*) (map fromInteger $ binomialSeq n) $
iterate (x*) 1
realPower :: Floating a => a -> T a
realPower expon x =
zipWith (*) (binomialSeqGen expon) $
iterate (/x) (x**expon)
exp :: Floating a => T a
exp = PowerSeries.fromDerivatives . Diff.exp
log :: Floating a => T a
log x = PowerSeries.integrate (Prelude.log x) (recip x)
cos :: Floating a => T a
cos = PowerSeries.fromDerivatives . Diff.cos
sin :: Floating a => T a
sin = PowerSeries.fromDerivatives . Diff.sin
tan :: Floating a => T a
tan x = PowerSeries.divide (sin x) (cos x)
recipCircle :: Floating a => T a
recipCircle x =
PowerSeries.divide [1]
(PowerSeries.sqRt [1-x^(2::Int),-2*x,-1])
acos :: Floating a => T a
acos x =
PowerSeries.integrate
(Prelude.acos x)
(PowerSeries.neg $ recipCircle x)
asin :: Floating a => T a
asin x = PowerSeries.integrate (Prelude.asin x) (recipCircle x)
atan :: Floating a => T a
atan x =
PowerSeries.integrate
(Prelude.atan x)
(PowerSeries.divide [1] [1+x^(2::Int),2*x,1])