{- |
Generate lists of basis functions with respect to interpolation nodes
and generate functions from coefficients with respect to these bases.

A basis function is one where all but one features are zero.
E.g. in a linear basis a basis function is one at one node,
and zero at all the other interpolation nodes.

You need the basis functions
for setting up the matrix for a linear least-squares solver for curve fitting.
The solver computes some coefficients
and in a second step you convert these coefficients
to the piecewise interpolation function.
-}
module Numeric.Interpolation.Basis (
   -- * Interpolation basis functions
   Compact.linear,
   Compact.hermite1,
   Compact.cubicLinear,
   Compact.cubicParabola,
   -- * Construct functions from the coefficients with respect to a basis
   coefficientsToLinear,
   coefficientsToHermite1,
   coefficientsToCubicLinear,
   coefficientsToCubicParabola,
   ) where

import qualified Numeric.Interpolation.Basis.Compact as Compact
import qualified Numeric.Interpolation.NodeList as Nodes
import Numeric.Interpolation.Private.Basis
          (parabolaDerivativeCenterNode, hermite1Split)
import Numeric.Interpolation.Private.List (mapAdjacent3, )


{- |
@coefficientsToLinear nodes coefficients@
creates an interpolation function for @nodes@,
where the @coefficients@ correspond to the basis functions
constructed with @Basis.linear nodes@.
-}
coefficientsToLinear :: [a] -> [b] -> Nodes.T a b
coefficientsToLinear :: [a] -> [b] -> T a b
coefficientsToLinear [a]
xs = [(a, b)] -> T a b
forall x y. [(x, y)] -> T x y
Nodes.fromList ([(a, b)] -> T a b) -> ([b] -> [(a, b)]) -> [b] -> T a b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [b] -> [(a, b)]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
xs

{- |
Cf. 'coefficientsToLinear'
-}
coefficientsToHermite1 :: [a] -> [b] -> Nodes.T a (b, b)
coefficientsToHermite1 :: [a] -> [b] -> T a (b, b)
coefficientsToHermite1 [a]
xs =
   [(a, (b, b))] -> T a (b, b)
forall x y. [(x, y)] -> T x y
Nodes.fromList ([(a, (b, b))] -> T a (b, b))
-> ([b] -> [(a, (b, b))]) -> [b] -> T a (b, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [(b, b)] -> [(a, (b, b))]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
xs ([(b, b)] -> [(a, (b, b))])
-> ([b] -> [(b, b)]) -> [b] -> [(a, (b, b))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [b] -> [(b, b)]
forall a b. [a] -> [b] -> [(b, b)]
hermite1Split [a]
xs



{- |
Cf. 'coefficientsToLinear'
-}
coefficientsToCubicLinear :: (Fractional a) => [a] -> [a] -> Nodes.T a (a, a)
coefficientsToCubicLinear :: [a] -> [a] -> T a (a, a)
coefficientsToCubicLinear [a]
xs =
   [(a, (a, a))] -> T a (a, a)
forall x y. [(x, y)] -> T x y
Nodes.fromList ([(a, (a, a))] -> T a (a, a))
-> ([a] -> [(a, (a, a))]) -> [a] -> T a (a, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   ((a, a) -> (a, a) -> (a, a) -> (a, (a, a)))
-> [(a, a)] -> [(a, (a, a))]
forall a b. (a -> a -> a -> b) -> [a] -> [b]
mapAdjacent3 (\(a
xl,a
yl) (a
xn,a
yn) (a
xr,a
yr) -> (a
xn, (a
yn, (a
yra -> a -> a
forall a. Num a => a -> a -> a
-a
yl)a -> a -> a
forall a. Fractional a => a -> a -> a
/(a
xra -> a -> a
forall a. Num a => a -> a -> a
-a
xl)))) ([(a, a)] -> [(a, (a, a))])
-> ([a] -> [(a, a)]) -> [a] -> [(a, (a, a))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   [a] -> [a] -> [(a, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
xs

{- |
Cf. 'coefficientsToLinear'
-}
coefficientsToCubicParabola :: (Fractional a) => [a] -> [a] -> Nodes.T a (a, a)
coefficientsToCubicParabola :: [a] -> [a] -> T a (a, a)
coefficientsToCubicParabola [a]
xs =
   [(a, (a, a))] -> T a (a, a)
forall x y. [(x, y)] -> T x y
Nodes.fromList ([(a, (a, a))] -> T a (a, a))
-> ([a] -> [(a, (a, a))]) -> [a] -> T a (a, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   ((a, a) -> (a, a) -> (a, a) -> (a, (a, a)))
-> [(a, a)] -> [(a, (a, a))]
forall a b. (a -> a -> a -> b) -> [a] -> [b]
mapAdjacent3
      (\(a, a)
pl pn :: (a, a)
pn@(a
xn,a
yn) (a, a)
pr ->
         (a
xn, (a
yn, (a, a) -> (a, a) -> (a, a) -> a
forall a. Fractional a => (a, a) -> (a, a) -> (a, a) -> a
parabolaDerivativeCenterNode (a, a)
pl (a, a)
pn (a, a)
pr))) ([(a, a)] -> [(a, (a, a))])
-> ([a] -> [(a, a)]) -> [a] -> [(a, (a, a))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   [a] -> [a] -> [(a, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
xs