-- | -- Module: Data.Poly.Sparse.Laurent -- Copyright: (c) 2020 Andrew Lelechenko -- Licence: BSD3 -- Maintainer: Andrew Lelechenko -- -- Sparse -- . -- -- @since 0.4.0.0 {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE PatternSynonyms #-} module Data.Poly.Sparse.Laurent ( Laurent , VLaurent , ULaurent , unLaurent , toLaurent , leading , monomial , scale , pattern X , (^-) , eval , subst , deriv ) where import Data.Euclidean (Field) import Data.Semiring (Semiring(..), Ring) import qualified Data.Vector.Generic as G import qualified Data.Vector.Unboxed.Sized as SU import qualified Data.Vector.Sized as SV import Data.Poly.Internal.Multi.Laurent hiding (monomial, scale, pattern X, (^-), eval, subst, deriv) import qualified Data.Poly.Internal.Multi.Laurent as Multi import Data.Poly.Internal.Multi (Poly) -- | Create a monomial from a power and a coefficient. -- -- @since 0.4.0.0 monomial :: (Eq a, Semiring a, G.Vector v (SU.Vector 1 Word, a)) => Int -> a -> Laurent v a monomial = Multi.monomial . SU.singleton {-# INLINABLE monomial #-} -- | Multiply a polynomial by a monomial, expressed as a power and a coefficient. -- -- >>> scale 2 3 (X^-2 + 1) :: ULaurent Int -- 3 * X^2 + 3 -- -- @since 0.4.0.0 scale :: (Eq a, Semiring a, G.Vector v (SU.Vector 1 Word, a)) => Int -> a -> Laurent v a -> Laurent v a scale = Multi.scale . SU.singleton {-# INLINABLE scale #-} -- | The polynomial 'X'. -- -- > X == monomial 1 one -- -- @since 0.4.0.0 pattern X :: (Eq a, Semiring a, G.Vector v (SU.Vector 1 Word, a)) => Laurent v a pattern X = Multi.X -- | Used to construct monomials with negative powers. -- -- This operator can be applied only to monomials with unit coefficients, -- but is instrumental to express Laurent polynomials -- in a mathematical fashion: -- -- >>> X^-3 :: ULaurent Int -- 1 * X^-3 -- >>> X + 2 + 3 * (X^2)^-1 :: ULaurent Int -- 1 * X + 2 + 3 * X^-2 -- -- @since 0.4.0.0 (^-) :: (Eq a, Semiring a, G.Vector v (SU.Vector 1 Word, a)) => Laurent v a -> Int -> Laurent v a (^-) = (Multi.^-) -- | Evaluate the polynomial at a given point. -- -- >>> eval (X^-2 + 1 :: ULaurent Double) 2 -- 1.25 -- -- @since 0.4.0.0 eval :: (Field a, G.Vector v (SU.Vector 1 Word, a)) => Laurent v a -> a -> a eval p = Multi.eval p . SV.singleton {-# INLINABLE eval #-} -- | Substitute another polynomial instead of 'X'. -- -- >>> import Data.Poly.Sparse (UPoly) -- >>> subst (Data.Poly.Sparse.X^2 + 1 :: UPoly Int) (X^-1 + 1 :: ULaurent Int) -- 2 + 2 * X^-1 + 1 * X^-2 -- -- @since 0.4.0.0 subst :: (Eq a, Semiring a, G.Vector v (SU.Vector 1 Word, a), G.Vector w (SU.Vector 1 Word, a)) => Poly v a -> Laurent w a -> Laurent w a subst p = Multi.subst p . SV.singleton {-# INLINABLE subst #-} -- | Take the derivative of the polynomial. -- -- >>> deriv (X^-3 + 3 * X) :: ULaurent Int -- 3 + (-3) * X^-4 -- -- @since 0.4.0.0 deriv :: (Eq a, Ring a, G.Vector v (SU.Vector 1 Word, a)) => Laurent v a -> Laurent v a deriv = Multi.deriv 0 {-# INLINABLE deriv #-}