module MathObj.Gaussian.Polynomial where
import qualified MathObj.Gaussian.Bell as Bell
import qualified MathObj.Polynomial as Poly
import qualified Number.Complex as Complex
import qualified Algebra.Differential as Differential
import qualified Algebra.Transcendental as Trans
import qualified Algebra.Field as Field
import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive
import Algebra.Transcendental (pi, )
import Algebra.Ring ((*), )
import NumericPrelude
import PreludeBase hiding (reverse, )
data T a = Cons {bell :: Bell.T a, polynomial :: Poly.T (Complex.T a)}
deriving (Eq, Show)
evaluate :: (Trans.C a) =>
T a -> a -> Complex.T a
evaluate f x =
Bell.evaluateSqRt (bell f) x *
Poly.evaluate (polynomial f) (Complex.fromReal $ sqrt pi * x)
multiply :: (Ring.C a) =>
T a -> T a -> T a
multiply x y =
Cons
(Bell.multiply (bell x) (bell y))
(polynomial x * polynomial y)
convolve :: (Field.C a) =>
T a -> T a -> T a
convolve f g =
reverse $ fourier $ multiply (fourier f) (fourier g)
reverse :: Additive.C a => T a -> T a
reverse x =
Cons
(Bell.reverse $ bell x)
(Poly.reverse $ polynomial x)
fourier :: (Field.C a) =>
T a -> T a
fourier x =
foldr
(\c p ->
let q = differentiate p
in q{polynomial =
Poly.const c +
fmap Complex.quarterLeft (polynomial q)})
(Cons (Bell.fourier $ bell x) zero) $
Poly.coeffs $ polynomial x
differentiate :: (Ring.C a) => T a -> T a
differentiate f =
f{polynomial =
Bell.exponentPolynomial (bell f) * polynomial f +
Differential.differentiate (polynomial f)}