packages feed

interpolation 0.1.1.1 → 0.1.1.2

raw patch · 17 files changed

+528/−203 lines, 17 filesdep +comfort-array-shapedep +doctest-exitcode-stdiodep +doctest-libdep ~comfort-arraydep ~containersdep ~lapackPVP ok

version bump matches the API change (PVP)

Dependencies added: comfort-array-shape, doctest-exitcode-stdio, doctest-lib

Dependency ranges changed: comfort-array, containers, lapack, random

API changes (from Hackage documentation)

Files

ChangeLog view
@@ -1,3 +1,7 @@+0.1.1.2:++* add testsuite based on doctest comments and doctest-extract+ 0.1:  * Hermite1 interpolation: different order of coefficients
+ Makefile view
@@ -0,0 +1,8 @@+run-test:	update-test+	runhaskell Setup configure --user --enable-test -fbuildExamples -flapack+	runhaskell Setup build+	runhaskell Setup haddock+	runhaskell Setup test --show-details=always++update-test:+	doctest-extract -i src/ -o test/ --module-prefix Test --executable-main=Test.hs $$(cat test-module.list)
example/Fit.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE Rank2Types #-} module Main where @@ -8,19 +9,23 @@ import qualified Numeric.Interpolation.Type as Type  import qualified Numeric.LAPACK.Singular as Singular-import qualified Numeric.LAPACK.ShapeStatic as ShapeStatic import qualified Numeric.LAPACK.Matrix.Shape as MatrixShape import qualified Numeric.LAPACK.Matrix.BandedHermitianPositiveDefinite                                                        as BandedSPD import qualified Numeric.LAPACK.Matrix.BandedHermitian as BandedHermitian+import qualified Numeric.LAPACK.Matrix.Banded as Banded import qualified Numeric.LAPACK.Matrix.Array as ArrMatrix import qualified Numeric.LAPACK.Matrix as Matrix import qualified Numeric.LAPACK.Vector as Vector+import Numeric.LAPACK.Matrix ((#\|))+import Numeric.LAPACK.Vector (Vector)  import qualified Type.Data.Num.Unary as Unary import Type.Base.Proxy (Proxy)  import qualified Data.Array.Comfort.Storable as Array+import qualified Data.Array.Comfort.Container as Container+import qualified Data.Array.Comfort.Shape.Static as ShapeStatic import qualified Data.Array.Comfort.Shape as Shape  import qualified Graphics.Gnuplot.Advanced as GP@@ -39,11 +44,11 @@ import Data.Monoid ((<>))  -type BandedHermitianMatrix k =-       BandedHermitian.BandedHermitian k Matrix.ShapeInt-type Matrix = Matrix.General Matrix.ShapeInt Matrix.ShapeInt-type Vector = Vector.Vector Matrix.ShapeInt-type ShortVector k = Vector.Vector (ShapeStatic.ZeroBased k)+{- |+We use @'Container.Shape' []@ for distinction.+We could use 'Matrix.ShapeInt' as well.+-}+type BasicMatrix = Matrix.General Matrix.ShapeInt (Container.Shape [])   noisy :: [(Double, Double)]@@ -55,24 +60,23 @@       (randomRs (-0.2,0.2) (mkStdGen 42))  basisMatrixFull ::-   Type.T Double Double ny -> [Double] -> [Double] -> Matrix Double+   Type.T Double Double ny -> [Double] -> [Double] -> BasicMatrix Double basisMatrixFull typ xs txs0 =    let txs = Vector.autoFromList txs0-   in  Matrix.fromColumns (Array.shape txs) $+   in  Matrix.fromColumnContainer (Array.shape txs) $        map (flip Array.map txs . Piecewise.interpolateConstantExt typ) $        Type.basisFunctions typ xs  zipRowsWith :: (a -> b -> c) -> [a] -> [[b]] -> [c] zipRowsWith f as bs = concat $ zipWith (map . f) as bs --- ToDo: generalize shapes basisMatrixSparse ::-   Type.T Double Double ny -> [Double] -> [Double] -> Matrix Double+   Type.T Double Double ny -> [Double] -> [Double] -> BasicMatrix Double basisMatrixSparse typ xs txs =    Matrix.fromRowMajor $    Array.fromAssociations 0       (Shape.ZeroBased $ length txs,-       Shape.ZeroBased $ length $ Type.basisFunctions typ xs) $+       Container.toShape $ Type.basisFunctions typ xs) $    zipRowsWith (\k (j,x) -> ((k,j),x)) [0..] $    map (Type.sampleBasisFunctions typ xs) txs @@ -99,34 +103,31 @@   mulSparseMatrixVector ::-   Int -> [[(Int, Double)]] -> [Double] -> Vector Double-mulSparseMatrixVector size samples tys =+   (Shape.Indexed shape) =>+   shape -> [[(Shape.Index shape, Double)]] ->+   [Double] -> Vector shape Double+mulSparseMatrixVector shape samples tys =    Array.accumulate (+)-      (Vector.zero (Matrix.shapeInt size))+      (Vector.zero shape)       (zipRowsWith (\ty (k,y) -> (k, y*ty)) tys samples) -{- ToDo:-use index type (ZeroInt, Enumeration Order)-with Order = Absolute | Derivative-Problem: not all interpolation types use derivatives--} shortVector ::    (Unary.Natural k) =>-   Proxy k -> [(Int, Double)] -> (Int, ShortVector k Double)+   Proxy k -> [(Int, Double)] -> (Int, Vector (ShapeStatic.ZeroBased k) Double) shortVector width xs =    let i0 = minimum $ map fst xs    in (i0,---       Array.fromAssociations 0 Shape.static $        Array.reshape Shape.static $-       Array.fromAssociations 0 (Matrix.shapeInt $ Unary.integralFromProxy width) $+       Array.fromAssociations 0+          (Matrix.shapeInt $ Unary.integralFromProxy width) $        map (mapFst (subtract i0)) xs)  bandedGramian ::-   (Unary.Natural k) =>-   Int -> Proxy (Unary.Succ k) ->-   [[(Int, Double)]] -> BandedHermitianMatrix k Double-bandedGramian size width samples =-   BandedHermitian.sumRank1 MatrixShape.ColumnMajor (Matrix.shapeInt size) $+   (Shape.Indexed shape, Shape.Index shape ~ Int, Unary.Natural k) =>+   shape -> Proxy (Unary.Succ k) ->+   [[(Int, Double)]] -> Banded.HermitianPosSemidef k shape Double+bandedGramian shape width samples =+   BandedHermitian.sumRank1 MatrixShape.ColumnMajor shape $    map ((,) 1 . shortVector width) samples  reifyPositive ::@@ -137,15 +138,16 @@    Type.T Double Double ny ->    [Double] -> [(Double, Double)] -> Nodes.T Double ny fitBanded typ xs target =-   let size = length $ Type.basisFunctions typ xs+   let shape = Container.toShape $ Type.basisFunctions typ xs        (txs, tys) = unzip target        samples = map (Type.sampleBasisFunctions typ xs) txs-   in reifyPositive (toInteger $ Type.basisOverlap typ) +   in reifyPositive+         (toInteger $ Type.basisOverlap typ)          (\width ->             Type.coefficientsToInterpolator typ xs $ Vector.toList $-            Matrix.unliftColumn MatrixShape.ColumnMajor-               (BandedSPD.solve (bandedGramian size width samples)) $-            mulSparseMatrixVector size samples tys)+            BandedSPD.assureFullRank (bandedGramian shape width samples)+            #\|+            mulSparseMatrixVector shape samples tys)  bandedDiff ::    (ny -> ny -> Double) ->
interpolation.cabal view
@@ -1,10 +1,11 @@+Cabal-Version:    2.2 Name:             interpolation-Version:          0.1.1.1-License:          BSD3+Version:          0.1.1.2+License:          BSD-3-Clause License-File:     LICENSE Author:           Henning Thielemann Maintainer:       Henning Thielemann <haskell@henning-thielemann.de>-Homepage:         http://hub.darcs.net/thielema/interpolation/+Homepage:         https://hub.darcs.net/thielema/interpolation/ Category:         Math Synopsis:         piecewise linear and cubic Hermite interpolation Description:@@ -33,10 +34,11 @@   Most of the package dependencies are only needed for the examples   and are only installed if you enable to build them. Tested-With:      GHC==7.4.2, GHC==7.6.3, GHC==7.8.4, GHC==7.10.1-Cabal-Version:    >=1.8 Build-Type:       Simple Extra-Source-Files:   ChangeLog+  Makefile+  test-module.list  Flag buildExamples   description: Build example executables@@ -47,13 +49,13 @@   default:     True  Source-Repository this-  Tag:         0.1.1.1+  Tag:         0.1.1.2   Type:        darcs-  Location:    http://hub.darcs.net/thielema/interpolation/+  Location:    https://hub.darcs.net/thielema/interpolation/  Source-Repository head   Type:        darcs-  Location:    http://hub.darcs.net/thielema/interpolation/+  Location:    https://hub.darcs.net/thielema/interpolation/  Library   Build-Depends:@@ -62,6 +64,7 @@    GHC-Options:      -Wall   Hs-Source-Dirs:   src, private+  Default-Language: Haskell98   Exposed-Modules:     Numeric.Interpolation.NodeList     Numeric.Interpolation.Piece@@ -81,6 +84,7 @@   Other-Modules:       Plot2DExtra   Hs-Source-Dirs:      example   GHC-Options:         -Wall+  Default-Language:    Haskell98   If flag(buildExamples)     Build-Depends:       interpolation,@@ -95,12 +99,14 @@   Other-Modules:       Plot2DExtra   Hs-Source-Dirs:      example   GHC-Options:         -Wall+  Default-Language:    Haskell98   If flag(buildExamples) && flag(lapack)     Build-Depends:       interpolation,-      lapack >=0.3 && <0.4,+      lapack >=0.4 && <0.5,       tfp >=1.0 && <1.1,-      comfort-array >=0.4 && <0.5,+      comfort-array-shape >=0.0 && <0.1,+      comfort-array >=0.5.1 && <0.6,       random >=1.0 && <1.2,       gnuplot >=0.5.6 && <0.6,       utility-ht >=0.0.9 && <0.1,@@ -112,14 +118,18 @@   Type:                exitcode-stdio-1.0   Main-Is:             Test.hs   Other-Modules:-    Test.Piece-    Test.Sample-    Test.Overlap+    Test.Numeric.Interpolation.Type+    Test.Numeric.Interpolation.NodeList+    Test.Numeric.Interpolation.Piece+    Test.Numeric.Interpolation.Piecewise     Numeric.Interpolation.Private.Piece   Hs-Source-Dirs:      test, private   GHC-Options:         -Wall+  Default-Language:    Haskell98   Build-Depends:     interpolation,+    doctest-exitcode-stdio >=0.0 && <0.1,+    doctest-lib >=0.1 && <0.2,     QuickCheck >=2.4 && <3,     utility-ht >=0.0.9 && <0.1,     array >=0.4 && <0.6,
src/Numeric/Interpolation/NodeList.hs view
@@ -16,22 +16,40 @@  import Prelude hiding (lookup) +{- $setup+>>> import qualified Numeric.Interpolation.NodeList as Nodes+>>> import qualified Data.Traversable as Trav+>>> import qualified Data.Foldable as Fold+>>> import qualified Data.List as List+>>> import Data.Tuple.HT (mapSnd)+>>> import Data.Char (ord)+-} + data T x y = Interval | Node (x, y) (T x y) (T x y)    deriving (Eq, Ord, Show) +{- |+prop> \xs -> map (mapSnd ord) xs == Nodes.toList (fmap ord (Nodes.fromList (xs::[(Integer,Char)])))+-} instance Functor (T x) where    fmap f =       let go Interval = Interval           go (Node (x,y) l r) = Node (x, f y) (go l) (go r)       in  go +{- |+prop> \xs -> map snd xs == Fold.toList (Nodes.fromList (xs::[(Integer,Char)]))+-} instance Foldable (T x) where    foldMap f =       let go Interval = mempty           go (Node (_x,y) l r) = go l <> f y <> go r       in  go +{- |+prop> \x xs -> let f acc y = (acc+y,acc) in List.mapAccumL f x (map snd xs) == mapSnd Fold.toList (Trav.mapAccumL f x (Nodes.fromList (xs::[(Int,Integer)])))+-} instance Traversable (T x) where    traverse f =       let go Interval = pure Interval@@ -55,15 +73,35 @@        rep (n,xyns) = if null xyns then n else rep $ merge n xyns    in  rep . merge Interval . map (flip (,) Interval) +{- |+prop> \x y -> Nodes.singleton x y == Nodes.fromList [(x,y)::(Integer,Char)]+-} singleton :: x -> y -> T x y singleton x y = Node (x,y) Interval Interval +{- |+prop> \xs -> xs == Nodes.toList (Nodes.fromList (xs::[(Integer,Char)]))+-} toList :: T x y -> [(x,y)] toList =    let go Interval = []        go (Node p l r) = go l ++ p : go r    in  go +{- |+>>> Nodes.lookup (Nodes.fromList ([(0,'a'),(2::Int,'b')])) (-1)+(Nothing,Just (0,'a'))+>>> Nodes.lookup (Nodes.fromList ([(0,'a'),(2::Int,'b')])) 0+(Just (0,'a'),Just (2,'b'))+>>> Nodes.lookup (Nodes.fromList ([(0,'a'),(2::Int,'b')])) 1+(Just (0,'a'),Just (2,'b'))+>>> Nodes.lookup (Nodes.fromList ([(0,'a'),(2::Int,'b')])) 2+(Just (2,'b'),Nothing)+>>> Nodes.lookup (Nodes.fromList ([(0,'a'),(2::Int,'b')])) 3+(Just (2,'b'),Nothing)+>>> Nodes.lookup (Nodes.fromList ([(0,'a'),(2,'b'),(5::Int,'c')])) 3+(Just (2,'b'),Just (5,'c'))+-} lookup :: Ord x => T x y -> x -> (Maybe (x,y), Maybe (x,y)) lookup nodes0 x0 =    let go lb rb Interval = (lb, rb)
src/Numeric/Interpolation/Piece.hs view
@@ -1,15 +1,40 @@ module Numeric.Interpolation.Piece (    Piece.T,-   Piece.linear,+   linear,    hermite1,    ) where  import qualified Numeric.Interpolation.Private.Piece as Piece  +{- $setup+>>> import qualified Numeric.Interpolation.Piece as Piece+>>> import qualified Numeric.Interpolation.Private.Piece as PiecePriv+>>> import qualified Test.QuickCheck as QC+>>> import Test.QuickCheck ((==>))+>>>+>>> forAllDistinctPoints ::+>>>    (Show a, QC.Arbitrary a, QC.Testable prop) =>+>>>    ((Rational, a) -> (Rational, a) -> prop) -> QC.Property+>>> forAllDistinctPoints f =+>>>    QC.forAll QC.arbitrary $ \p1@(x1,_) ->+>>>    QC.forAll QC.arbitrary $ \p2@(x2,_) ->+>>>       x1/=x2  ==>  f p1 p2+-}+ {- |+prop> forAllDistinctPoints $ \p1 p2 x -> Piece.linear p1 p2 x == Piece.linear p2 p1 x+-}+linear :: (Fractional a) => Piece.T a a a+linear = Piece.linear++{- | Hermite interpolation with one derivative per node. That is, the interpolating polynomial is cubic.++prop> forAllDistinctPoints $ \p1 p2 x -> Piece.hermite1 p1 p2 x == Piece.hermite1 p2 p1 x+prop> forAllDistinctPoints $ \p1@(x1,y1) p2@(x2,y2) x -> Piece.linear p1 p2 x == let slope = (y2-y1)/(x2-x1) in Piece.hermite1 (x1, (y1,slope)) (x2, (y2,slope)) x+prop> forAllDistinctPoints $ \p1 p2 x -> Piece.hermite1 p1 p2 x == PiecePriv.hermite1 p1 p2 x -} hermite1 :: (Fractional a) => Piece.T a a (a, a) hermite1 (x0,(y0,dy0)) (x1,(y1,dy1)) x =
src/Numeric/Interpolation/Piecewise.hs view
@@ -7,8 +7,60 @@ import qualified Numeric.Interpolation.Type as Type  +{- $setup+>>> import qualified Numeric.Interpolation.Piecewise as Piecewise+>>> import qualified Numeric.Interpolation.NodeList as Nodes+>>> import qualified Numeric.Interpolation.Type as Type+>>>+>>> import qualified Data.List as List+>>> import qualified Data.Set as Set+>>> import Data.Array (accumArray, listArray)+>>> import Data.List.HT (lengthAtLeast)+>>>+>>> import qualified Test.QuickCheck as QC+>>> import Test.QuickCheck ((==>))+>>>+>>> forAllSortedRatios ::+>>>    (QC.Testable prop) => ([Rational] -> Rational -> prop) -> QC.Property+>>> forAllSortedRatios f =+>>>    QC.forAll (fmap Set.toAscList QC.arbitrary) $ \nodeXs x ->+>>>       f (map fromInteger nodeXs) (fromInteger x)+>>>+>>> checkEq ::+>>>    (Ord x, Eq y, Num y) =>+>>>    Type.T x y ny -> [x] -> x -> Bool+>>> checkEq typ nodeXs x =+>>>    let ys =+>>>           map+>>>              (flip (Piecewise.interpolateConstantExt typ) x)+>>>              (Type.basisFunctions typ nodeXs)+>>>        bounds = (0, length ys - 1)+>>>    in  listArray bounds ys+>>>        ==+>>>        accumArray (flip const) 0 bounds+>>>           (Type.sampleBasisFunctions typ nodeXs x)+>>>+>>> quantile :: (Show a, Ord a, Fractional a) => [a] -> a -> a+>>> quantile [] _ = error "quantile: empty list"+>>> quantile [y] _ = y+>>> quantile ys x =+>>>    let len = fromIntegral (length ys - 1)+>>>    in Piecewise.interpolateConstantExt Type.linear+>>>          (Nodes.fromList $ zip (map (/ len) $ map fromInteger [0..]) $+>>>           List.sort ys)+>>>          x+-}++ {- | It is a checked error to interpolate outside of the range of nodes.++>>> Piecewise.interpolate Type.linear (Nodes.fromList [(0,0),(3,6),(5,10::Rational)]) 2+4 % 1+>>> Piecewise.interpolate Type.hermite1 (Nodes.fromList [(0,(0,0)),(3,(9,6)),(5,(25,10::Rational))]) 2+4 % 1+>>> Piecewise.interpolate Type.hermite1 (Nodes.fromList [(0,(1,-2)),(3,(4,4)),(5,(16,8::Rational))]) 2+1 % 1 -} interpolate :: (Ord x) => Type.T x y ny -> Nodes.T x ny -> x -> y interpolate typ ns x =@@ -19,6 +71,25 @@ {- | Outside the range of nodes the interpolation function takes the value of the respective border.++prop> forAllSortedRatios $ checkEq Type.linear+prop> forAllSortedRatios $ checkEq Type.hermite1+prop> forAllSortedRatios $ \nodeXs x -> lengthAtLeast 4 nodeXs ==> checkEq Type.cubicLinear nodeXs x+prop> forAllSortedRatios $ \nodeXs x -> lengthAtLeast 4 nodeXs ==> checkEq Type.cubicParabola nodeXs x+++Linear interpolation can be used to compute the median, a quartile+or any other quantile of a list of arbitrary numbers.++>>> quantile [2,5,3::Rational] 0.5+3 % 1+>>> quantile [2,5,3,7::Rational] 0.5+4 % 1+>>> quantile [2,5,3,7::Rational] 0.25+11 % 4++prop> \(QC.NonEmpty xs) -> quantile (xs::[Rational]) 0 == minimum xs+prop> \(QC.NonEmpty xs) -> quantile (xs::[Rational]) 1 == maximum xs -} interpolateConstantExt ::    (Ord x) => Type.T x y ny -> Nodes.T x ny -> x -> y
src/Numeric/Interpolation/Type.hs view
@@ -13,6 +13,21 @@ import Numeric.Interpolation.Private.Basis (hermite1Split)  +{- $setup+>>> import qualified Numeric.Interpolation.Type as Type+>>>+>>> checkOverlap :: Type.T Double y ny -> [Double] -> Double -> Bool+>>> checkOverlap typ xs xi =+>>>    let samples = map fst $ Type.sampleBasisFunctions typ xs xi+>>>    in  all (< minimum samples + Type.basisOverlap typ) samples+>>>+>>> checkOverlapNotTotal :: Type.T Double y ny -> [Double] -> Double -> Bool+>>> checkOverlapNotTotal typ xs xi =+>>>    let samples = map fst $ Type.sampleBasisFunctions typ xs xi+>>>    in  maximum samples - minimum samples < Type.basisOverlap typ+-}++ data T x y ny =    Cons {       ssvFromNodes :: [x] -> [y] -> String,@@ -27,6 +42,9 @@       valueFromNode :: ny -> y    } +{- |+prop> checkOverlap Type.linear+-} linear :: (Fractional a, Ord a, Show a) => T a a a linear =    Cons {@@ -40,6 +58,9 @@       valueFromNode = id    } +{- |+prop> checkOverlap Type.hermite1+-} hermite1 :: (Fractional a, Ord a, Show a) => T a a (a, a) hermite1 =    Cons {@@ -56,6 +77,9 @@       valueFromNode = fst    } +{- |+prop> checkOverlap Type.cubicLinear+-} cubicLinear :: (Fractional a, Ord a, Show a) => T a a (a, a) cubicLinear =    Cons {@@ -69,6 +93,9 @@       valueFromNode = fst    } +{- |+prop> checkOverlap Type.cubicParabola+-} cubicParabola :: (Fractional a, Ord a, Show a) => T a a (a, a) cubicParabola =    Cons {
+ test-module.list view
@@ -0,0 +1,4 @@+Numeric.Interpolation.Type+Numeric.Interpolation.NodeList+Numeric.Interpolation.Piece+Numeric.Interpolation.Piecewise
test/Test.hs view
@@ -1,16 +1,16 @@+-- Do not edit! Automatically created with doctest-extract. module Main where -import qualified Test.Piece as Piece-import qualified Test.Sample as Sample-import qualified Test.Overlap as Overlap-+import qualified Test.Numeric.Interpolation.Type+import qualified Test.Numeric.Interpolation.NodeList+import qualified Test.Numeric.Interpolation.Piece+import qualified Test.Numeric.Interpolation.Piecewise -run :: String -> [(String, IO ())] -> IO ()-run prefix =-   mapM_ (\(msg,act) -> putStr (prefix ++ '.' : msg ++ ": ") >> act)+import qualified Test.DocTest.Driver as DocTest  main :: IO ()-main = do-   run "Piece" Piece.tests-   run "Sample" Sample.tests-   run "Overlap" Overlap.tests+main = DocTest.run $ do+    Test.Numeric.Interpolation.Type.test+    Test.Numeric.Interpolation.NodeList.test+    Test.Numeric.Interpolation.Piece.test+    Test.Numeric.Interpolation.Piecewise.test
+ test/Test/Numeric/Interpolation/NodeList.hs view
@@ -0,0 +1,79 @@+-- Do not edit! Automatically created with doctest-extract from src/Numeric/Interpolation/NodeList.hs+{-# LINE 19 "src/Numeric/Interpolation/NodeList.hs" #-}++module Test.Numeric.Interpolation.NodeList where++import Test.DocTest.Base+import qualified Test.DocTest.Driver as DocTest++{-# LINE 20 "src/Numeric/Interpolation/NodeList.hs" #-}+import     qualified Numeric.Interpolation.NodeList as Nodes+import     qualified Data.Traversable as Trav+import     qualified Data.Foldable as Fold+import     qualified Data.List as List+import     Data.Tuple.HT (mapSnd)+import     Data.Char (ord)++test :: DocTest.T ()+test = do+ DocTest.printPrefix "Numeric.Interpolation.NodeList:33: "+{-# LINE 33 "src/Numeric/Interpolation/NodeList.hs" #-}+ DocTest.property+{-# LINE 33 "src/Numeric/Interpolation/NodeList.hs" #-}+     (\xs -> map (mapSnd ord) xs == Nodes.toList (fmap ord (Nodes.fromList (xs::[(Integer,Char)]))))+ DocTest.printPrefix "Numeric.Interpolation.NodeList:42: "+{-# LINE 42 "src/Numeric/Interpolation/NodeList.hs" #-}+ DocTest.property+{-# LINE 42 "src/Numeric/Interpolation/NodeList.hs" #-}+     (\xs -> map snd xs == Fold.toList (Nodes.fromList (xs::[(Integer,Char)])))+ DocTest.printPrefix "Numeric.Interpolation.NodeList:51: "+{-# LINE 51 "src/Numeric/Interpolation/NodeList.hs" #-}+ DocTest.property+{-# LINE 51 "src/Numeric/Interpolation/NodeList.hs" #-}+     (\x xs -> let f acc y = (acc+y,acc) in List.mapAccumL f x (map snd xs) == mapSnd Fold.toList (Trav.mapAccumL f x (Nodes.fromList (xs::[(Int,Integer)]))))+ DocTest.printPrefix "Numeric.Interpolation.NodeList:77: "+{-# LINE 77 "src/Numeric/Interpolation/NodeList.hs" #-}+ DocTest.property+{-# LINE 77 "src/Numeric/Interpolation/NodeList.hs" #-}+     (\x y -> Nodes.singleton x y == Nodes.fromList [(x,y)::(Integer,Char)])+ DocTest.printPrefix "Numeric.Interpolation.NodeList:83: "+{-# LINE 83 "src/Numeric/Interpolation/NodeList.hs" #-}+ DocTest.property+{-# LINE 83 "src/Numeric/Interpolation/NodeList.hs" #-}+     (\xs -> xs == Nodes.toList (Nodes.fromList (xs::[(Integer,Char)])))+ DocTest.printPrefix "Numeric.Interpolation.NodeList:92: "+{-# LINE 92 "src/Numeric/Interpolation/NodeList.hs" #-}+ DocTest.example+{-# LINE 92 "src/Numeric/Interpolation/NodeList.hs" #-}+   (Nodes.lookup (Nodes.fromList ([(0,'a'),(2::Int,'b')])) (-1))+  [ExpectedLine [LineChunk "(Nothing,Just (0,'a'))"]]+ DocTest.printPrefix "Numeric.Interpolation.NodeList:94: "+{-# LINE 94 "src/Numeric/Interpolation/NodeList.hs" #-}+ DocTest.example+{-# LINE 94 "src/Numeric/Interpolation/NodeList.hs" #-}+   (Nodes.lookup (Nodes.fromList ([(0,'a'),(2::Int,'b')])) 0)+  [ExpectedLine [LineChunk "(Just (0,'a'),Just (2,'b'))"]]+ DocTest.printPrefix "Numeric.Interpolation.NodeList:96: "+{-# LINE 96 "src/Numeric/Interpolation/NodeList.hs" #-}+ DocTest.example+{-# LINE 96 "src/Numeric/Interpolation/NodeList.hs" #-}+   (Nodes.lookup (Nodes.fromList ([(0,'a'),(2::Int,'b')])) 1)+  [ExpectedLine [LineChunk "(Just (0,'a'),Just (2,'b'))"]]+ DocTest.printPrefix "Numeric.Interpolation.NodeList:98: "+{-# LINE 98 "src/Numeric/Interpolation/NodeList.hs" #-}+ DocTest.example+{-# LINE 98 "src/Numeric/Interpolation/NodeList.hs" #-}+   (Nodes.lookup (Nodes.fromList ([(0,'a'),(2::Int,'b')])) 2)+  [ExpectedLine [LineChunk "(Just (2,'b'),Nothing)"]]+ DocTest.printPrefix "Numeric.Interpolation.NodeList:100: "+{-# LINE 100 "src/Numeric/Interpolation/NodeList.hs" #-}+ DocTest.example+{-# LINE 100 "src/Numeric/Interpolation/NodeList.hs" #-}+   (Nodes.lookup (Nodes.fromList ([(0,'a'),(2::Int,'b')])) 3)+  [ExpectedLine [LineChunk "(Just (2,'b'),Nothing)"]]+ DocTest.printPrefix "Numeric.Interpolation.NodeList:102: "+{-# LINE 102 "src/Numeric/Interpolation/NodeList.hs" #-}+ DocTest.example+{-# LINE 102 "src/Numeric/Interpolation/NodeList.hs" #-}+   (Nodes.lookup (Nodes.fromList ([(0,'a'),(2,'b'),(5::Int,'c')])) 3)+  [ExpectedLine [LineChunk "(Just (2,'b'),Just (5,'c'))"]]
+ test/Test/Numeric/Interpolation/Piece.hs view
@@ -0,0 +1,43 @@+-- Do not edit! Automatically created with doctest-extract from src/Numeric/Interpolation/Piece.hs+{-# LINE 10 "src/Numeric/Interpolation/Piece.hs" #-}++module Test.Numeric.Interpolation.Piece where++import qualified Test.DocTest.Driver as DocTest++{-# LINE 11 "src/Numeric/Interpolation/Piece.hs" #-}+import     qualified Numeric.Interpolation.Piece as Piece+import     qualified Numeric.Interpolation.Private.Piece as PiecePriv+import     qualified Test.QuickCheck as QC+import     Test.QuickCheck ((==>))++forAllDistinctPoints     ::+       (Show a, QC.Arbitrary a, QC.Testable prop) =>+       ((Rational, a) -> (Rational, a) -> prop) -> QC.Property+forAllDistinctPoints     f =+       QC.forAll QC.arbitrary $ \p1@(x1,_) ->+       QC.forAll QC.arbitrary $ \p2@(x2,_) ->+          x1/=x2  ==>  f p1 p2++test :: DocTest.T ()+test = do+ DocTest.printPrefix "Numeric.Interpolation.Piece:26: "+{-# LINE 26 "src/Numeric/Interpolation/Piece.hs" #-}+ DocTest.property+{-# LINE 26 "src/Numeric/Interpolation/Piece.hs" #-}+     (forAllDistinctPoints $ \p1 p2 x -> Piece.linear p1 p2 x == Piece.linear p2 p1 x)+ DocTest.printPrefix "Numeric.Interpolation.Piece:35: "+{-# LINE 35 "src/Numeric/Interpolation/Piece.hs" #-}+ DocTest.property+{-# LINE 35 "src/Numeric/Interpolation/Piece.hs" #-}+     (forAllDistinctPoints $ \p1 p2 x -> Piece.hermite1 p1 p2 x == Piece.hermite1 p2 p1 x)+ DocTest.printPrefix "Numeric.Interpolation.Piece:36: "+{-# LINE 36 "src/Numeric/Interpolation/Piece.hs" #-}+ DocTest.property+{-# LINE 36 "src/Numeric/Interpolation/Piece.hs" #-}+     (forAllDistinctPoints $ \p1@(x1,y1) p2@(x2,y2) x -> Piece.linear p1 p2 x == let slope = (y2-y1)/(x2-x1) in Piece.hermite1 (x1, (y1,slope)) (x2, (y2,slope)) x)+ DocTest.printPrefix "Numeric.Interpolation.Piece:37: "+{-# LINE 37 "src/Numeric/Interpolation/Piece.hs" #-}+ DocTest.property+{-# LINE 37 "src/Numeric/Interpolation/Piece.hs" #-}+     (forAllDistinctPoints $ \p1 p2 x -> Piece.hermite1 p1 p2 x == PiecePriv.hermite1 p1 p2 x)
+ test/Test/Numeric/Interpolation/Piecewise.hs view
@@ -0,0 +1,119 @@+-- Do not edit! Automatically created with doctest-extract from src/Numeric/Interpolation/Piecewise.hs+{-# LINE 10 "src/Numeric/Interpolation/Piecewise.hs" #-}++module Test.Numeric.Interpolation.Piecewise where++import Test.DocTest.Base+import qualified Test.DocTest.Driver as DocTest++{-# LINE 11 "src/Numeric/Interpolation/Piecewise.hs" #-}+import     qualified Numeric.Interpolation.Piecewise as Piecewise+import     qualified Numeric.Interpolation.NodeList as Nodes+import     qualified Numeric.Interpolation.Type as Type++import     qualified Data.List as List+import     qualified Data.Set as Set+import     Data.Array (accumArray, listArray)+import     Data.List.HT (lengthAtLeast)++import     qualified Test.QuickCheck as QC+import     Test.QuickCheck ((==>))++forAllSortedRatios     ::+       (QC.Testable prop) => ([Rational] -> Rational -> prop) -> QC.Property+forAllSortedRatios     f =+       QC.forAll (fmap Set.toAscList QC.arbitrary) $ \nodeXs x ->+          f (map fromInteger nodeXs) (fromInteger x)++checkEq     ::+       (Ord x, Eq y, Num y) =>+       Type.T x y ny -> [x] -> x -> Bool+checkEq     typ nodeXs x =+       let ys =+              map+                 (flip (Piecewise.interpolateConstantExt typ) x)+                 (Type.basisFunctions typ nodeXs)+           bounds = (0, length ys - 1)+       in  listArray bounds ys+           ==+           accumArray (flip const) 0 bounds+              (Type.sampleBasisFunctions typ nodeXs x)++quantile     :: (Show a, Ord a, Fractional a) => [a] -> a -> a+quantile     [] _ = error "quantile: empty list"+quantile     [y] _ = y+quantile     ys x =+       let len = fromIntegral (length ys - 1)+       in Piecewise.interpolateConstantExt Type.linear+             (Nodes.fromList $ zip (map (/ len) $ map fromInteger [0..]) $+              List.sort ys)+             x++test :: DocTest.T ()+test = do+ DocTest.printPrefix "Numeric.Interpolation.Piecewise:58: "+{-# LINE 58 "src/Numeric/Interpolation/Piecewise.hs" #-}+ DocTest.example+{-# LINE 58 "src/Numeric/Interpolation/Piecewise.hs" #-}+   (Piecewise.interpolate Type.linear (Nodes.fromList [(0,0),(3,6),(5,10::Rational)]) 2)+  [ExpectedLine [LineChunk "4 % 1"]]+ DocTest.printPrefix "Numeric.Interpolation.Piecewise:60: "+{-# LINE 60 "src/Numeric/Interpolation/Piecewise.hs" #-}+ DocTest.example+{-# LINE 60 "src/Numeric/Interpolation/Piecewise.hs" #-}+   (Piecewise.interpolate Type.hermite1 (Nodes.fromList [(0,(0,0)),(3,(9,6)),(5,(25,10::Rational))]) 2)+  [ExpectedLine [LineChunk "4 % 1"]]+ DocTest.printPrefix "Numeric.Interpolation.Piecewise:62: "+{-# LINE 62 "src/Numeric/Interpolation/Piecewise.hs" #-}+ DocTest.example+{-# LINE 62 "src/Numeric/Interpolation/Piecewise.hs" #-}+   (Piecewise.interpolate Type.hermite1 (Nodes.fromList [(0,(1,-2)),(3,(4,4)),(5,(16,8::Rational))]) 2)+  [ExpectedLine [LineChunk "1 % 1"]]+ DocTest.printPrefix "Numeric.Interpolation.Piecewise:75: "+{-# LINE 75 "src/Numeric/Interpolation/Piecewise.hs" #-}+ DocTest.property+{-# LINE 75 "src/Numeric/Interpolation/Piecewise.hs" #-}+     (forAllSortedRatios $ checkEq Type.linear)+ DocTest.printPrefix "Numeric.Interpolation.Piecewise:76: "+{-# LINE 76 "src/Numeric/Interpolation/Piecewise.hs" #-}+ DocTest.property+{-# LINE 76 "src/Numeric/Interpolation/Piecewise.hs" #-}+     (forAllSortedRatios $ checkEq Type.hermite1)+ DocTest.printPrefix "Numeric.Interpolation.Piecewise:77: "+{-# LINE 77 "src/Numeric/Interpolation/Piecewise.hs" #-}+ DocTest.property+{-# LINE 77 "src/Numeric/Interpolation/Piecewise.hs" #-}+     (forAllSortedRatios $ \nodeXs x -> lengthAtLeast 4 nodeXs ==> checkEq Type.cubicLinear nodeXs x)+ DocTest.printPrefix "Numeric.Interpolation.Piecewise:78: "+{-# LINE 78 "src/Numeric/Interpolation/Piecewise.hs" #-}+ DocTest.property+{-# LINE 78 "src/Numeric/Interpolation/Piecewise.hs" #-}+     (forAllSortedRatios $ \nodeXs x -> lengthAtLeast 4 nodeXs ==> checkEq Type.cubicParabola nodeXs x)+ DocTest.printPrefix "Numeric.Interpolation.Piecewise:91: "+{-# LINE 91 "src/Numeric/Interpolation/Piecewise.hs" #-}+ DocTest.property+{-# LINE 91 "src/Numeric/Interpolation/Piecewise.hs" #-}+     (\(QC.NonEmpty xs) -> quantile (xs::[Rational]) 0 == minimum xs)+ DocTest.printPrefix "Numeric.Interpolation.Piecewise:92: "+{-# LINE 92 "src/Numeric/Interpolation/Piecewise.hs" #-}+ DocTest.property+{-# LINE 92 "src/Numeric/Interpolation/Piecewise.hs" #-}+     (\(QC.NonEmpty xs) -> quantile (xs::[Rational]) 1 == maximum xs)+ DocTest.printPrefix "Numeric.Interpolation.Piecewise:84: "+{-# LINE 84 "src/Numeric/Interpolation/Piecewise.hs" #-}+ DocTest.example+{-# LINE 84 "src/Numeric/Interpolation/Piecewise.hs" #-}+   (quantile [2,5,3::Rational] 0.5)+  [ExpectedLine [LineChunk "3 % 1"]]+ DocTest.printPrefix "Numeric.Interpolation.Piecewise:86: "+{-# LINE 86 "src/Numeric/Interpolation/Piecewise.hs" #-}+ DocTest.example+{-# LINE 86 "src/Numeric/Interpolation/Piecewise.hs" #-}+   (quantile [2,5,3,7::Rational] 0.5)+  [ExpectedLine [LineChunk "4 % 1"]]+ DocTest.printPrefix "Numeric.Interpolation.Piecewise:88: "+{-# LINE 88 "src/Numeric/Interpolation/Piecewise.hs" #-}+ DocTest.example+{-# LINE 88 "src/Numeric/Interpolation/Piecewise.hs" #-}+   (quantile [2,5,3,7::Rational] 0.25)+  [ExpectedLine [LineChunk "11 % 4"]]
+ test/Test/Numeric/Interpolation/Type.hs view
@@ -0,0 +1,42 @@+-- Do not edit! Automatically created with doctest-extract from src/Numeric/Interpolation/Type.hs+{-# LINE 16 "src/Numeric/Interpolation/Type.hs" #-}++module Test.Numeric.Interpolation.Type where++import qualified Test.DocTest.Driver as DocTest++{-# LINE 17 "src/Numeric/Interpolation/Type.hs" #-}+import     qualified Numeric.Interpolation.Type as Type++checkOverlap     :: Type.T Double y ny -> [Double] -> Double -> Bool+checkOverlap     typ xs xi =+       let samples = map fst $ Type.sampleBasisFunctions typ xs xi+       in  all (< minimum samples + Type.basisOverlap typ) samples++checkOverlapNotTotal     :: Type.T Double y ny -> [Double] -> Double -> Bool+checkOverlapNotTotal     typ xs xi =+       let samples = map fst $ Type.sampleBasisFunctions typ xs xi+       in  maximum samples - minimum samples < Type.basisOverlap typ++test :: DocTest.T ()+test = do+ DocTest.printPrefix "Numeric.Interpolation.Type:46: "+{-# LINE 46 "src/Numeric/Interpolation/Type.hs" #-}+ DocTest.property+{-# LINE 46 "src/Numeric/Interpolation/Type.hs" #-}+     (checkOverlap Type.linear)+ DocTest.printPrefix "Numeric.Interpolation.Type:62: "+{-# LINE 62 "src/Numeric/Interpolation/Type.hs" #-}+ DocTest.property+{-# LINE 62 "src/Numeric/Interpolation/Type.hs" #-}+     (checkOverlap Type.hermite1)+ DocTest.printPrefix "Numeric.Interpolation.Type:81: "+{-# LINE 81 "src/Numeric/Interpolation/Type.hs" #-}+ DocTest.property+{-# LINE 81 "src/Numeric/Interpolation/Type.hs" #-}+     (checkOverlap Type.cubicLinear)+ DocTest.printPrefix "Numeric.Interpolation.Type:97: "+{-# LINE 97 "src/Numeric/Interpolation/Type.hs" #-}+ DocTest.property+{-# LINE 97 "src/Numeric/Interpolation/Type.hs" #-}+     (checkOverlap Type.cubicParabola)
− test/Test/Overlap.hs
@@ -1,25 +0,0 @@-module Test.Overlap where--import qualified Numeric.Interpolation.Type as Type--import Test.QuickCheck (quickCheck, )----test :: Type.T Double y ny -> IO ()-test typ =-   quickCheck $ \xs xi ->-      let samples = map fst $ Type.sampleBasisFunctions typ xs xi-          {- not total:-          maximum samples - minimum samples < Type.basisOverlap typ-          -}-      in  all (< minimum samples + Type.basisOverlap typ) samples---tests :: [(String, IO ())]-tests =-   ("linear", test Type.linear) :-   ("hermite1", test Type.hermite1) :-   ("cubicLinear", test Type.cubicLinear) :-   ("cubicParabola", test Type.cubicParabola) :-   []
− test/Test/Piece.hs
@@ -1,60 +0,0 @@-module Test.Piece where--import qualified Numeric.Interpolation.Piece as Piece-import qualified Numeric.Interpolation.Private.Piece as PiecePriv--import Test.QuickCheck (Property, quickCheck, (==>), )---type Point = (Rational, Rational)--linearCommutative ::-   Point -> Point -> Rational -> Property-linearCommutative p1@(x1,_) p2@(x2,_) x =-   x1/=x2-   ==>-   Piece.linear p1 p2 x-   ==-   Piece.linear p2 p1 x---type PointSlope = (Rational, (Rational, Rational))--hermite1Commutative ::-   PointSlope -> PointSlope -> Rational -> Property-hermite1Commutative p1@(x1,_) p2@(x2,_) x =-   x1/=x2-   ==>-   Piece.hermite1 p1 p2 x-   ==-   Piece.hermite1 p2 p1 x---linearHermite1 ::-   Point -> Point -> Rational -> Property-linearHermite1 p1@(x1,y1) p2@(x2,y2) x =-   x1/=x2-   ==>-   Piece.linear p1 p2 x-   ==-   let slope = (y2-y1)/(x2-x1)-   in  Piece.hermite1 (x1, (y1,slope)) (x2, (y2, slope)) x---hermite1Alternative ::-   PointSlope -> PointSlope -> Rational -> Property-hermite1Alternative p1@(x1,_) p2@(x2,_) x =-   x1/=x2-   ==>-   Piece.hermite1 p1 p2 x-   ==-   PiecePriv.hermite1 p1 p2 x---tests :: [(String, IO ())]-tests =-   ("linearCommutative", quickCheck linearCommutative) :-   ("hermite1Commutative", quickCheck hermite1Commutative) :-   ("linearHermite1", quickCheck linearHermite1) :-   ("hermite1Alternative", quickCheck hermite1Alternative) :-   []
− test/Test/Sample.hs
@@ -1,62 +0,0 @@-module Test.Sample where--import qualified Numeric.Interpolation.Type as Type-import qualified Numeric.Interpolation.Piecewise as Piecewise--import qualified Data.Set as Set-import Data.Array (accumArray, listArray, )-import Data.List.HT (lengthAtLeast, )--import Test.QuickCheck (Property, quickCheck, (==>), )----withSortedRatios ::-   ([Rational] -> Rational -> a) ->-   ([Integer] -> Integer -> a)-withSortedRatios f nodeXs x =-   f (map fromInteger $ Set.toAscList $ Set.fromList nodeXs) (fromInteger x)--checkEq ::-   (Ord x, Eq y, Num y) =>-   Type.T x y ny -> [x] -> x -> Bool-checkEq typ nodeXs x =-   let ys =-          map-             (flip (Piecewise.interpolateConstantExt typ) x)-             (Type.basisFunctions typ nodeXs)-       bounds = (0, length ys - 1)-   in  listArray bounds ys-       ==-       accumArray (flip const) 0 bounds-          (Type.sampleBasisFunctions typ nodeXs x)---linear :: [Integer] -> Integer -> Bool-linear = withSortedRatios $ checkEq Type.linear--hermite1 :: [Integer] -> Integer -> Bool-hermite1 = withSortedRatios $ checkEq Type.hermite1---derivativeFree ::-   Type.T Rational Rational ny ->-   [Integer] -> Integer -> Property-derivativeFree typ =-   withSortedRatios $ \nodeXs x ->-      lengthAtLeast 4 nodeXs ==> checkEq typ nodeXs x--cubicLinear :: [Integer] -> Integer -> Property-cubicLinear = derivativeFree Type.cubicLinear--cubicParabola :: [Integer] -> Integer -> Property-cubicParabola = derivativeFree Type.cubicParabola---tests :: [(String, IO ())]-tests =-   ("linear", quickCheck linear) :-   ("hermite1", quickCheck hermite1) :-   ("cubicLinear", quickCheck cubicLinear) :-   ("cubicParabola", quickCheck cubicParabola) :-   []