```module Math.Noise.Interpolation where

{- | Performs cubic interpolation between two values bound between two other values
- The alpha value should range from 0.0 to 1.0.
- If the alpha value is 0.0, this function returns the first value.
- If the alpha vlaue is 1.0, this function returns the second value.
-}
cubic :: Double -> Double -> Double -> Double -> Double -> Double
cubic beforeFirstValue firstValue secondValue afterSecondValue alpha =
(p * alpha * alpha * alpha) + (q * alpha * alpha) + (r * alpha) + firstValue
where p = (afterSecondValue - secondValue) - (beforeFirstValue - firstValue)
q = (beforeFirstValue- firstValue) - p
r = secondValue - beforeFirstValue

{- | Performs linear interpolation between two values.
- The alpha value should range from 0.0 to 1.0.
- If the alpha value is 0.0, this function returns the first value.
- If the alpha value is 1.0, this function returns the second value.
-}
linear :: Double -> Double -> Double -> Double
{-# INLINE linear #-}
linear firstValue secondValue alpha =
((1.0 - alpha) * firstValue) + (alpha * secondValue)

{- | Maps a value onto a cubic S-curve
- the derivative of a cubic S-curve is zero at 0.0 and "value" at 1.0 -}
scurve3 :: Double -> Double
{-# INLINE scurve3 #-}
scurve3 value = value^3

{- | Maps a value onto a quintic S-curve.
- The first derivative is zero at 0.0 and "value" at 1.0
- The second derivative is zero at 0.0 and "value" at 1.0 -}
scurve5 :: Double -> Double
{-# INLINE scurve5 #-}
scurve5 value = (6.0 * value^5) - (15.0 * value^4) + (10.0 * value^3)

```