module Math.LinearRecursive.Internal.Polynomial ( Polynomial , polynomial , unPoly , fromList , toList , singleton , x , degree , evalPoly ) where import qualified Data.IntMap as IntMap import Math.LinearRecursive.Internal.Vector newtype Polynomial a = Polynomial { unPoly :: Vector a } polynomial :: Num a => Vector a -> Polynomial a polynomial = Polynomial toList :: (Eq a, Num a) => Polynomial a -> [(Int, a)] toList (Polynomial a) = IntMap.assocs (unVector a) fromList :: (Eq a, Num a) => [(Int, a)] -> Polynomial a fromList lst = polynomial (vector (IntMap.fromListWith (+) lst)) singleton :: (Eq a, Num a) => a -> Polynomial a singleton v = polynomial (vector (IntMap.singleton 0 v)) x :: (Eq a, Num a) => Polynomial a x = polynomial (vector (IntMap.singleton 1 1)) degree :: (Eq a, Num a) => Polynomial a -> Int degree p = maximum $ (-1) : map fst (toList p) evalPoly :: (Eq a, Num a) => Polynomial a -> a -> a evalPoly p v = sum [ci * v ^ i | (i, ci) <- toList p] instance (Show a, Eq a, Num a) => Show (Polynomial a) where show a = "Polynomial " ++ show (toList a) instance Eq a => Eq (Polynomial a) where Polynomial a == Polynomial b = a == b instance (Eq a, Num a) => Num (Polynomial a) where Polynomial a + Polynomial b = polynomial (a <+> b) Polynomial a - Polynomial b = polynomial (a <-> b) negate (Polynomial a) = polynomial (vmap negate a) a * b = fromList [(i + j, ai * bj) | (i, ai) <- toList a , (j, bj) <- toList b] abs = error "Polynomial : absolute value undefined" signum = error "Polynomial : signum undefined" fromInteger = singleton . fromInteger