module Numeric.Interpolation.Sample (
T,
linear,
hermite1,
cubicLinear,
cubicParabola,
) where
import qualified Numeric.Interpolation.NodeList as Nodes
import qualified Numeric.Interpolation.Piece as Piece
import Numeric.Interpolation.Private.List (mapAdjacentMaybe3, )
import Numeric.Interpolation.Private.Basis (
parabolaBasisDerivativeRight,
parabolaBasisDerivativeCenter,
parabolaBasisDerivativeLeft,
)
type T x y = [x] -> x -> [(Int, y)]
linear :: (Fractional a, Ord a) => T a a
linear nodeXs =
let nodes = Nodes.fromList $ zip nodeXs [0..]
in \x ->
case Nodes.lookup nodes x of
(Just (l,nl), Just (r,nr)) ->
[(nl, Piece.linear (l,1) (r,0) x),
(nr, Piece.linear (l,0) (r,1) x)]
(Just (_l,nl), Nothing) -> [(nl, 1)]
(Nothing, Just (_r,nr)) -> [(nr, 1)]
(Nothing, Nothing) -> []
hermite1 :: (Fractional a, Ord a) => T a a
hermite1 nodeXs =
let nodes = Nodes.fromList $ zip nodeXs [0..]
in \x ->
case Nodes.lookup nodes x of
(Just (l,nl), Just (r,nr)) ->
[(2*nl+0, Piece.hermite1 (l,(1,0)) (r,(0,0)) x),
(2*nl+1, Piece.hermite1 (l,(0,1)) (r,(0,0)) x),
(2*nr+0, Piece.hermite1 (l,(0,0)) (r,(1,0)) x),
(2*nr+1, Piece.hermite1 (l,(0,0)) (r,(0,1)) x)]
(Just (_l,nl), Nothing) -> [(2*nl, 1)]
(Nothing, Just (_r,nr)) -> [(2*nr, 1)]
(Nothing, Nothing) -> []
cubicLinear :: (Fractional a, Ord a) => T a a
cubicLinear nodeXs =
let nodes =
Nodes.fromList $ zip nodeXs $ zip [0..] $
mapAdjacentMaybe3 (\l _ r -> (l,r)) nodeXs
in \x ->
case Nodes.lookup nodes x of
(Nothing, Nothing) -> []
(Just (_l,(nl,_)), Nothing) -> [(nl1, 1)]
(Nothing, Just (_r,(nr,_))) -> [(nr+1, 1)]
(Just (l,(nl,(mll,_))), Just (r,(nr,(_,mrr)))) ->
let interL ll =
(nl1, Piece.hermite1 (l,(0,recip(llr))) (r,(0,0)) x)
interR rr =
(nr+1, Piece.hermite1 (l,(0,0)) (r,(0,recip(rrl))) x)
in case (mll,mrr) of
(Just ll, Just rr) ->
interL ll :
(nl, Piece.hermite1 (l,(1,0)) (r,(0,recip(lrr))) x) :
(nr, Piece.hermite1 (l,(0,recip(rll))) (r,(1,0)) x) :
interR rr :
[]
(Just ll, Nothing) -> interL ll : [(nl, 1)]
(Nothing, Just rr) -> interR rr : [(nr, 1)]
(Nothing, Nothing) -> []
cubicParabola :: (Fractional a, Ord a) => T a a
cubicParabola nodeXs =
let nodes =
Nodes.fromList $ zip nodeXs $ zip [0..] $
mapAdjacentMaybe3 (\l _ r -> (l,r)) nodeXs
in \x ->
case Nodes.lookup nodes x of
(Nothing, Nothing) -> []
(Just (_l,(nl,_)), Nothing) -> [(nl1, 1)]
(Nothing, Just (_r,(nr,_))) -> [(nr+1, 1)]
(Just (l,(nl,(mll,_))), Just (r,(nr,(_,mrr)))) ->
let interL ll =
(nl1,
Piece.hermite1
(l,(0, parabolaBasisDerivativeLeft ll l r))
(r,(0, 0))
x)
interR rr =
(nr+1,
Piece.hermite1
(l,(0, 0))
(r,(0, parabolaBasisDerivativeRight l r rr))
x)
in case (mll,mrr) of
(Just ll, Just rr) ->
interL ll :
(nl,
Piece.hermite1
(l, (1, parabolaBasisDerivativeCenter ll l r))
(r, (0, parabolaBasisDerivativeLeft l r rr))
x) :
(nr,
Piece.hermite1
(l, (0, parabolaBasisDerivativeRight ll l r))
(r, (1, parabolaBasisDerivativeCenter l r rr))
x) :
interR rr :
[]
(Just ll, Nothing) -> interL ll : [(nl, 1)]
(Nothing, Just rr) -> interR rr : [(nr, 1)]
(Nothing, Nothing) -> []