{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PolyKinds #-}

module Geomancy.Interpolate
  ( linear
  , linearE
  , b1

  , quadratic
  , quadraticE
  , b2

  , cubic
  , cubicE
  , b3
  ) where

import Data.VectorSpace (VectorSpace, (*^), (^+^))
import Geomancy.Elementwise (Element, Elementwise(..))

{-# INLINEABLE linear #-}
linear :: VectorSpace v a => v -> v -> a -> v
linear :: v -> v -> a -> v
linear v
p0 v
p1 a
t =
  a
b01 a -> v -> v
forall v a. VectorSpace v a => a -> v -> v
*^ v
p0 v -> v -> v
forall v a. VectorSpace v a => v -> v -> v
^+^
  a
b11 a -> v -> v
forall v a. VectorSpace v a => a -> v -> v
*^ v
p1
  where
    (a
b01, a
b11) = a -> (a, a)
forall b. Num b => b -> (b, b)
b1 a
t

{-# INLINEABLE linearE #-}
linearE :: (Elementwise v, Element v ~ Float) => v -> v -> v -> v
linearE :: v -> v -> v -> v
linearE = (Element v -> Element v -> Element v -> Element v)
-> v -> v -> v -> v
forall a.
Elementwise a =>
(Element a -> Element a -> Element a -> Element a)
-> a -> a -> a -> a
emap3 Element v -> Element v -> Element v -> Element v
forall v a. VectorSpace v a => v -> v -> a -> v
linear

{-# INLINE b1 #-}
b1 :: Num b => b -> (b, b)
b1 :: b -> (b, b)
b1 b
t =
  ( b
1 b -> b -> b
forall a. Num a => a -> a -> a
- b
t
  , b
t
  )

{-# INLINEABLE quadratic #-}
quadratic :: VectorSpace v a => v -> v -> v -> a -> v
quadratic :: v -> v -> v -> a -> v
quadratic v
p0 v
p1 v
p2 a
t =
  a
b02 a -> v -> v
forall v a. VectorSpace v a => a -> v -> v
*^ v
p0 v -> v -> v
forall v a. VectorSpace v a => v -> v -> v
^+^
  a
b12 a -> v -> v
forall v a. VectorSpace v a => a -> v -> v
*^ v
p1 v -> v -> v
forall v a. VectorSpace v a => v -> v -> v
^+^
  a
b22 a -> v -> v
forall v a. VectorSpace v a => a -> v -> v
*^ v
p2
  where
    (a
b02, a
b12, a
b22) = a -> (a, a, a)
forall c. Num c => c -> (c, c, c)
b2 a
t

{-# INLINEABLE quadraticE #-}
quadraticE :: (Elementwise v, Element v ~ Float) => v -> v -> v -> v -> v
quadraticE :: v -> v -> v -> v -> v
quadraticE = (Element v -> Element v -> Element v -> Element v -> Element v)
-> v -> v -> v -> v -> v
forall a.
Elementwise a =>
(Element a -> Element a -> Element a -> Element a -> Element a)
-> a -> a -> a -> a -> a
emap4 Element v -> Element v -> Element v -> Element v -> Element v
forall v a. VectorSpace v a => v -> v -> v -> a -> v
quadratic

{-# INLINE b2 #-}
b2 :: Num c => c -> (c, c, c)
b2 :: c -> (c, c, c)
b2 c
t =
  ( c
1 c -> c -> c
forall a. Num a => a -> a -> a
-
    c
2 c -> c -> c
forall a. Num a => a -> a -> a
* c
t c -> c -> c
forall a. Num a => a -> a -> a
+
    c
t c -> c -> c
forall a. Num a => a -> a -> a
* c
t

  , c
2 c -> c -> c
forall a. Num a => a -> a -> a
* c
t c -> c -> c
forall a. Num a => a -> a -> a
-
    c
2 c -> c -> c
forall a. Num a => a -> a -> a
* c
t c -> c -> c
forall a. Num a => a -> a -> a
* c
t

  , c
t c -> c -> c
forall a. Num a => a -> a -> a
* c
t
  )

{-# INLINEABLE cubic #-}
cubic :: VectorSpace v a => v -> v -> v -> v -> a -> v
cubic :: v -> v -> v -> v -> a -> v
cubic v
p0 v
p1 v
p2 v
p3 a
t =
  a
b03 a -> v -> v
forall v a. VectorSpace v a => a -> v -> v
*^ v
p0 v -> v -> v
forall v a. VectorSpace v a => v -> v -> v
^+^
  a
b13 a -> v -> v
forall v a. VectorSpace v a => a -> v -> v
*^ v
p1 v -> v -> v
forall v a. VectorSpace v a => v -> v -> v
^+^
  a
b23 a -> v -> v
forall v a. VectorSpace v a => a -> v -> v
*^ v
p2 v -> v -> v
forall v a. VectorSpace v a => v -> v -> v
^+^
  a
b33 a -> v -> v
forall v a. VectorSpace v a => a -> v -> v
*^ v
p3
  where
    (a
b03, a
b13, a
b23, a
b33) = a -> (a, a, a, a)
forall d. Num d => d -> (d, d, d, d)
b3 a
t

{-# INLINEABLE cubicE #-}
cubicE :: (Elementwise v, Element v ~ Float) => v -> v -> v -> v -> v -> v
cubicE :: v -> v -> v -> v -> v -> v
cubicE = (Element v
 -> Element v -> Element v -> Element v -> Element v -> Element v)
-> v -> v -> v -> v -> v -> v
forall a.
Elementwise a =>
(Element a
 -> Element a -> Element a -> Element a -> Element a -> Element a)
-> a -> a -> a -> a -> a -> a
emap5 Element v
-> Element v -> Element v -> Element v -> Element v -> Element v
forall v a. VectorSpace v a => v -> v -> v -> v -> a -> v
cubic

{-# INLINE b3 #-}
b3 :: Num d => d -> (d, d, d, d)
b3 :: d -> (d, d, d, d)
b3 d
t =
  ( d
1 d -> d -> d
forall a. Num a => a -> a -> a
- d
3 d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
+
    d
3 d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
-
    d
t d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
* d
t

  , d
3 d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
-
    d
6 d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
+
    d
3 d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
* d
t

  , d
3 d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
-
    d
3 d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
* d
t

  , d
t d -> d -> d
forall a. Num a => a -> a -> a
* d
t d -> d -> d
forall a. Num a => a -> a -> a
* d
t
  )