Permalink
Browse files

Add SPECIALIZE pragmas to all of the things

  • Loading branch information...
1 parent 6c6dcd5 commit 83b94e0d24cb82f0f7467352e60a2391a519e5d9 @alang9 committed May 24, 2012
Showing with 32 additions and 3 deletions.
  1. +18 −1 src/Math/Spline/BSpline/Internal.hs
  2. +13 −1 src/Math/Spline/Class.hs
  3. +1 −1 test/Tests/BSpline/Reference.hs
@@ -16,6 +16,8 @@ import Math.Spline.Knots
import Data.Monoid
import Data.Vector.Generic.Safe as V hiding (slice)
+import qualified Data.Vector.Safe as BV (Vector)
+import qualified Data.Vector.Unboxed.Safe as UV (Vector)
import Data.VectorSpace
import Prelude as P
@@ -37,6 +39,8 @@ instance (Show (Scalar a), Show a, Show (v a)) => Show (BSpline v a) where
)
mapControlPoints :: (Scalar a ~ Scalar b, Vector v a, Vector v b) => (a -> b) -> BSpline v a -> BSpline v b
+{-# SPECIALIZE mapControlPoints :: (Scalar a ~ Scalar b) => (a -> b)
+ -> BSpline BV.Vector a -> BSpline BV.Vector b #-}
mapControlPoints f spline = spline
{ controlPoints = V.map f (controlPoints spline)
, knotVector = knotVector spline
@@ -53,6 +57,8 @@ mapControlPoints f spline = spline
evalBSpline :: ( VectorSpace a, Fractional (Scalar a), Ord (Scalar a)
, Vector v a, Vector v (Scalar a))
=> BSpline v a -> Scalar a -> a
+{-# SPECIALIZE evalBSpline :: ( VectorSpace a, Fractional (Scalar a)
+ , Ord (Scalar a)) => BSpline BV.Vector a -> Scalar a -> a#-}
evalBSpline spline
| V.null (controlPoints spline) = zeroV
| otherwise = V.head . P.last . deBoor spline
@@ -64,12 +70,16 @@ evalBSpline spline
evalNaturalBSpline :: ( VectorSpace a, Fractional (Scalar a), Ord (Scalar a)
, Vector v a, Vector v (Scalar a))
=> BSpline v a -> Scalar a -> a
+{-# SPECIALIZE evalNaturalBSpline :: ( VectorSpace a, Fractional (Scalar a), Ord (Scalar a))
+ => BSpline BV.Vector a -> Scalar a -> a #-}
evalNaturalBSpline spline x = V.head (P.last (deBoor (slice spline x) x))
-- |Insert one knot into a 'BSpline' without changing the spline's shape.
insertKnot
:: (VectorSpace a, Ord (Scalar a), Fractional (Scalar a), Vector v a, Vector v (Scalar a)) =>
BSpline v a -> Scalar a -> BSpline v a
+{-# SPECIALIZE insertKnot :: (VectorSpace a, Ord (Scalar a), Fractional (Scalar a)) =>
+ BSpline BV.Vector a -> Scalar a -> BSpline BV.Vector a #-}
insertKnot spline x = spline
{ knotVector = knotVector spline `mappend` knot x
, controlPoints = V.zipWith4 (interp x) us (V.drop p us) ds (V.tail ds)
@@ -82,6 +92,7 @@ insertKnot spline x = spline
-- duplicate the endpoints of a list; for example,
-- extend [1..5] -> [1,1,2,3,4,5,5]
extend :: Vector v t => v t -> v t
+{-# SPECIALIZE extend :: BV.Vector t -> BV.Vector t #-}
extend vec
| V.null vec = V.empty
| otherwise = V.cons (V.head vec) (V.snoc vec (V.last vec))
@@ -92,7 +103,9 @@ extend vec
-- greatly simplifies the definition and makes the similarity to splitting Bezier curves very obvious.
deBoor :: (Fractional (Scalar a), Ord (Scalar a), VectorSpace a, Vector v a, Vector v (Scalar a))
=> BSpline v a -> Scalar a -> [v a]
-deBoor spline x = go us0 (V.convert $ controlPoints spline)
+{-# SPECIALIZE deBoor :: (Fractional (Scalar a), Ord (Scalar a), VectorSpace a)
+ => BSpline BV.Vector a -> Scalar a -> [BV.Vector a] #-}
+deBoor spline x = go us0 (controlPoints spline)
where
us0 = V.convert $ knotsVector (knotVector spline)
-- Upper endpoints of the intervals are the same for
@@ -132,6 +145,8 @@ interp x x0 x1 y0 y1
{-# INLINE slice #-}
slice :: (Num (Scalar a), Ord (Scalar a), AdditiveGroup a, Vector v a)
=> BSpline v a -> Scalar a -> BSpline v a
+{-# SPECIALIZE INLINE slice :: (Num (Scalar a), Ord (Scalar a), AdditiveGroup a)
+ => BSpline BV.Vector a -> Scalar a -> BSpline BV.Vector a #-}
slice spline x = spline
{ knotVector = stakeKnots (n + n) . sdropKnots (l - n) $ knotVector spline
, controlPoints = vtake n . vdrop (l - n) $ controlPoints spline
@@ -144,12 +159,14 @@ slice spline x = spline
-- Try to take n, but if there's not enough, pad the rest with 0s
vtake :: (Vector v t, AdditiveGroup t) => Int -> v t -> v t
+{-# SPECIALIZE vtake :: AdditiveGroup t => Int -> BV.Vector t -> BV.Vector t #-}
vtake n xs
| n <= V.length xs = V.take n xs
| otherwise = xs V.++ V.replicate (n - V.length xs) zeroV
-- Try to drop n, but if n is negative, pad the beginning with 0s
vdrop :: (Vector v t, AdditiveGroup t) => Int -> v t -> v t
+{-# SPECIALIZE vdrop :: AdditiveGroup t => Int -> BV.Vector t -> BV.Vector t #-}
vdrop n xs
| n >= 0 = V.drop n xs
| otherwise = V.replicate (-n) zeroV V.++ xs
View
@@ -1,11 +1,13 @@
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances #-}
+{-# LANGUAGE OverlappingInstances, IncoherentInstances #-}
module Math.Spline.Class where
import Control.Applicative
import Math.Spline.Knots
import qualified Math.Spline.BSpline.Internal as BSpline
import qualified Data.Vector.Safe as V
+import qualified Data.Vector.Generic.Safe as G
import Data.VectorSpace
-- |A spline is a piecewise polynomial vector-valued function. The necessary
@@ -42,5 +44,15 @@ instance (VectorSpace v, Fractional (Scalar v), Ord (Scalar v)) => Spline (BSpli
knotVector = BSpline.knotVector
toBSpline = id
+instance ( VectorSpace a, Fractional (Scalar a), Ord (Scalar a), G.Vector v a
+ , G.Vector v (Scalar a)) => Spline (BSpline.BSpline v) a where
+ evalSpline = BSpline.evalBSpline
+ splineDegree = BSpline.degree
+ knotVector = BSpline.knotVector
+ toBSpline (BSpline.Spline deg ks ctp) = BSpline.Spline deg ks (G.convert $ ctp)
+
instance Spline (BSpline.BSpline V.Vector) a => ControlPoints (BSpline.BSpline V.Vector) a where
- controlPoints = BSpline.controlPoints
+ controlPoints = BSpline.controlPoints
+
+instance (Spline (BSpline.BSpline v) a, G.Vector v a) => ControlPoints (BSpline.BSpline v) a where
+ controlPoints = V.convert . BSpline.controlPoints
@@ -1,4 +1,4 @@
-{-# LANGUAGE ParallelListComp, ExtendedDefaultRules #-}
+{-# LANGUAGE ParallelListComp, ExtendedDefaultRules, OverlappingInstances #-}
module Tests.BSpline.Reference where
import qualified Data.Vector.Safe as V

0 comments on commit 83b94e0

Please sign in to comment.