module Diagrams.CubicSpline.Internal
(
solveCubicSplineDerivatives
, solveCubicSplineDerivativesClosed
, solveCubicSplineCoefficients
) where
import Diagrams.Solve.Tridiagonal
import Data.List
solveCubicSplineDerivatives :: Fractional a => [a] -> [a]
solveCubicSplineDerivatives :: [a] -> [a]
solveCubicSplineDerivatives (x :: a
x:xs :: [a]
xs) = [a] -> [a] -> [a] -> [a] -> [a]
forall a. Fractional a => [a] -> [a] -> [a] -> [a] -> [a]
solveTriDiagonal [a]
as [a]
bs [a]
as [a]
ds
where
as :: [a]
as = Int -> a -> [a]
forall a. Int -> a -> [a]
replicate (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) 1
bs :: [a]
bs = 2 a -> [a] -> [a]
forall a. a -> [a] -> [a]
: Int -> a -> [a]
forall a. Int -> a -> [a]
replicate (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- 2) 4 [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [2]
l :: Int
l = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
ds
ds :: [a]
ds = (a -> a -> a) -> [a] -> [a] -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> a -> a
forall a. Num a => a -> a -> a
f ([a]
xs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [[a] -> a
forall a. [a] -> a
last [a]
xs]) (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs)
f :: a -> a -> a
f a :: a
a b :: a
b = 3a -> a -> a
forall a. Num a => a -> a -> a
*(a
a a -> a -> a
forall a. Num a => a -> a -> a
- a
b)
solveCubicSplineDerivatives _ = [Char] -> [a]
forall a. HasCallStack => [Char] -> a
error "argument to solveCubicSplineDerivatives must be nonempty"
solveCubicSplineDerivativesClosed :: Fractional a => [a] -> [a]
solveCubicSplineDerivativesClosed :: [a] -> [a]
solveCubicSplineDerivativesClosed xs :: [a]
xs = [a] -> [a] -> [a] -> [a] -> a -> a -> [a]
forall a. Fractional a => [a] -> [a] -> [a] -> [a] -> a -> a -> [a]
solveCyclicTriDiagonal [a]
as [a]
bs [a]
as [a]
ds 1 1
where
as :: [a]
as = Int -> a -> [a]
forall a. Int -> a -> [a]
replicate (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) 1
bs :: [a]
bs = Int -> a -> [a]
forall a. Int -> a -> [a]
replicate Int
l 4
l :: Int
l = [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs
xs' :: [a]
xs' = [a] -> [a]
forall a. [a] -> [a]
cycle [a]
xs
ds :: [a]
ds = Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
l ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ (a -> a -> a) -> [a] -> [a] -> [a]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith a -> a -> a
forall a. Num a => a -> a -> a
f (Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop 1 [a]
xs') (Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) [a]
xs')
f :: a -> a -> a
f a :: a
a b :: a
b = 3a -> a -> a
forall a. Num a => a -> a -> a
*(a
a a -> a -> a
forall a. Num a => a -> a -> a
- a
b)
solveCubicSplineCoefficients :: Fractional a => Bool -> [a] -> [[a]]
solveCubicSplineCoefficients :: Bool -> [a] -> [[a]]
solveCubicSplineCoefficients closed :: Bool
closed xs :: [a]
xs =
[ [a
x,a
d,3a -> a -> a
forall a. Num a => a -> a -> a
*(a
x1a -> a -> a
forall a. Num a => a -> a -> a
-a
x)a -> a -> a
forall a. Num a => a -> a -> a
-2a -> a -> a
forall a. Num a => a -> a -> a
*a
da -> a -> a
forall a. Num a => a -> a -> a
-a
d1,2a -> a -> a
forall a. Num a => a -> a -> a
*(a
xa -> a -> a
forall a. Num a => a -> a -> a
-a
x1)a -> a -> a
forall a. Num a => a -> a -> a
+a
da -> a -> a
forall a. Num a => a -> a -> a
+a
d1]
| (x :: a
x,x1 :: a
x1,d :: a
d,d1 :: a
d1) <- [a] -> [a] -> [a] -> [a] -> [(a, a, a, a)]
forall a b c d. [a] -> [b] -> [c] -> [d] -> [(a, b, c, d)]
zip4 [a]
xs' ([a] -> [a]
forall a. [a] -> [a]
tail [a]
xs') [a]
ds' ([a] -> [a]
forall a. [a] -> [a]
tail [a]
ds')
]
where
ds :: [a]
ds | Bool
closed = [a] -> [a]
forall a. Fractional a => [a] -> [a]
solveCubicSplineDerivativesClosed [a]
xs
| Bool
otherwise = [a] -> [a]
forall a. Fractional a => [a] -> [a]
solveCubicSplineDerivatives [a]
xs
close :: [a] -> [a]
close as :: [a]
as | Bool
closed = [a]
as [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [[a] -> a
forall a. [a] -> a
head [a]
as]
| Bool
otherwise = [a]
as
xs' :: [a]
xs' = [a] -> [a]
forall a. [a] -> [a]
close [a]
xs
ds' :: [a]
ds' = [a] -> [a]
forall a. [a] -> [a]
close [a]
ds