{-# LANGUAGE NoImplicitPrelude #-}
module MathObj.PowerSeries.Example where
import qualified MathObj.PowerSeries.Core as PS
import qualified Algebra.Field as Field
import qualified Algebra.Ring as Ring
import qualified Algebra.ZeroTestable as ZeroTestable
import qualified Algebra.Transcendental as Transcendental
import Algebra.Additive (zero, subtract, negate)
import Data.List (intersperse, )
import Data.List.HT (sieve, )
import NumericPrelude.Numeric (one, (*), (/),
fromInteger, pi)
import NumericPrelude.Base
recip :: (Ring.C a) => [a]
recip = recipExpl
exp, sin, cos,
log, asin, atan, sqrt :: (Field.C a) => [a]
acos :: (Transcendental.C a) => [a]
tan :: (ZeroTestable.C a, Field.C a) => [a]
exp = expODE
sin = sinODE
cos = cosODE
tan = tanExplSieve
log = logODE
asin = asinODE
acos = acosODE
atan = atanODE
sinh, cosh, atanh :: (Field.C a) => [a]
sinh = sinhODE
cosh = coshODE
atanh = atanhODE
pow :: (Field.C a) => a -> [a]
pow = powExpl
sqrt = sqrtExpl
recipExpl :: (Ring.C a) => [a]
recipExpl = cycle [1,-1]
expExpl, sinExpl, cosExpl :: (Field.C a) => [a]
expExpl = scanl (*) one PS.recipProgression
sinExpl = zero : PS.holes2alternate (tail expExpl)
cosExpl = PS.holes2alternate expExpl
tanExpl, tanExplSieve :: (ZeroTestable.C a, Field.C a) => [a]
tanExpl = PS.divide sinExpl cosExpl
tanExplSieve =
concatMap
(\x -> [zero,x])
(PS.divide (sieve 2 (tail sin)) (sieve 2 cos))
logExpl, atanExpl, sqrtExpl :: (Field.C a) => [a]
logExpl = zero : PS.alternate PS.recipProgression
atanExpl = zero : PS.holes2alternate PS.recipProgression
sinhExpl, coshExpl, atanhExpl :: (Field.C a) => [a]
sinhExpl = zero : PS.holes2 (tail expExpl)
coshExpl = PS.holes2 expExpl
atanhExpl = zero : PS.holes2 PS.recipProgression
powExpl :: (Field.C a) => a -> [a]
powExpl expon =
scanl (*) 1 (zipWith (/)
(iterate (subtract 1) expon) PS.progression)
sqrtExpl = powExpl (1/2)
erf :: (Field.C a) => [a]
erf = PS.integrate 0 $ intersperse 0 $ PS.alternate exp
expODE, sinODE, cosODE, tanODE, tanODESieve :: (Field.C a) => [a]
expODE = PS.integrate 1 expODE
sinODE = PS.integrate 0 cosODE
cosODE = PS.integrate 1 (PS.negate sinODE)
tanODE = PS.integrate 0 (PS.add [1] (PS.mul tanODE tanODE))
tanODESieve =
let tan2 = map head (iterate (drop 2) (tail tanODESieve))
in PS.integrate 0 (intersperse zero (1 : PS.mul tan2 tan2))
logODE, recipCircle, asinODE, atanODE, sqrtODE :: (Field.C a) => [a]
logODE = PS.integrate zero recip
recipCircle = intersperse zero (PS.alternate (powODE (-1/2)))
asinODE = PS.integrate 0 recipCircle
atanODE = PS.integrate zero (cycle [1,0,-1,0])
sqrtODE = powODE (1/2)
acosODE :: (Transcendental.C a) => [a]
acosODE = PS.integrate (pi/2) recipCircle
sinhODE, coshODE, atanhODE :: (Field.C a) => [a]
sinhODE = PS.integrate 0 coshODE
coshODE = PS.integrate 1 sinhODE
atanhODE = PS.integrate zero (cycle [1,0])
powODE :: (Field.C a) => a -> [a]
powODE expon =
let y = PS.integrate 1 y'
y' = PS.scale expon (scanl1 subtract y)
in y