module Math.Polynomial.Hermite where import Math.Polynomial import Data.VectorSpace probHermite :: [Poly Integer] probHermite = one : [ multPoly x h_n ^-^ polyDeriv h_n | h_n <- probHermite ] physHermite :: [Poly Integer] physHermite = one : [ scalePoly 2 (multPoly x h_n) ^-^ polyDeriv h_n | h_n <- physHermite ] evalProbHermite :: (Integral a, Num b) => a -> b -> b evalProbHermite n = fst . evalProbHermiteDeriv n evalProbHermiteDeriv :: (Integral a, Num b) => a -> b -> (b, b) evalProbHermiteDeriv 0 _ = (1, 0) evalProbHermiteDeriv 1 x = (x, 1) evalProbHermiteDeriv n x | n < 0 = error "evalProbHermite: n < 0" | otherwise = loop 1 x 1 where loop k h_k h_km1 | k == n = (h_k, k' * h_km1) | otherwise = loop (k+1) (x * h_k - k' * h_km1) h_k where k' = fromIntegral k evalPhysHermite :: (Integral a, Num b) => a -> b -> b evalPhysHermite n = fst . evalPhysHermiteDeriv n evalPhysHermiteDeriv :: (Integral a, Num b) => a -> b -> (b,b) evalPhysHermiteDeriv 0 _ = (1, 0) evalPhysHermiteDeriv 1 x = (2*x, 2) evalPhysHermiteDeriv n x | n < 0 = error "evalProbHermite: n < 0" | otherwise = loop 1 (2*x) 1 where loop k h_k h_km1 | k == n = (h_k, 2 * k' * h_km1) | otherwise = loop (k+1) (2 * (x * h_k - k' * h_km1)) h_k where k' = fromIntegral k