-- | Hermit polynomials
--
-- See <https://en.wikipedia.org/wiki/Hermite_polynomials>
-- 

{-# LANGUAGE DataKinds, TypeSynonymInstances, FlexibleContexts, FlexibleInstances, BangPatterns, ScopedTypeVariables #-}
module Math.Algebra.Polynomial.Univariate.Hermite
  ( hermiteH
  , hermiteHe
  , integralHermiteH
  , integralHermiteHe
  ) 
  where

--------------------------------------------------------------------------------

import Data.List
import Data.Ratio

import Data.Semigroup
import Data.Monoid

import GHC.TypeLits

import qualified Math.Algebra.Polynomial.FreeModule as ZMod
import Math.Algebra.Polynomial.FreeModule ( FreeMod , FreeModule(..) , ZMod , QMod )

import Math.Algebra.Polynomial.Univariate

import Math.Algebra.Polynomial.Class
import Math.Algebra.Polynomial.Pretty
import Math.Algebra.Polynomial.Misc

--------------------------------------------------------------------------------

-- | Probabilists\' Hermite polynomials
hermiteHe :: (Ring c, KnownSymbol v) => Int -> Univariate c v
hermiteHe :: Int -> Univariate c v
hermiteHe = Univariate Integer v -> Univariate c v
forall c (v :: Symbol).
(Ring c, KnownSymbol v) =>
Univariate Integer v -> Univariate c v
fromZUni (Univariate Integer v -> Univariate c v)
-> (Int -> Univariate Integer v) -> Int -> Univariate c v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Univariate Integer "x" -> Univariate Integer v
forall c (var1 :: Symbol) (var2 :: Symbol).
Univariate c var1 -> Univariate c var2
renameUniVar (Univariate Integer "x" -> Univariate Integer v)
-> (Int -> Univariate Integer "x") -> Int -> Univariate Integer v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Univariate Integer "x"
integralHermiteHe

-- | Physicists\' Hermite polynomials
hermiteH :: (Ring c, KnownSymbol v) => Int -> Univariate c v
hermiteH :: Int -> Univariate c v
hermiteH = Univariate Integer v -> Univariate c v
forall c (v :: Symbol).
(Ring c, KnownSymbol v) =>
Univariate Integer v -> Univariate c v
fromZUni (Univariate Integer v -> Univariate c v)
-> (Int -> Univariate Integer v) -> Int -> Univariate c v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Univariate Integer "x" -> Univariate Integer v
forall c (var1 :: Symbol) (var2 :: Symbol).
Univariate c var1 -> Univariate c var2
renameUniVar (Univariate Integer "x" -> Univariate Integer v)
-> (Int -> Univariate Integer "x") -> Int -> Univariate Integer v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Univariate Integer "x"
integralHermiteH

--------------------------------------------------------------------------------

x, twox :: Univariate Integer "x"
x :: Univariate Integer "x"
x    = VarP (Univariate Integer "x") -> Univariate Integer "x"
forall p. AlmostPolynomial p => VarP p -> p
variableP ()
twox :: Univariate Integer "x"
twox = MonomP (Univariate Integer "x")
-> CoeffP (Univariate Integer "x") -> Univariate Integer "x"
forall p. AlmostPolynomial p => MonomP p -> CoeffP p -> p
monomP'   (Int -> U "x"
forall (var :: Symbol). Int -> U var
U Int
1) CoeffP (Univariate Integer "x")
2

-- | Probabilists\' Hermite polynomials
integralHermiteHe :: Int -> Univariate Integer "x"
integralHermiteHe :: Int -> Univariate Integer "x"
integralHermiteHe = ((Int -> Univariate Integer "x") -> Int -> Univariate Integer "x")
-> Int -> Univariate Integer "x"
forall a. ((Int -> a) -> Int -> a) -> Int -> a
intCache (Int -> Univariate Integer "x") -> Int -> Univariate Integer "x"
forall a.
(Eq a, Num a) =>
(a -> Univariate Integer "x") -> a -> Univariate Integer "x"
compute where
  compute :: (a -> Univariate Integer "x") -> a -> Univariate Integer "x"
compute a -> Univariate Integer "x"
recur a
n = case a
n of 
    a
0 -> Univariate Integer "x"
1
    a
1 -> Univariate Integer "x"
x
    a
n -> Univariate Integer "x"
x Univariate Integer "x"
-> Univariate Integer "x" -> Univariate Integer "x"
forall a. Num a => a -> a -> a
* a -> Univariate Integer "x"
recur (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1) Univariate Integer "x"
-> Univariate Integer "x" -> Univariate Integer "x"
forall a. Num a => a -> a -> a
- Univariate Integer "x" -> Univariate Integer "x"
forall c (var :: Symbol).
(Ring c, KnownSymbol var) =>
Univariate c var -> Univariate c var
differentiateUni (a -> Univariate Integer "x"
recur (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1))

-- | Physicists\' Hermite polynomials
integralHermiteH :: Int -> Univariate Integer "x"
integralHermiteH :: Int -> Univariate Integer "x"
integralHermiteH = ((Int -> Univariate Integer "x") -> Int -> Univariate Integer "x")
-> Int -> Univariate Integer "x"
forall a. ((Int -> a) -> Int -> a) -> Int -> a
intCache (Int -> Univariate Integer "x") -> Int -> Univariate Integer "x"
forall a.
(Eq a, Num a) =>
(a -> Univariate Integer "x") -> a -> Univariate Integer "x"
compute where
  compute :: (a -> Univariate Integer "x") -> a -> Univariate Integer "x"
compute a -> Univariate Integer "x"
recur a
n = case a
n of 
    a
0 -> Univariate Integer "x"
1
    a
1 -> Univariate Integer "x"
twox
    a
n -> Univariate Integer "x"
twox Univariate Integer "x"
-> Univariate Integer "x" -> Univariate Integer "x"
forall a. Num a => a -> a -> a
* a -> Univariate Integer "x"
recur (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1) Univariate Integer "x"
-> Univariate Integer "x" -> Univariate Integer "x"
forall a. Num a => a -> a -> a
- Univariate Integer "x" -> Univariate Integer "x"
forall c (var :: Symbol).
(Ring c, KnownSymbol var) =>
Univariate c var -> Univariate c var
differentiateUni (a -> Univariate Integer "x"
recur (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1))

--------------------------------------------------------------------------------