module Math.Polynomial
( Endianness(..)
, Poly, poly, polyDegree
, polyCoeffs, polyIsZero, polyIsOne
, zero, one, constPoly, x
, scalePoly, negatePoly
, composePoly
, addPoly, sumPolys, multPoly, powPoly
, quotRemPoly, quotPoly, remPoly
, evalPoly, evalPolyDeriv, evalPolyDerivs
, contractPoly
, monicPoly
, gcdPoly, separateRoots
, polyDeriv, polyDerivs, polyIntegral
) where
import Math.Polynomial.Type
import Math.Polynomial.Pretty ()
import Math.Polynomial.VectorSpace (one, x)
import qualified Math.Polynomial.VectorSpace as VS
import Data.VectorSpace.WrappedNum
constPoly :: (Num a, Eq a) => a -> Poly a
constPoly x = unwrapPoly (VS.constPoly (WrapNum x))
scalePoly :: (Num a, Eq a) => a -> Poly a -> Poly a
scalePoly x f = unwrapPoly (VS.scalePoly (WrapNum x) (wrapPoly f))
negatePoly :: (Num a, Eq a) => Poly a -> Poly a
negatePoly f = unwrapPoly (VS.negatePoly (wrapPoly f))
addPoly :: (Num a, Eq a) => Poly a -> Poly a -> Poly a
addPoly p q = unwrapPoly (VS.addPoly (wrapPoly p) (wrapPoly q))
sumPolys :: (Num a, Eq a) => [Poly a] -> Poly a
sumPolys ps = unwrapPoly (VS.sumPolys (map wrapPoly ps))
multPoly :: (Num a, Eq a) => Poly a -> Poly a -> Poly a
multPoly p q = unwrapPoly (VS.multPolyWith (*) (wrapPoly p) (wrapPoly q))
powPoly :: (Num a, Eq a, Integral b) => Poly a -> b -> Poly a
powPoly p n = unwrapPoly (VS.powPolyWith 1 (*) (wrapPoly p) n)
quotRemPoly :: (Fractional a, Eq a) => Poly a -> Poly a -> (Poly a, Poly a)
quotRemPoly u v = (unwrapPoly q, unwrapPoly r)
where
~(q, r) = VS.quotRemPolyWith (*) (/) (wrapPoly u) (wrapPoly v)
quotPoly :: (Fractional a, Eq a) => Poly a -> Poly a -> Poly a
quotPoly u v = unwrapPoly (VS.quotPolyWith (*) (/) (wrapPoly u) (wrapPoly v))
remPoly :: (Fractional a, Eq a) => Poly a -> Poly a -> Poly a
remPoly u v = unwrapPoly (VS.remPolyWith (*) (/) (wrapPoly u) (wrapPoly v))
composePoly :: (Num a, Eq a) => Poly a -> Poly a -> Poly a
composePoly p q = unwrapPoly (VS.composePolyWith (*) (wrapPoly p) (wrapPoly q))
evalPoly :: (Num a, Eq a) => Poly a -> a -> a
evalPoly f x = unwrapNum (VS.evalPoly (wrapPoly f) (WrapNum x))
evalPolyDeriv :: (Num a, Eq a) => Poly a -> a -> (a,a)
evalPolyDeriv f x = (unwrapNum y, unwrapNum y')
where
~(y, y') = VS.evalPolyDeriv (wrapPoly f) (WrapNum x)
evalPolyDerivs :: (Num a, Eq a) => Poly a -> a -> [a]
evalPolyDerivs f x = map unwrapNum (VS.evalPolyDerivs (wrapPoly f) (WrapNum x))
contractPoly :: (Num a, Eq a) => Poly a -> a -> (Poly a, a)
contractPoly p a = (unwrapPoly q, unwrapNum r)
where
(q, r) = VS.contractPoly (wrapPoly p) (WrapNum a)
gcdPoly :: (Fractional a, Eq a) => Poly a -> Poly a -> Poly a
gcdPoly a b = unwrapPoly (VS.gcdPolyWith 1 (*) (/) (wrapPoly a) (wrapPoly b))
monicPoly :: (Fractional a, Eq a) => Poly a -> Poly a
monicPoly p = unwrapPoly (VS.monicPolyWith 1 (/) (wrapPoly p))
polyDeriv :: (Num a, Eq a) => Poly a -> Poly a
polyDeriv p = unwrapPoly (VS.polyDeriv (wrapPoly p))
polyDerivs :: (Num a, Eq a) => Poly a -> [Poly a]
polyDerivs p = map unwrapPoly (VS.polyDerivs (wrapPoly p))
polyIntegral :: (Fractional a, Eq a) => Poly a -> Poly a
polyIntegral p = unwrapPoly (VS.polyIntegral (wrapPoly p))
separateRoots :: (Fractional a, Eq a) => Poly a -> [Poly a]
separateRoots p
| polyIsZero q = error "separateRoots: zero polynomial"
| polyIsOne q = [p]
| otherwise = p `quotPoly` q : separateRoots q
where
q = gcdPoly p (polyDeriv p)